Java的设计模式三大类
1.责任链模式(Chain of Responsibility)
有多个对象,每个对象持有对下一个对象的引用,这样就会形成一条链,请求在这条链上传递,直到某一对象决定处理该请求。但是发出者并不清楚到底最终那个对象会处理该请求,所以,责任链模式可以实现,在隐瞒客户端的情况下,对系统进行动态的调整。
Handler接口:
public interface Handler {
public void operator();
}
Abstracthandler类提供了get和set方法,方便MyHandle类设置和修改引用对象。
public abstract class abstractHandler {
private Handler handler;
public Handler getHandler() {
return handler;
}
public void setHandler(Handler handler) {
this.handler = handler;
}
}
MyHandle类是核心,实例化后生成一系列相互持有的对象,构成一条链。
public class myHandler extends abstractHandler implements Handler {
private String name;
public myHandler(String name) {
this.name = name;
}
@Override
public void operator() {
System.out.println(name+"chain");
if(getHandler()!=null){
getHandler().operator();
}
}
}
测试:
public class Test {
public static void main(String[] args){
myHandler h1=new myHandler("h1");
myHandler h2=new myHandler("h2");
myHandler h3=new myHandler("h3");
myHandler h4=new myHandler("h4");
h3.setHandler(h4);
h2.setHandler(h3);
h1.setHandler(h2);
h1.operator();
}
}
结果:
责任链模式屏蔽了请求的处理过程,你发一个请求到底是谁处理的,这个你不用关心,只要你把请求抛给责任链的第一个处理者,最终返回一个处理结果(也可以不返回),作为请求者可以不用知道到底需要谁来处理,这是责任链模式的核心。
注意:链接上的请求可以是一条链,可以是一个树,还可以是一个环,模式本身不约束这个,需要我们自己去实现,同时,在一个时刻,命令只允许由一个对象传给另一个对象,而不允许传给多个对象。
类图如下:
2.访问者模式(Visitor Pattern)
简单来说,访问者模式就是一种分离对象数据结构与行为的方法,通过这种分离,可达到为一个被访问者动态添加新的操作而无需做其它的修改的效果。
Subject接口:
public interface Subject {
//接受将要访问它的对象
public void accept(Visitor visitor);
//获取将要被访问的属性
public String getSubject();
}
Visitor接口:
public interface Visitor {
//存放要访问的对象
public void visit(Subject subject);
}
Subject实现类:
public class mySubject implements Subject {
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
@Override
public String getSubject() {
return "A";
}
}
Vistor实现类:
public class myVisitor implements Visitor {
@Override
public void visit(Subject subject) {
System.out.println("访问"+subject.getSubject());
}
}
测试:
public class Test {
public static void main(String[] args){
Visitor visitor=new myVisitor();
Subject su=new mySubject();
su.accept(visitor);
}
}
结果:
类图如下:
3.状态模式(State Pattern)
当对象的状态改变时,同时改变其行为,很好理解!状态模式就两点:1、可以通过改变状态来获得不同的行为。2、别人能同时看到你的变化。
举例:开门、关门。
状态类:
public class State {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public void open(){
System.out.println("开门");
}
public void close(){
System.out.println("关门");
}
}
状态类的替换类:
public class Change {
private State state;
public State getState() {
return state;
}
public void setState(State state) {
this.state = state;
}
public Change(State state) {
this.state = state;
}
public void change(){
if(state.getValue().equals("state1")){
state.open();
}else if(state.getValue().equals("state2")){
state.close();
}
}
}
测试:
public class Test {
public static void main(String[] args){
State state=new State();
Change change=new Change(state);
//设置一种状态
state.setValue("state1");
//state.setValue("state2");
change.change();
}
}
结果:
状态模式相当于当某个对象在它的状态发生改变时,他的行为也随着发生较大变化。也就是说行为是受状态约束的情况下才可以使用,而且对象的状态最好控制在5个之内。
类图如下:
4.原型模式(Prototype Pattern)
原型模式虽然是创建型的模式,但是与工程模式没有关系,从名字即可看出,该模式的思想就是将一个对象作为原型,对其进行复制、克隆,产生一个和原对象类似的新对象。本小结会通过对象的复制,进行讲解。在Java中,复制对象是通过clone()实现的,先创建一个原型类:
public class Prototype implements Cloneable {
@Override
//super.clone()调用的是Object的clone()方法,而在Object类中,clone()是native的,具体怎么实现,了解JNI
protected Object clone() throws CloneNotSupportedException {
Prototype p= (Prototype) super.clone();
return super.clone();
}
}
举例深浅复制:
浅复制:对对象中的基本数据类型进行简单的赋值,如果存在动态成员和指针就会出现问题。
深复制:对对象中的动态成员重新开辟内存空间。
import java.io.Serializable;
class SerializableObject implements Serializable {
private static final long serialVersionUID=1L;
}
import java.io.*;
public class Prototype implements Cloneable,Serializable{
private static final long serialVersionUID = 1L;
private String string;
private SerializableObject obj;
// 浅复制
public Object clone() throws CloneNotSupportedException{
Prototype proto= (Prototype) super.clone();
return proto;
}
//深复制
public Object deepClone()throws IOException,ClassNotFoundException{
//写入当前对象的二进制流
ByteArrayOutputStream bos=new ByteArrayOutputStream();
ObjectOutputStream oos=new ObjectOutputStream(bos);
oos.writeObject(this);
// 读出二进制流产生的新对象
ByteArrayInputStream bis=new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois=new ObjectInputStream(bis);
return ois.readObject();
}
public String getString() {
return string;
}
public void setString(String string) {
this.string = string;
}
public SerializableObject getObj(){
return obj;
}
public void setObj(SerializableObject obj) {
this.obj=obj;
}
}
要实现深复制,需要采用流的形式读入当前对象的二进制输入,再写出二进制数据对应的对象。
类图如下:
全部评论