Java设计模式——装饰器模式(Decorator)

孙悟空有七十二般变化,他的每一种变化都给他带来一种附加本领。而不管孙悟空怎么变化在二郎神眼里,他永远是那只猢狲。
装饰器模式以对客户透明的方式动态的给一个对象附加上更多的责任。
在孙悟空的例子里,老孙变成的鱼儿相当于老孙的子类。
装饰模式的类图如下:
这里写图片描述
装饰模式的角色介绍:
抽象构件角色(ComponentDec):给出一个抽象接口,以规范准备接收附加责任的对象
具体构件(Concrete ComponentDec):定义一个将要接收附加责任的类
装饰角色(Decortor):持有一个构件对象的实例,并顶一个与抽象构件接口一致的接口
具体装饰(Concrete Decorator):负责给构件对象“贴上”附加的责任

public interface Component {
    void simpleOperation();
} 
public class Decorator implements Component {

    private Component component;

    public Decorator(Component component) {
        super();
        this.component = component;
    }
    public Decorator() {
        super();
    }
    /**
     * 商业方法,委派给构件
     */
    public void simpleOperation() {
        component.simpleOperation();
    }
}

1、上面的修饰类中有一个私有的属性Component,其数据类型是构件类型
2、此装饰类实现了构件接口
3、接口的实现方法也值得注意,每一个实现的方法都委派给父类,当并不是单纯的委派,而是有功能的增强。
虽然Decorator类不是一个抽象类,但是由于他的功能是一个抽象角色,因此也常常称它为抽象修饰。

public class ConcreteComponent implements Component {

    public ConcreteComponent() {
        super();
    }
    /**
     * 商业方法
     */
    public void simpleOperation() {

    }
} 
public class ConcreteDecorator extends Decorator {
    public void simpleOperation(){
        super.simpleOperation();
    }
}

齐天大圣的例子:
Component的角色便是大名鼎鼎的齐天大圣孙悟空扮演的;ConcreteComponent的角色属于大圣的本尊,就是猢狲本人;大圣的72变便是Decorator角色;而ConcreteDecorator便是花、鸟、鱼、虫等72般变化。
这里写图片描述
装饰模式应该在什么情况下使用?
1、需要扩展一个类的功能,或给一个类增加附加功能
2、需要动态的给一个对象增加功能,这些功能可以再动态的撤销
3、需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使得继承关系不现实
装饰模式的优缺点
优点:
1、与继承关系目的都是要扩展对象的功能,但装饰模式可以提供比继承更多的灵活性
装饰模式允许系统动态的决定贴上一个需要的装饰,或者除掉一个不需要的装饰。继承关系则不同,继承关系是静态的,他在系统运行前就已经决定了。
2、通过使用不同的具体修饰类及这些装饰类的排列组合,设计师可以创造出很多不同的行为组合。而继承没有这个关系优势。每一种不同的组合均需要事先通过子类继承的方式设计好。
3、这种比继承更加灵活机动的特性,也同时意味着装饰模式比继承更加容易出错
缺点
使用装饰模式会产生比使用继承关系更多的类。特别是这些类看上去都比较相近

设计模式-decorator 演示程序

10-20

////////////////////////////////////////rn// Decorator.cpp rn//装饰类模式演示程序,rn//2003-10-16 zhj creatern/////////////////////////////////////////rn//Notern//1)装饰类可以装饰任何从抽象类派生的,实现了抽象类接口的类(装饰类没有实现抽象类接口,rn//如本例,decoOut及其子类都没有实现TextOut接口,所以不能修饰decoOut及其派生类,也就是说rn//装饰类不能装饰自身)rn//2)模式在于“神”而不在于“形”,散文在于“形散而神不散”,模式同样如此。理解了某一个模式,rn//写出10个concrete implmentataion,10个都会不同,总之,多多练习。rn//3)随手写成,没经过大脑,例子选得不好,命名也不好,里面还有几个用1234标识的对象,rn//不好意思。我个人理解,这个模式使用得比较广的。rn//4)此例子对高手不适用,恳请高手提出意见。rn/////////////////////////////////////////rn//authorrn//msn:topower4@hotmail.comrn//希望同c++,linux,arm(偏软件的),qt爱好者交流。rnrn//////////////////////////////////////////rn//rn#include "iostream.h"rnrn/////////////////////////////rn//接口,抽象类rnclass visualOutrnrnpublic:rn virtual void TextOut(void)=0;rnprotected:rn visualOut();rn;rn/////////////////////////////////////rn//基本类rnclass basicOut:public visualOutrnrnpublic:rn basicOut();rn virtual void TextOut(void)rn rn cout<<"basicOut"<TextOut();rn rnprivate:rn visualOut * mpVisualOut;rn//组合了接口,由concrete decorator的构造函数来对其赋值。rn;rn////////////////////////////rn//Concrete装饰类1rnclass ex1decoOut:public decoOutrnrnpublic:rn ex1decoOut(visualOut * p):decoOut(p)rn rn virtual void TextOut(void)rn rn decoOut::TextOut();rn cout<<"装饰了ex1"<TextOut();rn rn;rn///////////////////////////rn//rnint main(int argc, char* argv[])rnrn rn CTest* pTest=new CTest; rn if (NULL==pTest) rn cout<<"error"<fOut(pvisualOut);rnrn//基本类的子类(扩展了基本类的功能)的输出rn cout<<"**********基本类的子类扩展了基本类**********************"<fOut(pvisualOut);rnrn//rn cout<<"**********装饰类装饰了基本类****************************"<fOut(pvisualOut);rn//客户用同样的接口调用,但是实现基本功能(basicOut)+扩展功能(ex2decoOut)rn//rn cout<<"**********装饰类装饰了基本类的子类**********************"<fOut(pvisualOut);rn//rn cout<<"**********多个不同的装饰类装饰了基本类******************"<fOut(pvisualOut);rn rn//rn cout<<"**********多个相同的装饰类装饰了基本类******************"<fOut(pvisualOut);rnrn//不要装饰了,回收,实际上mbasicOut对象根本没改变过rn cout<<"**********回收装饰类************************************"<fOut(pvisualOut);rn rn return 0;rnrn

没有更多推荐了,返回首页

私密
私密原因:
请选择设置私密原因
  • 广告
  • 抄袭
  • 版权
  • 政治
  • 色情
  • 无意义
  • 其他
其他原因:
120
出错啦
系统繁忙,请稍后再试