其实,最早在思考该主题时,只考虑到上一部分,没想过把具体的设计模式请出来的,然而这样的东西很难说说服力,所以才决定把这些模式解释一遍。喜欢
5.主要模式:
iterator, adater, chain of responsibility, builder, proxy, decorator, (template)strategy, bridge, state, visitor,observer, command, mediator
1.iterator模式(反向委托):这是反向委托的应用之一,通过被委托者来获得委托实例,也就是被委托者先于委托者创建,客户最终还是面向委托者进行操作,这里迭代器就是委托者,集合就是被委托者,这只是一个形意义上的解释,例如,当客户C要求跟负责人R进行会话,而又一时无法找到负责人R时, 刚好C知道R的下属员工E,当然,R会先找到E(只因为E知道R而已,E只完成一件事,找到R),让E去把R带到他的面前来,OK,这样的话,C就可以和R会话了,但是那个懒散的家伙R,他还是把事交给了员工E,那为什么,客户不直接让那员工来处理,而是找了一个负责人来交付呢?有一点, 我们会想,员工级别不够高,没人会鸟你的,太牵强了,这样的解释。因为我们想让客户看到这个负责人是以一致的行为在处理事件,其内部处理委托到具体的员工身上。这样就无需暴露员工的内部实现细节,又将不同员工不同处理以一致的方式提供给客户。当然,对客户隐藏实现细节是委托的效果之一,看你怎么使用它了,你也可以不用在迭代器上,只要任何想隐藏实现细节的,你都可以拿去用。
class Aggregate{
private Object[] array;
public Aggregate(int size){
array = new Object[size];
}
public void put(){
for(int i=0;i<array.length;i++){
array[i] = i;
}
}
public Object getAt(int index){
return array[index];
}
public int length(){
return array.length;
}
public Iterator iterator(){
return new Iterator(this);
}
}
class Iterator{
Aggregate aggregate;
int curIndex = 0;
public Iterator(Aggregate aggregate){
this.aggregate = aggregate;
}
public boolean hasNext(){
return curIndex<aggregate.length();
}
public Object next(){
return aggregate.getAt(curIndex++);
}
}
void main(){
Aggregate aggregate new Aggregate();
aggregate.put(); //初始化数据
for(Iterator iterator = aggregate.iterator();iterator.hasNext();){
String value = (String)iterator.next();
System.out.println(value);
}
}
2.adapter(简单单向委托):适配器有两种实现实现方式,其一就是委托,另一种则为继承。委托方式很简单,用简单委托即可实现,代码如下:
class Adaptee {
public void methodAdaptee(){
....
}
}
class Adapter{
private Adaptee adaptee;
public Adapter(Adaptee adaptee){
this.adaptee = adaptee;
}
public void methodAdapter(){
adaptee.methodAdaptee();
}
}
void main(){
Adapter adapter = new Adapter(new Adaptee());
adapter.methodAdapter();
}
Adapter委托者委托被委托者Adaptee处理。这东西生活中到处都是,比如处理电压不一致问题时所使用的变压器等等。继承方式暂略。
3.chain of responsibility(单向简单委托的传递):委托传递过程,构成了该模式,看例子。
class A{
public void methodA(){}
}
class B{
A a;
public B(A a){
this.a = a;
}
public void methodB(){
if(未处理) a.methodA();
}
}
class C{
B b;
public C(B b){
this.b = b;
}
public void methodC(){
if(未处理) b.methodB();
}
}
void main(){
C c = new C(new B(new A()));
c.methodC();
}
4.Builder模式(单向简单委托),首先,委托者(也就是建造者),知道constuct时需要的步骤,他只是把每一步骤委托给被委托者处理,然后返回最终结果,好比,包工头,他知道建造房屋的步骤,但他不会自己动手,然后在建造过程中,他每进行一个阶段都会把该阶段的建造过程委托给某个工人,估计这工人还没疯之前,他也想当Director了,因为他没法自己构造房屋,尽管他确实有能力,房屋的从头到脚他都懂。god让他只是个工人。
class Builder{
public void buildpart1(){
}
public void buildpart2(){
}
public void buildpart3(){
}
public Object getResult(){
}
}
class Director {
Builder builder;
public Director(Builder builder){
this.builder = builder;
}
public void constuct(){
builder.buildpart1();
builder.buildpart2();
builder.buildpart3();
builder.getResult();
}
}
void main(){
Director director = new Director(new Builder());
director.constuct();
}
5.proxy(单向简单委托),下面是最原始的委托。
class Subject{
public void methodSubject(){
}
}
class Proxy{
private Subject subject;
public Proxy(){
this.subject = new Subject();
}
public void methodProxy(){
subject.methodSubject();
}
}
void main(){
Proxy proxy = new Proxy();
proxy.methodProxy();
}
代理类似于委托,属于委托的一种,但是又有区别,为什么呢?因为代理人和本人要有一致的事件处理方式,我们就是为了让客户分不清是代理人在帮你处理,还是本人帮你处理,所以必须这样做,同时,我们会把本人和代理人改成同样的处理方式(method方法)。出现了这么特殊的委托,那么你是不是觉得有点别扭,好象有种阴影在心里做怪,凭什么要遵守这样的约定,那么我们就把这魔鬼驱除吧。我们把这些特殊委托的双方的公共行为提取出来,干什么?安置在接口中,或抽象类中,让委托双方都实现或继承它。OK了,问题解决了。必须遵循的规则被我们分离出来了。之前说过,面向对象思想提倡面向接口或抽象编程,本来,委托双方都该是基于借口或抽象类的,而且是独立于不同接口或抽象类的,但是为了简单起见,我们简化了。它与这里提取的共同接口或抽象类是有区别的,这里是为了驱除那该死的魔鬼,同时它也无意识的遵循了面向接口或抽象编程的思想,一举两得,很好。
演化结果:
abstract class Subject{
abstract public void method();
}
class RealSubject extends Subject{
public void method(){
}
}
class Proxy extends Subject{
private Subject subject;
public Proxy(){
this.subject = new RealSubject();
}
public void method(){
subject.method();
}
}
void main(){
Proxy proxy = new Proxy();
proxy.methodProxy();
}
需要记得的一点是,委托从不强迫你的执行顺序,你可以选择任何委托时机,通用的模型是:
(1)委托前的初始化工作
(2)委托过程
(3)委托后的善后处理
以上三步骤可以多层嵌套,需具体而定。
所以,比如在proxy模式里,你可以在交给代理处理前后做你想做的事。
6.decorator(单向简单委托)
下面是最原始的委托。
class Component{
public void methodComponent(){
}
}
class Decorator {
private Component component;
public Decorator(Component component){
this.component = component;
}
public void methodDecorator(){
component.methodComponent();
}
}
void main(){
Decorator decorator = new Decorator(new Component());
decorator.methodDecorator();
}
装饰模式,是动态扩展功能是常用的。先想想,扩展某一类功能,有几种方式?继承,委托。那为什么不用继承呢?因为耦合度太高,每扩展一个功能就得派生一个新的类,这样的结果,会使类层次不断膨胀,这种膨胀不只是在一个方向上。它横纵通吃,有一天你会被多叉树似的类蜘蛛网捆住的,然后蜘蛛慢慢享受它的美餐。为了逃命我们选择了委托,让装饰者委托被装饰者,同时为了让两者有一致的行为方式,同样抽象出接口或抽象类。你会发现,这跟proxy模式结构一样的,没错,基本一样。关键是,目的不同,装饰模式是为了扩展功能,主要对于层次级别的扩展很有用,假如,你为了扩展功能而仅仅派生了一个类,我会建议你使用,继承扩展。那么层次级别的扩展什么意思呢?就是依据扩展树的深度来考虑,可能是这样的,你扩展了原先的某个类A的methodA功能,你给它加了文件的持久化功能,然后,你可能还要在文件持久化上继续扩展缓冲功能。同时,该树很可能是多叉的,所以,你可以按照这种方式进行横向扩展。演化结果:
abstract class Component{
abstract public void method();
}
class ConcreteCompnent extends Component{
public void method(){
}
}
abstract class Decorator extends Component{
protected Component component;
public Decorator(Component component){
this.component = component;
}
public void method(){
component.method();
}
}
class ConcreteDecorator extends Decorator{
public void method(){
base.method();
增加新功能
}
}
proxy可以认为是decorator的简化形式,上面提到,为了扩展功能而仅仅派生了一个类的方式是不合理的,同样通过委托来扩展功能而仅仅得到一个装饰者同样也是不可取的,但是,我们不会抛弃这样的结构,如果这种情况产生了,我们改变其名称--代理,同时改变其目的,OK,得到的就是Proxy模式。然后,我想说的是,委托,是一种形,而真正的意是要结合具体模式的,就象在这里,它可以被解释为扩展,也可以被解释为代理。这才是它的意义所在。
posted on 2008-08-13 16:55
zhqh 阅读(172)
评论(0) 编辑 收藏 所属分类:
设计模式