第 3 卷
} return prototypeClass;
} }
原型模式实际上就是实现 Cloneable 接口,重写 clone()方法。
使用原型模式的优点:
- 性能优良
原型模式是在内存二进制流的拷贝,要比直接 new 一个对象性能好很多,特别是要在一个循环体内产生大量的对象时,原型模式可以更好地体现其优点。
- 逃避构造函数的约束
这既是它的优点也是缺点,直接在内存中拷贝,构造函数是不会执行的(参见 13.4 节)。
使用场景:
- 资源优化场景
类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等。
- 性能和安全要求的场景
通过 new 产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式。
- 一个对象多个修改者的场景
一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用。
浅拷贝和深拷贝:
浅拷贝:Object 类提供的方法 clone 只是拷贝本对象,其对象内部的数组、引用对象等都不拷贝,还是指向原生对象的内部元素地址,这种拷贝就叫做浅拷贝,其
他的原始类型比如 int、long、char、string(当做是原始类型)等都会被拷贝。
注意:使用原型模式时,引用的成员变量必须满足两个条件才不会被拷贝:一是类的成员变量,而不是方法内变量;二是必须是一个可变的引用对象,而不是一个
原始类型或不可变对象。
深拷贝:对私有的类变量进行独立的拷贝如:thing.arrayList = (ArrayList<String>)this.arrayList.clone();
8.中介者模式
定义:Define an object that encapsulates how a set of objects interact.Mediator promotes loose coupling by keeping objects from referring to each other
explicitly,and it lets you vary their interaction independently.(用一个中介对象封装一系列的对象交互,中介者使各对象不需要显示地相互作用,从而使其耦合松散,
而且可以独立地改变它们之间的交互。)
- Mediator 抽象中介者角色
- Concrete Mediator 具体中介者角色
具体中介者角色通过协调各同事角色实现协作行为,因此它必须依赖于各个同事角色。
- Colleague 同事角色
每一个同事角色都知道中介者角色,而且与其他的同事角色通信的时候,一定要通过中介者角色协作。每个同事类的行为分为两种:一种是同事本身的行为,比如改
变对象本身的状态,处理自己的行为等,这种行为叫做自发行为(Self- Method),与其他的同事类或中介者没有任何的依赖;第二种是必须依赖中介者
才能完成的行为,叫做依赖方法(Dep-Method)。
通用抽象中介者代码:
public abstract class Mediator { //定义同事类
protected ConcreteColleague1 c1;
protected ConcreteColleague2 c2;
//通过 getter/setter 方法把同事类注入进来 public ConcreteColleague1 getC1() {
return c1;
} public void setC1(ConcreteColleague1 c1) {
this.c1 = c1;
} public ConcreteColleague2 getC2() {
return c2;
} public void setC2(ConcreteColleague2 c2) {
this.c2 = c2;
} //中介者模式的业务逻辑
public abstract void doSomething1();
public abstract void doSomething2();
}
ps:使用同事类注入而不使用抽象注入的原因是因为抽象类中不具有每个同事类必须要完成的方法。即每个同事类中的方法各不相同。
问:为什么同事类要使用构造函数注入中介者,而中介者使用 getter/setter 方式注入同事类呢?
这是因为同事类必须有中介者,而中介者却可以只有部分同事类。
使用场景:
现了蜘蛛网状结构,即每个类都与其他的类有直接的联系。
9.命令模式
定义:Encapsulate a request as an object,thereby letting you parameterize clients with different requests,queue or log requests,and support undoable operations.
(将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能。)
- Receive 接收者角色
该角色就是干活的角色,命令传递到这里是应该被执行的,具体到我们上面的例子中就是 Group 的三个实现类(需求组,美工组,代码组)。
- Command 命令角色
需要执行的所有命令都在这里声明。
- Invoker 调用者角色
接收到命令,并执行命令。在例子中,我(项目经理)就是这个角色。
使用场景:
认为是命令的地方就可以采用命令模式,例如,在 GUI 开发中,一个按钮的点击是一个命令,可以采用命令模式;模拟 DOS 命令的时候,当然也要采用命令模
式;触发-反馈机制的处理等。
10.责任链模式
定义:Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request.Chain the receiving objects and pass
the request along the chain until an object handles it.(使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,
并沿着这条链传递该请求,直到有对象处理它为止。)
抽象处理者的代码:
public abstract class Handler { private Handler nextHandler;
//每个处理者都必须对请求做出处理 public final Response handleMessage(Request request){
Response response = null;
//判断是否是自己的处理级别
if(this.getHandlerLevel().equals(request.getRequestLevel())){ response = this.echo(request);