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

装饰者模式(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. Strange Problem O(∩_∩)O~

    题目描述: 古代某个狱卒某天闲着没事想和两个罪犯玩个游戏,他找了个国际象棋盘,每个格子放上一个硬币,硬币长得都一样,正反都是狱卒自己决定. 之后他只让A罪犯观看棋盘,并随便指一个硬币告诉A罪犯,只要B ...

  2. Photo Shop 设置

    1. 编辑 > 首选项 > 单位与标尺 2. 面板 在『窗口』 菜单下开启: 工具 选项 信息(F8) 图层(F7) 历史记录 可以将设置好的面板保存下来,这样下次别人弄乱了你的面板后,你 ...

  3. DOM属性操作

    HTML attribute  --> DOM property 每个html属性都对应一个DOM对象属性,举个栗子: <div> <label for="userN ...

  4. 每日Scrum(7)

    今天是小组用来写文稿的日子,包括软件需求分析报告,概要设计报告,详细设计报告,数据库设计报告,软件测试报告,各组员领取自己的任务然后完成~

  5. android 基本布局(RelativeLayout、TableLayout等)使用方法及各种属性

        本文介绍 Android 界面开发中最基本的四种布局LinearLayout.RelativeLayout.FrameLayout.TableLayout 的使用方法及这四种布局中常用的属性. ...

  6. MySQL 调优基础(五) Linux网络

    1. TCP/IP模型 我们一般知道OSI的网络参考模型是分为7层:“应表会传网数物”——应用层,表示层,会话层,传输层,网络层,数据链路层,物理层.而实际的Linux网络层协议是参照了OSI标准,但 ...

  7. MongoDB学习——基础入门

    MongoDB--基础入门 MongoDB是目前比较流行的一种非关系型数据库(NoSql),他的优势这里不废话,我们关注怎么使用它. 安装 下载,首先肯定要去下载,我们去官网下载,在国内,可能没FQ可 ...

  8. Validation failed for one or more entities. See ‘EntityValidationErrors’解决方法

    Validation failed for one or more entities. See ‘EntityValidationErrors’解决方法 You can extract all the ...

  9. Java api 入门教程 之 JAVA的String 类

    1.String对象的初始化 由于String对象特别常用,所以在对String对象进行初始化时,Java提供了一种简化的特殊语法,格式如下: String s = “abc”; s = “Java语 ...

  10. 关于iOS构建版本提交iTunes后,一直不出现,没加号的解决方案

    最近第一次遇到,正常打包,上传iTunes App Store,都能正常upload. 也可能是因为刚升了Xcode 8 的缘故,莫名其妙的小问题... 描述如下: 如果进iTunes的活动界面,也能 ...