装饰器(decorator)模式又名包装器(Wrapper)模式,它的主要用途在于给一个对象动态的添加一些额外的职责。与生成子类相比,它更具有灵活性。
有时候,我们需要为一个对象而不是整个类添加一些新的功能,比如,给一个文本区添加一个滚动条的功能。我们可以使用继承机制来实现这一功能,但是这种方法不够灵活,我们无法控制文本区加滚动条的方式和时机。而且当文本区需要添加更多的功能时,比如边框等,需要创建新的类,而当需要组合使用这些功能时无疑将会引起类的爆炸。
我们可以使用一种更为灵活的方法,就是把文本区嵌入到滚动条中。而这个滚动条的类就相当于对文本区的一个装饰。这个装饰(滚动条)必须与被装饰的组件(文本区)继承自同一个接口,这样,用户就不必关心装饰的实现,因为这对他们来说是透明的。装饰会将用户的请求转发给相应的组件(即调用相关的方法),并可能在转发的前后做一些额外的动作(如添加滚动条)。通过这种方法,我们可以根据组合对文本区嵌套不同的装饰,从而添加任意多的功能。这种动态的对对象添加功能的方法不会引起类的爆炸,也具有了更多的灵活性。
JAVA中IO流的设计就大量运用了装饰模式。看看我们熟悉的代码:
BufferedReader br = new BufferedReader(
new InputStreamReader(new FileInputStream("..")));
层层包装,增强功能。这就是装饰模式的要旨。(当然红字部分用到了适配器模式).
UML图
抽象组件角色(Component):定义一个对象接口,以规范准备接受附加责任的对象,即可以给这些对象动态地添加职责。
具体组件角色(ConcreteComponent) :被装饰者,定义一个将要被装饰增加功能的类。可以给这个类的对象添加一些职责
抽象装饰器(Decorator):维持一个指向构件Component对象的实例,并定义一个与抽象组件角色Component接口一致的接口
具体装饰器角色(ConcreteDecorator):向组件添加职责。
java代码实现
package com.ihyperwin.designPattern.decorator;
/**
* 冰淇淋接口,抽象组件角色,也可设置成抽象类
* 抽象组件角色(Component):定义一个对象接口,以规范准备接受附加责任的对象,即可以给这些对象动态地添加职责。
* @author ihyperwin
*
*/
public interface IceCream {
int price();
}
package com.ihyperwin.designPattern.decorator;
/**
* 最基本的冰淇淋类,具体组件角色(ConcreteComponent) ,被装饰者,定义一个将要被装饰增加功能的类
* @author ihyperwin
*
*/
public class BaseIceCream implements IceCream{
@Override
public int price() {
return 2;//价格为2元
}
}
package com.ihyperwin.designPattern.decorator;
/**
* 抽象装饰器(Decorator):维持一个IceCream对象的实例,并定义一个与抽象组件角色IceCream接口一致的接口
*
* @author ihyperwin
*
*/
public abstract class IceCreamDecorator implements IceCream{
public IceCream iceCream;
public abstract int price();
}
package com.ihyperwin.designPattern.decorator;
/**
* 具体装饰器角色(ConcreteDecorator):向组件添加职责。加香草的冰淇淋,价格加2元。
*
* @author ihyperwin
*
*/
public class VanillaIceCreamDecorator extends IceCreamDecorator {
public VanillaIceCreamDecorator(IceCream iceCream) {
this.iceCream = iceCream;
}
@Override
public int price() {
return this.iceCream.price()+2;
}
}
package com.ihyperwin.designPattern.decorator;
/**
* 具体装饰器角色(ConcreteDecorator):向组件添加职责。加葡萄的冰淇淋,价格加3元
* @author ihyperwin
*
*/
public class GrapeIceCreamDecorator extends IceCreamDecorator{
public GrapeIceCreamDecorator(IceCream iceCream){
this.iceCream=iceCream;
}
@Override
public int price() {
return this.iceCream.price()+3;
}
}
package com.ihyperwin.designPattern.decorator;
/**
* 具体装饰器角色(ConcreteDecorator):向组件添加职责。加草莓的冰淇淋,价格加4元
* @author ihyperwin
*
*/
public class StrawBerryIceCreamDecorator extends IceCreamDecorator{
public StrawBerryIceCreamDecorator(IceCream iceCream){
this.iceCream=iceCream;
}
@Override
public int price() {
return this.iceCream.price()+4;
}
}
package com.ihyperwin.designPattern.decorator;
public class Client {
/**
* @param args
*/
public static void main(String[] args) {
IceCream iceCream = new BaseIceCream();
System.out.println("原味冰淇淋价格为:"+iceCream.price());
IceCream vanillaIceCream = new VanillaIceCreamDecorator(iceCream);
System.out.println("香草冰淇淋价格为:"+vanillaIceCream.price());
IceCream grapeIceCream = new GrapeIceCreamDecorator(iceCream);
System.out.println("葡萄冰淇淋价格为:"+grapeIceCream.price());
IceCream strawBerryIceCream = new StrawBerryIceCreamDecorator(iceCream);
System.out.println("草莓冰淇淋价格为:"+strawBerryIceCream.price());
IceCream strawBerryGrapeIceCream = new GrapeIceCreamDecorator( new StrawBerryIceCreamDecorator(iceCream));
System.out.println("加葡萄有加草莓冰淇淋价格为:"+strawBerryGrapeIceCream.price());
IceCream vanillaStrawBerryGrapeIceCream =new VanillaIceCreamDecorator( new GrapeIceCreamDecorator( new StrawBerryIceCreamDecorator(iceCream)));
System.out.println("加香草加葡萄有加草莓冰淇淋价格为:"+vanillaStrawBerryGrapeIceCream.price());
IceCream twoGrapeIceCream = new GrapeIceCreamDecorator( new GrapeIceCreamDecorator(iceCream));
System.out.println("加两层葡萄也可以,价格为:"+twoGrapeIceCream.price());
}
}
装饰器(decorator)模式有效的避免了类爆炸,如上述代码所示,一个原味冰淇淋和三个装饰器就组合出了各种冰淇淋。如果采用多重继承(而且java中还不允许),则会产成很多子类。
装饰器模式与代理模式的比较
首先先说下区分设计模式是从语义上来说的,而不是语法。这个很关键。
面向对象编程中设计模式的实现基于面向对象的3个基本要素:封装、继承、多态。遵从面向对象的5个基本设计原则:单一职责原则(Single-Resposibility Principle),开放封闭原则(Open-Closed principle),Liskov替换原则(Liskov-Substituion Principle),依赖倒置原则(Dependecy-Inversion Principle),接口隔离原则(Interface-Segregation Principle)。因此有些设计模式其实看起来都是一样的,类似的,所以主要看这些设计模式是用来解决什么问题的,怎么解决的。
代理模式:为其他对象提供一个代理以控制对这个对象的访问. 关键在于控制。从语义上来说,一般会限制功能,而且如果增加的话一般和被代理的对象原方法不属于同一范畴,比如:打印日志/事务控制/计算方法时间等,从语法上你当然可以增加,随便增加什么功能。
装饰器模式:动态地给一个对象添加一些额外的职责。从语义上来说,是要增加功能的,而且基本上应该为和原来方法属于统一范畴的方法。比如说BufferedReader和InputStreamReader。但从语法上来说,又不是绝对的。
- 大小: 40.3 KB
分享到:
相关推荐
主要为大家详细介绍了java设计模式之装饰器模式Decorator,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
c++设计模式-结构型模式-装饰器模式;QT工程;c++简单源码; 装饰器(Decorator)模式的定义:指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式,它属于对象结构型模式。
装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。 这种模式创建了一个装饰类,用来包装原有的类,并在...
主要介绍了Python中设计模式之Decorator装饰器模式模式,文中详细地讲解了装饰对象的相关加锁问题,需要的朋友可以参考下
“就增加功能来说,Decorator 模式相比生成子类更为灵活” 这句话的含义是,组合比继承更灵活,当可拓展的功能很多时,继承方案会产生大量的子类,而组合可以提
主要介绍了Java设计模式之装饰模式(Decorator模式)介绍,本文讲解了为什么使用Decorator、如何使用装饰模式、Jive中的Decorator实现等内容,需要的朋友可以参考下
本文实例讲述了PHP设计模式之装饰器模式定义与用法。分享给大家供大家参考,具体如下: 什么是装饰器模式 作为一种结构型模式, 装饰器(Decorator)模式就是对一个已有结构增加”装饰”. 适配器模式, 是为现在有结构...
控制访问,装饰器设计的四个名词,装饰器模式与代理模式的区别,
主要介绍了PHP设计模式之装饰器(装饰者)模式(Decorator),结合实例形式详细分析了PHP装饰者模式的概念、原理、用法及相关操作注意事项,需要的朋友可以参考下
23种Python设计模式示例演示源码包,比如包括了工厂模式、Bridge桥接模式、Builder构建模式、Facade外观模式、Adapter适配器模式,Composite组合模式、Decorator装饰器模式,FactoryMethod工厂方法模式、Flyweight享...
C#面向对象设计模式纵横谈(10):Decorator 装饰模式(结构型模式) C#面向对象设计模式纵横谈(11):Facade 外观模式(结构型模式) C#面向对象设计模式纵横谈(12):Flyweight 享元模式(结构型模式) C#面向对象设计...
第22章 装饰模式(Decorator) 第23章 职责链模式(Chain of Responsibility) 第24章 桥接模式(Bridge) 第25章 访问者模式(Visitor) 附录A常见面向对象设计原则 附录BUML简介 参考文献
装饰器模式(Decorator Pattern) 外观模式(Facade Pattern) 享元模式(Flyweight Pattern) 代理模式(Proxy Pattern) 3 行为型模式 这些设计模式特别关注对象之间的通信。 责任链模式(Chain of ...
装饰器模式(Decorator Pattern) 外观模式(Facade Pattern) 享元模式(Flyweight Pattern) 代理模式(Proxy Pattern) 3. 行为型模式 责任链模式(Chain of Responsibility Pattern) 命令模式(Command ...
书名: 设计模式可复用面向对象软件的基础 英文原书名: Design Patterns:Elements of Reusable Object-Oriented software 作者: Erich Gamma 等 译者: 李英军 马晓星 蔡敏 刘建中 书号: 7-111-07575-7 页码: 254 定价...
主要介绍了PHP设计模式:装饰器模式Decorator,结合实例形式分析了PHP装饰器模式Decorator相关概念、功能、原理、用法及操作注意事项,需要的朋友可以参考下
C#设计模式(12)-Decorator Pattern 101 一、 装饰(Decorator)模式 101 二、 装饰模式的结构 102 三、 装饰模式示例性代码 103 四、 装饰模式应当在什么情况下使用 106 五、 装饰模式实际应用的例子 106 六、 ...
23种设计模式(Design Pattern)的C++实现范例,包括下面列出的各种模式,代码包含较详细注释。另外附上“设计模式迷你手册.chm” 供参考。 注:项目在 VS2008 下使用。 创建型: 抽象工厂模式(Abstract Factory) ...