当前位置: 首页 > 编程日记 > 正文

装饰模式(Decorator Pattern)

装饰模式(Decorator Pattern

一句话                                                                

继承一个抽象类,加上自己的特点,然后再使自己也变成抽象类,然后让子类继承的模式,叫装饰模式

意图

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

结构图

生活中的例子

     我们还是拿咖啡来举例子,现在有需要泡一杯咖啡出来。泡咖啡的几个步骤:

1.    磨咖啡豆

2.    煮。

先定义一个接口

public interface MakeCoffee
{
  public void milling();//

public void cook();//

}

//来一杯蓝山咖啡

public class Blue_Mountain_Coffee : MakeCoffee

{
  public void milling()

{
    //代码略
  }

  public void cook()

{
    //代码略
  }

}

现在要来杯卡布奇诺Cappuccino,那么需要加入“做泡泡”的行为。

如果是按一般的方法,在接口内加入“做泡泡(Bubbles)”的行为。但是这样的话,做其他咖啡的时候都必须去实现Bubbles的行为,这样代码就很罗嗦。

所以,我们引入一个简单的处理,装饰模式(Decorator Pattern

public abstract class Decorator : MakeCoffee

{

  public void milling();

  public void cook();

   public void Bubbles();

}

所有要做泡泡的咖啡都来继承这个类。

//来一杯卡布奇诺咖啡

public class Cappuccino : MakeCoffee

{
  public void milling()

{
    //代码略
  }

  public void cook()

{
    //代码略
  }

  public void Bubbles()

{
    //代码略
  }

  public void MakeCoffee()

{
    milling();//磨咖啡豆

cook();//

Bubbles();//做泡泡
  }

}

好了,打完收工。

装饰模式解说

我们分析一下这样会带来什么好处?首先对于扩展功能已经实现了真正的动态增加,只在需要某种功能的时候才进行包装;其次,如果再出现一种新的扩展功能,只需要增加一个对应的包装子类(注意:这一点任何时候都是避免不了的),而无需再进行很多子类的继承,不会出现子类的膨胀,同时Decorator模式也很好的符合了面向对象设计原则中的“优先使用对象组合而非继承”和“开放-封闭”原则。

.NET中的装饰模式

1.NETDecorator模式一个典型的运用就是关于Stream,它存在着如下的类结构:

可以看到, BufferedStreamCryptoStream其实就是两个包装类,这里的Decorator模式省略了抽象装饰角色(Decorator),示例代码如下:

class Program

{

    public static void Main(string[] args)

    {

        MemoryStream ms =

            new MemoryStream(new byte[] { 100,456,864,222,567});

 

        //扩展了缓冲的功能

        BufferedStream buff = new BufferedStream(ms);

 

        //扩展了缓冲,加密的功能

        CryptoStream crypto = new CryptoStream(buff);

    }

}

通过反编译,可以看到BufferedStream类的代码(只列出部分),它是继承于Stream类:

public sealed class BufferedStream : Stream

{

    // Methods

    private BufferedStream();

    public BufferedStream(Stream stream);

    public BufferedStream(Stream stream, int bufferSize);

    // Fields

    private int _bufferSize;

    private Stream _s;

}

2.在Enterprise Library中的DAAB中有一个DbCommandWrapper的包装类,它实现了对IDbCommand类的包装并提供了参数处理的功能。结构图如下:

示意性代码如下:

public abstract class DBCommandWrapper : MarshalByRefObject, IDisposable

{

 

}

public class SqlCommandWrapper : DBCommandWrapper

{

   

}

public class OracleCommandWrapper : DBCommandWrapper

{

 

}

效果及实现要点

1Component类在Decorator模式中充当抽象接口的角色,不应该去实现具体的行为。而且Decorator类对于Component类应该透明,换言之Component类无需知道Decorator类,Decorator类是从外部来扩展Component类的功能。

2Decorator类在接口上表现为is-a Component的继承关系,即Decorator类继承了Component类所具有的接口。但在实现上又表现为has-a Component的组合关系,即Decorator类又使用了另外一个Component类。我们可以使用一个或者多个Decorator对象来“装饰”一个Component对象,且装饰后的对象仍然是一个Component对象。

3Decortor模式并非解决“多子类衍生的多继承”问题,Decorator模式的应用要点在于解决“主体类在多个方向上的扩展功能”——是为“装饰”的含义。

4.对于Decorator模式在实际中的运用可以很灵活。如果只有一个ConcreteComponent类而没有抽象的Component类,那么Decorator类可以是ConcreteComponent的一个子类。

如果只有一个ConcreteDecorator类,那么就没有必要建立一个单独的Decorator类,而可以把DecoratorConcreteDecorator的责任合并成一个类。

5Decorator模式的优点是提供了比继承更加灵活的扩展,通过使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同行为的组合。

6.由于使用装饰模式,可以比使用继承关系需要较少数目的类。使用较少的类,当然使设计比较易于进行。但是,在另一方面,使用装饰模式会产生比使用继承关系更多的对象。更多的对象会使得查错变得困难,特别是这些对象看上去都很相像。

适用性

在以下情况下应当使用装饰模式:

1.需要扩展一个类的功能,或给一个类增加附加责任。

2.需要动态地给一个对象增加功能,这些功能可以再动态地撤销。

3.需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变得不现实。

总结

Decorator模式采用对象组合而非继承的手法,实现了在运行时动态的扩展对象功能的能力,而且可以根据需要扩展多个功能,避免了单独使用继承带来的“灵活性差”和“多子类衍生问题”。同时它很好地符合面向对象设计原则中“优先使用对象组合而非继承”和“开放-封闭”原则。

 

转载于:https://www.cnblogs.com/hainange/archive/2007/07/17/6153379.html

相关文章:

python 区域和检索_304. 二维区域和检索(Python)

题目难度:★★★☆☆类型:二维数组方法:动态规划给定一个二维矩阵,计算其子矩形范围内元素的总和,该子矩阵的左上角为 (row1, col1) ,右下角为 (row2, col2)。示例:给定 matrix [[3, 0, 1, 4, 2],[5, 6, 3…

观察者模式(Observer Pattern)(二):HeadFirst中的气象站的实现

1 观察者模式的原理,首先由一个主题,当主题发送变化的时候,通知该主题的订阅者 按照上面的分析我们来进行设计 1.抽象主题Subject public interface Subject {public void registerObserver(Observer o);public void removeObserver(Observer…

专访图灵奖得主John Hopcroft:中国必须提升本科教育水平,才能在AI领域赶上美国

AI技术年度盛会即将开启!11月8-9日,来自Google、Amazon、微软、Facebook、LinkedIn、阿里巴巴、百度、腾讯、美团、京东、小米、字节跳动、滴滴、商汤、旷视、思必驰、第四范式、云知声等企业的技术大咖将带来工业界AI应用的最新思维。 如果你是某个AI技…

完整复现何恺明ICCV获奖论文结果并开源 !(附论文开源代码)

ICCV 作为计算机视觉的顶级会议,2017年共收到2143篇论文投稿,比上一届ICCV2015的1698篇增加了26.2%。共621篇被选为大会论文,录用比例28.9%;poster、spotlight、oral 比例分别为24.61%、2.61%和2.09%。组委会根据作者署名统计了不…

电子合同的履行_什么是电子合同履行?怎么履行电子合同?

随着互联网产业的发展,许多传统产业都与互联网接轨,人们的传统生活方式也在转变。现在许多人的各种消费都喜欢在方便、快捷的互联网上进行,就连严肃的合同签订也是如此。不过还有很多人不知道什么是电子合同履行,下面律图小编就为…

10月机器学习开源项目Top10

作者 | Mybridge 译者 | 林春眄 整理 | Jane 出品 | AI科技大本营 【导读】过去一个月里,我们对近 250 个机器学习开源项目进行了排名,并挑选出热度前 10 的项目。这份清单的平均 github star 数量高达 1345,涵盖了包括深度学习, Tensorfl…

用SDM架构Cisco IOS ***图文详解全攻略(一)——easy ***

在测试***的过程中发现网上资料少少,于是自己花点力气写几篇普及教程,希望转贴的朋友给与支持,不要忘记署上原创是水煮豆豆的大名,嘿嘿~Cisco给我们提供了管理路由器的很好的安全工具SDM,同时也给我们提供了…

HP 服务器使用 SmartStart CD 引导安装 windows 2008 操作系统

1. 使用SmartStart CD引导安装之前的准备工作:首先,先根据自己的需要配置好RAID,可以使用开机自检检测到阵列卡时按F8进入ORCA的方法配置,也可以使用SmartStart CD中附带的ACU工具配置。其次,需要确认BIOS中启动顺…

parameter缩略语_缩略语

缩略语AccAccelerate(加速)BFBreakerfailure(断路器失灵)BRCBBuferReportControlBloc(有缓存报告控制块)CIDConfiguredIEDDescription(IED实例配置文件)CTCurrenttransformer(电流互感器)DevDevice(设备)ErrError(错误)FstFirst(第一个)GOOSE,GoGenericobjectorientedsubstatio…

[译]怎样用VisualStudio查看非托管代码

(译者:这篇文章作者是一位美国的MVP,这是他的系列文章"Under the cover"的第一篇,文章的本意从最底层的角度来优化代码的性能,并作为阅读作者其他文章的技术基础,这种通过这样的做法虽然初看起来有些过分,但是对读者了解.Net许多底层运作是十分有益的) 我们从使用vi…

盘点互联网大厂AI战略变迁,开发者将怎样pick前进路线?

随着各大企业相继试水“全面 AI”,人工智能在技术落地层面也开始持续深入,泛人工智能时代正在逼近。越来越多的发展趋势表明,未来的人工智能将逐步迈入广泛普及阶段,继而深入影响人类日常的生产生活方式,重塑传统生产结…

druid拦截器_CMS基于SpringBoot+Shiro+Mybatis+Druid+layui后台管理系统

contentManagerSystem后台管理系统简介contentManagerSystem,后台管理系统,采用SpringBoot构建整个项目框架,apacheShiro权限验证,mybatisdruid数据持久化动作,前端采用layui(http://www.layui.com/)展示,整个项目全部通过注解方式进行配置,具体大家可以…

Boost::asio io_service 实现分析

io_service的作用 io_servie 实现了一个任务队列,这里的任务就是void(void)的函数。Io_servie最常用的两个接口是post和run,post向任务队列中投递任务,run是执行队列中的任务,直到全部执行完毕,并且run可以被N个线程调…

叮!你有一份2018英特尔人工智能大会的邀请函,请查收!

AI赋能的数字化应用,作为时代发展的核心驱动力,已经成为改变各行各业的神奇力量。想要准确把握智能时代的发展航向,领航舵手英特尔已向你发出邀请:2018英特尔人工智能大会,欢迎你的到来!11月14日-15日&…

赢得高薪的锦囊三秘诀

作者:jingch 来源:南京竞成 时间:2007-6-27 10:58:40 秘诀一 获得高薪的必备素质通过对一些高收入的外企白领阶层的调查发现,高学历并不与高收入划等号,高薪收入者的基本素质上的优势才是他们获得高薪的关键。概括起…

可疑文件_【国家标准】印刷文件鉴定技术规范点阵式打印文件的同机鉴定

印刷文件鉴定技术规范(GB/T 37232-2018)总则印刷文件同机(同版)鉴定的受理程序、送检材料的标识、检验鉴定程序、送检材料的流转程序及结果报告程序应按GB/T 37234-2018第4章~第8章中相应的要求。印刷文件同机鉴定分为传统制版文件同机鉴定和办公设备机制文件同机鉴定。其中,办…

前端开发神器之ngrok

ngrok能做什么,为什么是前端开发神器? 内网穿透,映射本地开发环境到公网,模拟多终端线上环境。 结合一个很简单的PWA demo,举个简单的例子 1.克隆demo到本地 git clone https://github.com/minimal-xyz/minimal-pwa.gi…

YC陆奇发起知乎第一问:怎样的环境才能让更多AI创业公司成功?

“在人工智能时代,怎样的创新环境和措施能让更多科技驱动的创业公司成功,使其不再是大型科技公司的专利?” 一周前,知乎发起了“2018 互联网洞见者”提问,先后邀请到鹅厂厂长马化腾、“风投女王”徐新、香港科技大学杨…

Linq to SQL 资源

Scott Guthrie 的 Linq to SQL 系列:1)介绍http://weblogs.asp.net/scottgu/archive/2007/05/19/using-linq-to-sql-part-1.aspx 2)定义数据模型http://weblogs.asp.net/scottgu/archive/2007/05/29/linq-to-sql-part-2-defining-our-data-model-classes.aspx 3)查询…

首发|机器学习未来十年:你需要把握的趋势和热点

CSDN 出品的《2018-2019 中国人工智能产业路线图》V2.0 版即将重磅面世! V1.0 版发布以来,我们有幸得到了诸多读者朋友及行业专家的鼎力支持,在此表示由衷感谢。此次 V2.0 版路线图将进行新一轮大升级,力求为读者呈现更全面的中国…

web前端知识点太多_初学web前端,学习方法容易走偏,这是为什么?

一、了解web前端所谓“知己知彼,百战不殆”,在学习web前端之前,还是让我们先了解一下什么是web前端吧!所有用户终端产品与视觉和交互有关的部分,都属于前端开发的领域。从狭义上讲,Web前端就是用HTML、CSS、…

2017-2018 ACM-ICPC, NEERC, Southern Subregional Contest

A. Automatic Door 对于规律的点可以推公式计算&#xff0c;对于噪点则暴力计算&#xff0c;时间复杂度$O(m\log m)$。 #include<stdio.h> #include<iostream> #include<string.h> #include<string> #include<ctype.h> #include<math.h> #…

正则过滤非法字符

小写英文&#xff1a;大写英文&#xff1a;任意数字&#xff1a;限2位小数&#xff1a; 如: 123.12日  期&#xff1a; 如: 2002-9-29任意中文&#xff1a;部分英文&#xff1a; 范围: a,b,c,d,e部分中文&#xff1a; 范围: 一二三四五六七八九十有关正则表达式 ?.只能输入数…

emoji 乱码_这个自制emoji的网站,让你成为永远不输的斗图王者

作为表情界的元老级人物&#xff0c;不管是苹果官网输入法、微信官方表情还是各个主流输入法里&#xff0c;我们都可以从里面找到大量 emoji 表情。然鹅……就算这么多表情&#xff0c;小帮每次发 emoji 时还有有些选择困难。因为翻遍所有表情&#xff0c;都没法找到合适的啊&a…

[vijos1234]口袋的天空最小生成树

题目链接&#xff1a;https://vijos.org/p/1234 白天刚刚写完prim的算法&#xff0c;晚上就心血来潮的打了一道最小生成树的题 虽然有题解说可以用prim做&#xff0c;但是这道题明显是加最小的边&#xff0c;感觉kruskal方便多了 但是愉快的是我竟然不是一次过&#xff0c;最后…

南开大学提出最新边缘检测与图像分割算法,精度刷新记录(附开源地址)

作者 | 刘云、程明明、胡晓伟、边佳旺等 译者 | 刘畅 整理 | Jane 出品 | AI科技大本营 近日&#xff0c;南开大学媒体计算实验室提出的最新边缘检测和图像过分割&#xff08;可用于生成超像素&#xff09;被 IEEE PAMI 录用。研究的第一作者也发微博称&#xff1a;“这是第…

修改Vista系统目录权限

例如C:\Windows\System32\DriverStore\FileRepository1. 修改目录所有者右键菜单->Properties->Security->Advanced->Owner->Edit->Other users or groups...输入用户名并确定&#xff0c;勾选Replace owner on subcontainers and objects&#xff0c;一路确…

gitlab安装各种坑

架构&#xff1a;源码安装, 数据库用mysql,网站用nginx 坑一.nginx报错 122016/07/19 09:26:11 [crit] 3881#0: *10 connect() to unix:/home/git/gitlab/tmp/sockets/gitlab-workhorse.socket failed (13: Permission denied) while connecting to upstream, client: 192.168.…

当代的设计潮流是什么_解码“潮流合伙人”IP生意经

每经记者&#xff1a;杜蔚 每经编辑&#xff1a;董兴生11月18日&#xff0c;备受期待的《潮流合伙人2》在成都举办了FOURTRY FAMILY PARTY新品发布日活动&#xff0c;节目的品牌主理人陈伟霆&#xff0c;合伙人欧阳娜娜、范丞丞等纷纷亮相现场&#xff0c;吸引众多人前来围观。…

Loonframwork到SWT的移植测试(JAVA GAME TEST SOURCE)

愚以为&#xff0c;用SWT作界面&#xff0c;是一种在用Java写VB的体验。本周心情极度恶劣&#xff0c;一直不想说话&#xff0c;也不想写新代码&#xff0c;郁闷中尝试了一下将Loonframework的代码移植到SWT。&#xff08;其实我觉得AWT,SWT,Swing用那个真的要根据需求决定&…