`
ihyperwin
  • 浏览: 434646 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

设计模式之装饰器模式(decorator)

阅读更多
   装饰器(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
分享到:
评论

相关推荐

    C#设计模式之Decorator 装饰模式

    装饰模式(Decorator Pattern)是设计模式中的一种结构型模式,它在不改变原有对象的基础上,通过添加额外的职责来扩展对象的功能。在C#中,装饰模式尤其适用于那些需要动态地增加或减少对象功能的情况,避免了使用...

    设计模式之装饰模式(Decorator Pattern)

    装饰模式(Decorator Pattern)是一种结构型设计模式,它在不改变原有对象的基础上,通过包裹一个对象并为其添加新的行为或责任,实现对对象功能的扩展。这种模式在软件开发中非常常见,尤其当需要在运行时动态改变...

    c++-设计模式之装饰模式(Decorator)

    装饰模式(Decorator Pattern)是一种结构型设计模式,允许在不改变对象接口的情况下,动态地为对象添加额外的职责或功能。装饰模式通常用于需要扩展对象功能而又不希望使用子类化的场景。 装饰模式的组成 组件接口...

    PHP设计模式(八)装饰器模式Decorator实例详解【结构型】

    装饰器模式(Decorator Pattern)是一种结构型设计模式,主要用于在运行时动态地给对象添加新的职责或行为,而不必改变现有对象的类定义。在面向对象编程中,装饰器模式提供了一种相对于继承更加灵活的方式来增强或...

    装饰器模式[Decorator]

    装饰器模式(Decorator)是一种设计模式,它允许在运行时向对象添加新的行为或责任,而无需修改对象的源代码。这种模式属于结构型模式,是面向对象设计中的一种非常实用的技术。 装饰器模式的核心思想是通过将一个...

    装饰器(Decorator)模式

    装饰器(Decorator)模式 装饰器(Decorator)模式是一种典型的结构型模式,主要用意是动态地为对象添加一些额外...装饰器模式是一种非常实用的设计模式,在软件设计中可以广泛地应用于解决类库膨胀和维护的困难问题。

    设计模式C++学习之装饰模式(Decorator)

    装饰模式(Decorator)是软件设计领域中一种非常实用的结构型设计模式,它允许我们向一个对象添加新的行为或责任,而无需修改该对象的源代码。在C++编程语言中,装饰模式常用于动态地扩展类的功能,使得类的行为在...

    设计模式之Decorator

    《设计模式之Decorator》 设计模式是软件工程中的一种最佳实践,它是在特定场景下解决常见问题的经验总结。Decorator模式是一种结构型设计模式,它的主要作用是为对象添加额外的功能,而无需修改对象的源代码。...

    [结构型模式] head first 设计模式之装饰者模式(decorator)

    装饰者模式(Decorator Pattern)是结构型设计模式之一,它允许在运行时向对象添加新的行为或职责,而无需修改对象的源代码。这个模式的名字来源于装饰艺术,它通过添加额外的装饰来增强一个物体的外观,同样地,...

    23设计模式之装饰器模式-前端篇.pptx

    在前端开发中,装饰器模式常用于实现AOP(面向切面编程),比如日志记录、性能监控、权限控制等功能。通过定义装饰器函数,可以在不侵入原代码逻辑的情况下,控制代码的执行流程。例如,可以创建一个`logDecorator`...

    设计模式-装饰器模式

    装饰器模式是一种结构型设计模式,它允许在不修改对象本身的情况下动态地为对象添加新的行为或职责。这种模式在软件工程中广泛应用,特别是在需要扩展已有功能而不影响原有代码结构时。在iOS开发中,装饰器模式同样...

    Java设计模式之装饰器模式.docx

    【Java设计模式之装饰器模式】装饰器模式是一种结构型设计模式,它的主要目的是在不修改已有对象的前提下,通过添加额外的职责来扩展对象的功能。这种模式遵循单一职责原则,使得扩展职责时不会破坏原有对象的结构。...

    通过C#实现设计模式-装饰模式(DecoratorPattern).rar

    装饰模式(Decorator Pattern)是一种结构型设计模式,它允许你向一个现有的对象添加新的功能,同时又不改变其结构。装饰模式通过创建一个装饰类,该类包装了原始类的实例,并在调用原始类方法之前或之后添加额外的...

    设计模式 t07Decorator

    在给定的“设计模式 t07Decorator”主题中,我们聚焦于装饰者模式(Decorator Pattern)。装饰者模式是一种结构型设计模式,它允许我们在运行时给对象添加新的行为或职责,而无需修改其原有代码。这种模式遵循开闭...

    c++设计模式-结构型模式-装饰器模式

    c++设计模式-结构型模式-装饰器模式;QT工程;c++简单源码; 装饰器(Decorator)模式的定义:指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式,它属于对象结构型模式。

    设计模式之装饰模式

    4. 具体装饰器(Concrete Decorator):实现了装饰器接口,并且持有具体组件的实例。它可以添加新的属性或行为,并调用具体组件的方法来实现装饰功能。 在C#代码示例中,我们可以创建一个`IComponent`接口,表示...

    java常用设计模式-装饰器模式

    装饰器模式(Decorator Pattern)是一种结构性设计模式,它允许您在不影响同一类的其他对象的行为的情况下,静态或动态地向单个对象添加行为。该模式非常有用,当您想要在运行时添加或删除对象的功能时,或者当您想...

    JAVA设计模式学习12——装饰器模式

    装饰器模式是面向对象设计模式的一种,主要用于在不改变原有对象结构的情况下,动态地为对象增加新的功能。这种模式在Java中尤其常见,因为它允许我们遵循“开闭原则”——对扩展开放,对修改关闭。 装饰器模式的...

Global site tag (gtag.js) - Google Analytics