装饰者模式 - 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.概 ...
随机推荐
- 一道面试题与Java位操作 和 BitSet 库的使用
前一段时间在网上看到这样一道面试题: 有个老的手机短信程序,由于当时的手机CPU,内存都很烂.所以这个短信程序只能记住256条短信,多了就删了. 每个短信有个唯一的ID,在0到255之间.当然用户可能 ...
- [LeetCode] 35. Search Insert Position 解决思路
Given a sorted array and a target value, return the index if the target is found. If not, return the ...
- hadoop2.2.0的WordCount程序
package com.my.hadoop.mapreduce.wordcount; import java.io.IOException; import org.apache.hadoop.conf ...
- C++图结构的图结构操作示例
示例代码: /* By qianshou 2013/10/5明天就要开学了~哎~ */ #include<iostream> using namespace std; /********* ...
- window下安装FTP服务器
系统window8.1 1.安装IIS组件:点开始菜单-选择控制面板--程序--打开或关闭WINDOWS功能--展开Internet信息服务,勾选FTP服务器(包括FTP服务和FTP扩展性),点确定. ...
- css样式:列表
css code: /*系统自带的*/ ul li{ list-style-style: disc; } /*自定义图标*/ ul li{ list-style-image: url("im ...
- servlet过滤器配置白名单、黑名单
1.web.xml配置 <filter> <description>过滤是否登陆</description> <filter-name>encoding ...
- SQL Server 启用 xp_cmdshell 与bcp 使用
启用 xp_cmdshell 1: sp_configure 'show advanced options',1 2: reconfigure 3: GO 4: 5: sp_configure 'xp ...
- DELL RACADM 工具使用介绍
如果iDRAC的IP或者设置出现问题,不能够链接,那么可以通过RACADM这个程序在系统层面可以对iDRAC进行设置,使用的方法以及命令都在下边. RACADM provides command li ...
- tail-head
[root@rusky]# tail test3 #不加参数默认显示全部内容 line line2 line3 line4 line5 line6 line7 line8 line9 line10 [ ...