装饰模式(Decorator),动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。

   装饰者模式隐含的是通过一条条装饰链去实现具体对象,每一条装饰链都始于一个Componet对象,每个装饰者对象后面紧跟着另一个装饰者对象,而对象链终于ConcreteComponet对象。

  用粗略的话讲:装饰模式就是为已有功能动态地添加更多功能的一种方式。

  何为动态。比如打折策略。3折后再减30元再打8折,

  UML图如下:

    

  Component是定义一个对象接口,可以给这些对象动态地添加职责。ConcreteComponent是定义了一个具体的对象,也可以给这个对象添加一些职责。Decorator,装饰着抽象类,继承了Component从外类来扩展Component类的功能,但对于Component来说,就无需知道Decorator的存在的。至于ConcreteDecorator就是具体的装饰对象。起到给Component添加职责的功能。

  实现代码示例:

  装饰模式是利用SetComponent来对对象进行包装的。这样每个装饰对象的实现就和如何使用这个对象分离开了。每个装饰对象只关心自己的功能,不需要关心如何被添加到对象链当中。

  示例:

namespace 装饰者模式
{
class Program
{
static void Main(string[] args)
{
ConcreateComponent c = new ConcreateComponent();
ConcreteDecorator眉毛 d1 = new ConcreteDecorator眉毛();
ConcreteDecorator头发 d2 = new ConcreteDecorator头发(); d1.SetComponent(c); //d1里面放入c,是为了调用原始c的 捕获素颜美女
d2.SetComponent(d1); //d1是画过眉毛的
d2.Operation(); Console.ReadKey();
}
} abstract class Component
{
public abstract void Operation();
} class ConcreateComponent : Component
{
//原始内容,具体装饰类都会调用一次
public override void Operation()
{
Console.WriteLine("捕获素颜美女一个!");
}
} abstract class Decorator : Component
{
//里面放一个父接口
protected Component component; public void SetComponent(Component component) //设置Component
{
this.component = component;
} public override void Operation() //用接收到的Component的Operation方法来重写父Component接口的Operation方法
{
if (component != null)
{
component.Operation();
}
}
} class ConcreteDecorator眉毛 : Decorator
{
private string addedState; //代表画眉毛的实际操作 public override void Operation()
{
base.Operation(); //素颜美女(原始内容)
Console.WriteLine("帮美女画画眉!");
addedState = "眉毛漂亮了!"; //实际装饰内容
}
} class ConcreteDecorator头发 : Decorator
{
public override void Operation()
{
base.Operation(); //原始内容
Console.WriteLine("帮美女梳梳头!");
AddedBehavior(); //实际装饰内容
} private void AddedBehavior() //本类独有的方法,以区别于ConcrateDecoratorA
{
Console.WriteLine("头发变精神了!");
}
}
}

  这个示例写得不错,基本上掌握了装饰者的作用。

  

  装饰者模式的应用场景:

  1. 想透明并且动态地给对象增加新的职责的时候。
  2. 给对象增加的职责,在未来存在增加或减少可能。
  3. 用继承扩展功能不太现实的情况下,应该考虑用组合的方式。

  装饰者模式的优点:

  1. 通过组合而非继承的方式,实现了动态扩展对象的功能的能力。
  2. 有效避免了使用继承的方式扩展对象功能而带来的灵活性差,子类无限制扩张的问题。
  3. 充分利用了继承和组合的长处和短处,在灵活性和扩展性之间找到完美的平衡点。
  4. 装饰者和被装饰者之间虽然都是同一类型,但是它们彼此是完全独立并可以各自独立任意改变的。
  5. 遵守大部分GRASP原则和常用设计原则,高内聚、低偶合。

  装饰者模式的缺点:

  1. 装饰链不能过长,否则会影响效率。
  2. 因为所有对象都是继承于Component,所以如果Component内部结构发生改变,则不可避免地影响所有子类(装饰者和被装饰者),也就是说,通过继承建立的关系总是脆弱地,如果基类改变,势必影响对象的内部,而通过组合(Decoator HAS A Component)建立的关系只会影响被装饰对象的外部特征。
  3. 只在必要的时候使用装饰者模式,否则会提高程序的复杂性,增加系统维护难度。
 
 
分类: 设计模式
 
0
0
 
(请您对文章做出评价)
 
« 上一篇:策略模式 - OK
» 下一篇:代理模式 - OK

装饰者模式 - OK的更多相关文章

  1. 装饰者模式 Decoration

    1.什么是装饰者模式 动态给对象增加功能,从一个对象的外部来给对象添加功能,相当于改变了对象的外观,比用继承的方式更加的灵活.当使用装饰后,从外部系统的角度看,就不再是原来的那个对象了,而是使用一系列 ...

  2. JAVA装饰者模式(从现实生活角度理解代码原理)

    装饰者模式可以动态地给一个对象添加一些额外的职责.就增加功能来说,Decorator模式相比生成子类更为灵活. 该模式的适用环境为: (1)在不影响其他对象的情况下,以动态.透明的方式给单个对象添加职 ...

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

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

  4. 设计模式(九)装饰者模式(Decorator Pattern)

    一.引言 在软件开发中,我们经常想要对一类对象添加不同的功能,例如要给手机添加贴膜,手机挂件,手机外壳等,如果此时利用继承来实现的话,就需要定义无数的类,如StickerPhone(贴膜是手机类).A ...

  5. PHP 装饰器模式

    装饰器模式:是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能. [装饰器模式中主要角色] 抽象组件角色(Component):定义一个对象接口,以规范准备接受附加责任的对象,即可以给这 ...

  6. C#设计模式-装饰者模式

    在软件开发中,我们经常想要对一类对象添加不同的功能,例如要给手机添加贴膜,手机挂件,手机外壳等,如果此时利用继承来实现的话,就需要定义无数的类,如StickerPhone(贴膜是手机类).Access ...

  7. Java 的设计模式之一装饰者模式

    刚开始接触装饰者的设计模式,感觉挺难理解的,不够后来花了一个晚上的时间,终于有头绪了 装饰者设计模式:如果想对已经存在的对象进行装饰,那么就定义一个类,在类中对已经有的对象进行功能的增强或添加另外的行 ...

  8. 《Head First 设计模式》之装饰者模式

    作者:Grey 原文地址:http://www.cnblogs.com/greyzeng/p/5922248.html 模式名称 装饰者模式(Decorator Pattern) 需求 定义咖啡厅中的 ...

  9. DecoratorPattern(装饰器模式)

    /** * 装饰者模式 * @author TMAC-J * 总的来说,装饰者模式就是继承的应用 */ public class DecoratorPattern { interface Beans{ ...

  10. 设计模式-装饰器模式(Decrator Model)

    文 / vincentzh 原文连接:http://www.cnblogs.com/vincentzh/p/6057666.html 目录 1.概述 2.目的 3.结构组成 4.实现 5.总结 1.概 ...

随机推荐

  1. 2015第24周五Spring的AOP

    AOP(面向方面编程:Aspect Oriented Programing)和IoC一样是Spring容器的内核,声明式事务的功能在此基础上开花结果.但AOP的应用场合是受限的,它一般只适合于那些具有 ...

  2. HDU_1426——数独问题,DFS

    Problem Description 自从2006年3月10日至11日的首届数独世界锦标赛以后,数独这项游戏越来越受到人们的喜爱和重视. 据说,在2008北京奥运会上,会将数独列为一个单独的项目进行 ...

  3. HDU-3787(字符串模拟)

    Problem Description 给定两个整数A和B,其表示形式是:从个位开始,每三位数用逗号","隔开.现在请计算A+B的结果,并以正常形式输出.   Input 输入包含 ...

  4. JavaScript学习笔记(高级部分—01)

    JavaScript的核心ECMAScript描述了该语言的语法和基本对象:DOM描述了处理网页内容的方法和接口:BOM描述了与浏览器进行交互的方法和接口. 简单说,ECMAScript描述了以下内容 ...

  5. (各个公司面试原题)在线做了一套CC++综合測试题,也来測一下你的水平吧(二)

    刚才把最后的10道题又看了下.也发上来吧. 以下给出试题.和我对题目的一些理解 前10道题地址 (各个公司面试原题)在线做了一套CC++综合測试题.也来測一下你的水平吧(一) 11.设已经有A,B,C ...

  6. 使用Eclipse生成自动生成apk

    使用Eclipse生成自动生成apk     在eclipse的Preferences -> Android -> Build中有一项“Skip packaging and dexing ...

  7. (1)QlikView概要

    本文的内容,以学习的两个合伙人: I.什么是Qlikview II. QlikView 的优点和缺点 1.1什么是QlikView 1.1什么是QlikView QlikView是一个工具,一个商业智 ...

  8. ios 绘制wav波形图

    最近研究了如何在iOS上绘制wav波形图.查了很多资料,都没能找到一个很完整的介绍,我这里总结一下一些经验. 首先需要了解wav的这3个重要指标:采样率.采样位数.声道数.下面以16KHz, 16Bi ...

  9. How to get multi-touch working(Linux and Andriod)

    1.在hid-ids.h中加入vid pid           2.在hid-multitouch..c->mt_devices[] 中加入          {                ...

  10. Gradle的简介、安装与配置

    Gradle介绍 Gradle是一个基于JVM的构建工具,它提供了: 像Ant一样,通用灵活的构建工具,对Ant的任务做了很好的集成 同Maven一样是基于约定的构建框架 强大的多工程构建支持.有广泛 ...