挖了设计模式这个坑,得继续填上。继续设计模式之路。这次讨论的模式,是

装饰者模式(Decorator Pattern)

装饰者模式,有时也叫包装者(Wrapper),主要用于静态或动态地为一个特定的对象增加新的特性,而不影响这个对象的类(allows behavior to be added to an individual object, either statically or dynamically, without affecting the behavior of other objects from the same class)。

装饰者模式,主要用处是,灵活方便地增加特性到特定的对象上。请看下面的例子:

 /**
* Coffee interface defines the functionality of Coffee implemented by decorator
* @author YYC
*
*/
public interface ICoffee { double getCost(); String getIngredients(); } /**
* extension of a simple coffee without any extra ingredients
* @author YYC
*
*/
public class SimpleCoffee implements ICoffee{ public double getCost() {
return 1;
} public String getIngredients() {
return "Coffee";
} } /**
* abstract decorator class - note that it implement Coffee interface
* @author YYC
*
*/
public abstract class CoffeDecorator implements ICoffee { protected final ICoffee decoratedCoffee;
protected String ingredientSeparator = ","; public CoffeDecorator(ICoffee decoratedCoffee) {
this.decoratedCoffee = decoratedCoffee;
} public double getCost(){
return decoratedCoffee.getCost();
} public String getIngredients(){
return decoratedCoffee.getIngredients();
} }

首先对于装饰者模式而已,一个公共的接口是必须的,在这里是ICoffee,代表咖啡的抽象接口。然后需要有一个简单的实现类以及一个装饰者的抽象类,作为具体装饰者的父类。接下来的是具体的装饰者类:

 /**
* Decorator Milk that mixes milk with coffee
* @author YYC
*
*/
public class Milk extends CoffeDecorator { public Milk(ICoffee decoratedCoffee) {
super(decoratedCoffee);
} public double getCost() {
return super.getCost() + 0.5;
} public String getIngredients() {
return super.getIngredients() + ingredientSeparator + "Milk";
} } /**
* @author YYC
* Decorator Sprinkles that mixes sprinkles with coffee
*/
public class Sprinkles extends CoffeDecorator { public Sprinkles(ICoffee decoratedCoffee) {
super(decoratedCoffee);
} public double getCost() {
return super.getCost() + 1.2;
} public String getIngredients() {
return super.getIngredients() + ingredientSeparator + "Sprinkles";
} }

具体的装饰者类,继承抽象装饰者类,并具体实现抽象装饰者类的方法,达到将新的特性(milk/sprinkles)加到原来的类(coffee)的目的。

public class Main {

    public static void main(String[] args) {

        ICoffee c = new SimpleCoffee();
System.out.println("Cost: " + c.getCost() + "; Ingredients: " + c.getIngredients()); c = new Milk(c);
System.out.println("Cost: " + c.getCost() + "; Ingredients: " + c.getIngredients()); c = new SimpleCoffee();
c = new Sprinkles(c);
System.out.println("Cost: " + c.getCost() + "; Ingredients: " + c.getIngredients()); c=new SimpleCoffee();
c = new Milk(new Sprinkles(c));
System.out.println("Cost: " + c.getCost() + "; Ingredients: " + c.getIngredients()); } } /*
* output:
* Cost: 1.0; Ingredients: Coffee
* Cost: 1.5; Ingredients: Coffee,Milk
* Cost: 2.2; Ingredients: Coffee,Sprinkles
* Cost: 2.7; Ingredients: Coffee,Sprinkles,Milk
*/

抽象类理解起来并不困难,而且相当实用,很多时候比创建子类更加灵活。在Java里java.io.BufferedReader/FileReader/Reader都有使用这个模式。

以下情况使用Decorator模式

1. 需要扩展一个类的功能,或给一个类添加附加职责。

2. 需要动态的给一个对象添加功能,这些功能可以再动态的撤销。

3. 需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变的不现实。

4. 当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。

优点:

1. Decorator模式与继承关系的目的都是要扩展对象的功能,但是Decorator可以提供比继承更多的灵活性。

2. 通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合。

缺点:

1. 这种比继承更加灵活机动的特性,也同时意味着更加多的复杂性。

2. 装饰模式会导致设计中出现许多小类,如果过度使用,会使程序变得很复杂。

3. 装饰模式是针对抽象组件(Component)类型编程。但是,如果你要针对具体组件编程时,就应该重新思考你的应用架构,以及装饰者是否合适。当然也可以改变Component接口,增加新的公开的行为,实现“半透明”的装饰者模式。在实际项目中要做出最佳选择。

参考:

http://javapapers.com/design-patterns/decorator-pattern/

http://www.cnblogs.com/god_bless_you/archive/2010/06/10/1755212.html

浅谈设计模式--装饰者模式(Decorator Pattern)的更多相关文章

  1. 设计模式 - 装饰者模式(Decorator Pattern) Java的IO类 用法

    装饰者模式(Decorator Pattern) Java的IO类 用法 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26716 ...

  2. 设计模式 - 装饰者模式(Decorator Pattern) 具体解释

    装饰者模式(Decorator Pattern) 具体解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26707033 装饰者 ...

  3. C#设计模式——装饰者模式(Decorator Pattern)

    一.例子在软件开发中,我们往往会想要给某一类对象增加不同的功能.比如要给汽车增加ESP.天窗或者定速巡航.如果利用继承来实现,就需要定义无数的类,Car,ESPCar,CCSCar,SunRoofCa ...

  4. 浅谈设计模式--建造器模式(Builder Pattern)

    建造器模式,是于创建带有大量参数的对象,并避免因参数数量多而产生的一些问题(如状态不一致-JavaBean的setter模式). 如果参数多且有些是必须初始化的,有些是不一定需要初始化的时候,创建对象 ...

  5. 设计模式学习--装饰者模式(Decorator Pattern)

    概念: 装饰者模式(Decorator Pattern): 动态地将功能添加到对象,相比生成子类更灵活,更富有弹性. 解决方案: 装饰者模式的重点是对象的类型,装饰者对象必须有着相同的接口,也也就是有 ...

  6. 大话设计模式--装饰者模式 Decorator -- C++实现实例

    1.装饰者模式 Decorator 动态地给一个对象添加一个额外的职责, 就添加功能来说, 装饰模式比生成子类更为灵活. 每个装饰对象的实现和如何使用这个对象分离,  每个装饰对象只关心自己的功能,不 ...

  7. 23种设计模式之装饰器模式(Decorator Pattern)

    装饰器模式(Decorator Pattern) 允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装饰类,用来包 ...

  8. 设计模式(三):“花瓶+鲜花”中的装饰者模式(Decorator Pattern)

    在前两篇博客中详细的介绍了"策略模式"和“观察者模式”,今天我们就通过花瓶与鲜花的例子来类比一下“装饰模式”(Decorator Pattern).在“装饰模式”中很好的提现了开放 ...

  9. C#设计模式之装饰者模式(Decorator Pattern)

    1.概述 装饰者模式,英文名叫做Decorator Pattern.装饰模式是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能.它是通过创建一个包装对象,也就是装饰来包裹真实的对象. 2 ...

随机推荐

  1. Android Studio中怎么使用DDMS工具?

    随着android studio的广泛使用,开发人员对相关工具的使用需求更加凸显.昨天在一个android studio教程网站上,看到一篇有关DDMS工具使用的相关知识,感觉很不错,分享给大家,一起 ...

  2. windows server 开机自动登录并锁定

    这个操作对于广大使用Windows(包括xp/win7/2003/2008 R2 等windows 系统) 的上班族会有点用. 其一:如果是个人吧系统(win7.xp)上班时候打开电脑,自动登录,系统 ...

  3. WPF学习之路(二) XAML

    在WPF中引入了XAML语言,主要用于界面设计,业务逻辑则使用C#实现后台代码,将界面设计与业务逻辑分离 XAML是一种声明式语言,类似XML\HTML 示例: <!--Start Tag--& ...

  4. SQL动态列查询

    数据库中为了实现表格数据的自由设置,我们经常设计纵表,或者列定义的表(如下KeyValue),定义一个列超级多的表中每个字段的意义. 但是在设计时简单的东西却很容易被人们忘记,如下一个简单但是很松散的 ...

  5. Oracle not in子连接查询不到值的问题(not in 不能查询null数据)

    前几天在项目中,做数据导入时,发现not in和in 查出来的条数不互补.ATABLE2明明中有些记录在ATABLE3中不存在,但是not in时查不出记录. CREATE TABLE ATABLE2 ...

  6. linux权限补充:rwt rwT rws rwS 特殊权限

    众所周知,Linux的文件权限如: 777:666等,其实只要在相应的文件上加上UID的权限,就可以用到加权限人的身份去运行这个文件.所以我们只需要将bash复制出来到另一个地方,然后用root加上U ...

  7. input子系统

    input子系统:      像按键.键盘.鼠标.触摸屏.游戏摇杆等设备只有输入没有输出,而且在编程实现其对应的驱动程序时会有很多重复性的代码,内核的设计者将该部分代码抽象出来,驱动工程师只需要复用该 ...

  8. node js学习(一)

    1.简介 JavaScript是一种运行在浏览器的脚本,它简单,轻巧,易于编辑,这种脚本通常用于浏览器的前端编程,但是一位开发者Ryan有一天发现这种前端式的脚本语言可以运行在服务器上的时候,一场席卷 ...

  9. HDU 4866 Shooting(持久化线段树)

    view code//第二道持久化线段树,照着别人的代码慢慢敲,还是有点不理解 #include <iostream> #include <cstdio> #include & ...

  10. [转] Finding the Best Programmer's Font

    原文 Finding the Best Programmer's Font