装饰者模式 - OK
装饰模式(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("头发变精神了!");
}
}
}

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

装饰者模式的应用场景:
- 想透明并且动态地给对象增加新的职责的时候。
- 给对象增加的职责,在未来存在增加或减少可能。
- 用继承扩展功能不太现实的情况下,应该考虑用组合的方式。
装饰者模式的优点:
- 通过组合而非继承的方式,实现了动态扩展对象的功能的能力。
- 有效避免了使用继承的方式扩展对象功能而带来的灵活性差,子类无限制扩张的问题。
- 充分利用了继承和组合的长处和短处,在灵活性和扩展性之间找到完美的平衡点。
- 装饰者和被装饰者之间虽然都是同一类型,但是它们彼此是完全独立并可以各自独立任意改变的。
- 遵守大部分GRASP原则和常用设计原则,高内聚、低偶合。
装饰者模式的缺点:
- 装饰链不能过长,否则会影响效率。
- 因为所有对象都是继承于Component,所以如果Component内部结构发生改变,则不可避免地影响所有子类(装饰者和被装饰者),也就是说,通过继承建立的关系总是脆弱地,如果基类改变,势必影响对象的内部,而通过组合(Decoator HAS A Component)建立的关系只会影响被装饰对象的外部特征。
- 只在必要的时候使用装饰者模式,否则会提高程序的复杂性,增加系统维护难度。
装饰者模式 - OK的更多相关文章
- 装饰者模式 Decoration
1.什么是装饰者模式 动态给对象增加功能,从一个对象的外部来给对象添加功能,相当于改变了对象的外观,比用继承的方式更加的灵活.当使用装饰后,从外部系统的角度看,就不再是原来的那个对象了,而是使用一系列 ...
- JAVA装饰者模式(从现实生活角度理解代码原理)
装饰者模式可以动态地给一个对象添加一些额外的职责.就增加功能来说,Decorator模式相比生成子类更为灵活. 该模式的适用环境为: (1)在不影响其他对象的情况下,以动态.透明的方式给单个对象添加职 ...
- 设计模式(三):“花瓶+鲜花”中的装饰者模式(Decorator Pattern)
在前两篇博客中详细的介绍了"策略模式"和“观察者模式”,今天我们就通过花瓶与鲜花的例子来类比一下“装饰模式”(Decorator Pattern).在“装饰模式”中很好的提现了开放 ...
- 设计模式(九)装饰者模式(Decorator Pattern)
一.引言 在软件开发中,我们经常想要对一类对象添加不同的功能,例如要给手机添加贴膜,手机挂件,手机外壳等,如果此时利用继承来实现的话,就需要定义无数的类,如StickerPhone(贴膜是手机类).A ...
- PHP 装饰器模式
装饰器模式:是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能. [装饰器模式中主要角色] 抽象组件角色(Component):定义一个对象接口,以规范准备接受附加责任的对象,即可以给这 ...
- C#设计模式-装饰者模式
在软件开发中,我们经常想要对一类对象添加不同的功能,例如要给手机添加贴膜,手机挂件,手机外壳等,如果此时利用继承来实现的话,就需要定义无数的类,如StickerPhone(贴膜是手机类).Access ...
- Java 的设计模式之一装饰者模式
刚开始接触装饰者的设计模式,感觉挺难理解的,不够后来花了一个晚上的时间,终于有头绪了 装饰者设计模式:如果想对已经存在的对象进行装饰,那么就定义一个类,在类中对已经有的对象进行功能的增强或添加另外的行 ...
- 《Head First 设计模式》之装饰者模式
作者:Grey 原文地址:http://www.cnblogs.com/greyzeng/p/5922248.html 模式名称 装饰者模式(Decorator Pattern) 需求 定义咖啡厅中的 ...
- DecoratorPattern(装饰器模式)
/** * 装饰者模式 * @author TMAC-J * 总的来说,装饰者模式就是继承的应用 */ public class DecoratorPattern { interface Beans{ ...
- 设计模式-装饰器模式(Decrator Model)
文 / vincentzh 原文连接:http://www.cnblogs.com/vincentzh/p/6057666.html 目录 1.概述 2.目的 3.结构组成 4.实现 5.总结 1.概 ...
随机推荐
- Delphi EurekaLog 调试内存泄露方法
要使用EurekaLog进行内存泄露检测,需要手动开启"EurekaLog Options..."下的"Advanced Options"旁的"Mem ...
- codevs1044:dilworth定理
http://www.cnblogs.com/submarine/archive/2011/08/03/2126423.html dilworth定理的介绍 题目大意:求一个序列的lds 同时找出这个 ...
- sicily 1035. DNA matching
题意:判断基因链是否匹配,匹配的双链数加1,并要标记,下次比较不能重用! 解法: 打擂台法 #include<iostream> #include<string> #inclu ...
- linux中cat、more、less、tail、head命令
cat命令功能用于显示整个文件的内容单独使用没有翻页功能因此经常和more命令搭配使用,cat命令还有就是将数个文件合并成一个文件的功能. more命令功能:让画面在显示满一页时暂停,此时可按空格健继 ...
- XAMPP的MYSQL无法启动
昨天用各种方式试验MYSQL的数据库备份与恢复操作,恢复过程中,MYSQL就无法启动了. 提示如下: 22:59:43 [mysql] Attempting to start MySQL app... ...
- 经常使用ARM汇编指令
一面学习,一面总结,一面记录. 以下是整理在网上找到的一些资料,简单整理记录一下,方便以后查阅. ARM处理器的指令集能够分为跳转指令.数据处理指令.程序状态寄存器(PSR)处理指令.载入/存储指令. ...
- VB.NET入门基础
众所周知,Visual Basic.NET是由Visual Basic发展而来,这两者之间的升级使得Visual Basic语言发生了革命性的变革,使得由基于对象编程的Visual Basic过渡到了 ...
- UVA10765-Doves and bombs(BCC)
option=com_onlinejudge&Itemid=8&page=show_problem&problem=1706">题目链接 题意:给定一个n个点的 ...
- arcpagelistarclist列表分页
arcpagelistarclist列表分页 (DedeCMS 5.6) 名称:arcpagelist 功能:通过制定arclist的pagesize及tagid属性,配合arcpagelist标签进 ...
- NPM与调试工具的使用
1)NPM 2)nodemon 自动监视文件的变化并重启应用 3)pm2 启动node,资源共享 4)node-inspector node调试工具 5)Chrome Developer Tools