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

装饰者模式(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. 正则表达式 exec 获取字符串中的汉字

    要求:仅获取attr中的 “编辑发起状态的执行人表单” ,路径C:\fakepath\是不固定的,可以是C:\fakepath\hhh\hhhh\ 解决: var attr = C:\fakepath ...

  2. 利用yii2 gridview实现批量删除案例

    作者:白狼 出处:http://www.manks.top/article/yii2_gridview_deleteall本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置 ...

  3. Unknown tag

    <c:forEach items="" var="" varStatus="s">缺少<%@ taglib uri=&qu ...

  4. java容器(java编程思想第四版-读书笔记)

    容器类库图    List(interface) 次序是List最重要的特点:它保证维护元素特定的顺序.List为Collection添加了许多方法,使得能够向List中间插入与移除元素.(这只推荐L ...

  5. Java api 入门教程 之 JAVA的IO处理

    IO是输入和输出的简称,在实际的使用时,输入和输出是有方向的.就像现实中两个人之间借钱一样,例如A借钱给B,相对于A来说是借出,而相对于B来说则是借入.所以在程序中提到输入和输出时,也需要区分清楚是相 ...

  6. 烂泥:更换ESXI5.0管理网卡及管理IP地址

    本文由秀依林枫提供友情赞助,首发于烂泥行天下. 公司的服务器基本上都是在IDC机房里面的,为了更有效的利用服务器性能.所以有几台服务器,安装的是ESXI5.0做成虚拟化. 注意目前这些服务器都是双网卡 ...

  7. php遍历循环数组实现方法

    简单利用foreach for list each while来遍历数组,包括普通的一维数组与二维数组遍历方法,下面详细的介绍了每个函数的使用方法. $foreach = array(1,2,3); ...

  8. 关于SUID、SGID、Sticky

    SUID属性 passwd命令可以用于更改用户的密码,一般用户可以使用这个命令修改自己的密码.但是保存用户密码的/etc/shadow文件的权限是400,也就是说只有文件的所有者root用户可以写入, ...

  9. C语言怎么将用户账号密码写入文件实现登录注册功能?

    创建储存用户账号密码的文件: void Create_File() { FILE *fp; if ((fp = fopen("users.txt","rb")) ...

  10. Linux nm命令

    一.简介 显示关于对象文件.可执行文件以及对象文件库里的符号信息. 二.选项 http://www.cnblogs.com/wangkangluo1/archive/2012/07/02/257243 ...