经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » 设计模式 » 查看文章
【23种设计模式】装饰模式(九)
来源:cnblogs  作者:码农阿亮  时间:2023/9/14 9:56:10  对本文有异议

前言

装饰模式,英文名称:Decorator Pattern。我第一次看到这个名称想到的是另外一个词语“装修”,我就说说我对“装修”的理解吧,大家一定要看清楚,是“装修”,不是“装饰”。在房子装修的过程中,各种功能可以相互组合,来增加房子的功用。类似的,如果我们在软件系统中,要给某个类型或者对象增加功能,如果使用“继承”的方案来写代码,就会出现子类暴涨的情况。比如:IMarbleStyle是大理石风格的一个功能,IKeepWarm是保温的一个接口定义,IHouseSecurity是房子安全的一个接口,就三个接口来说,House是我们房子,我们的房子要什么功能就实现什么接口,如果房子要的是复合功能,接口不同的组合就有不同的结果,这样就导致我们子类膨胀严重,如果需要在增加功能,子类会成指数增长。

装饰模式的定义

上述的问题的根源在于我们“过度地使用了继承来扩展对象的功能”,由于继承为类型引入的静态特质,所谓静态特质,就是说如果想要某种功能,我们必须在编译的时候就要定义这个类,这也是强类型语言的特点。静态,就是指在编译的时候要确定的东西;动态,是指运行时确定的东西。使得这种扩展方式缺乏灵活性;并且随着子类的增多(扩展功能的增多),各种子类的组合(扩展功能的组合)会导致更多子类的膨胀(多继承)。如何使“对象功能的扩展”能够根据需要来动态(即运行时)地实现?同时避免“扩展功能的增多”带来的子类膨胀问题?从而使得任何“功能扩展变化”所导致的影响降为最低?装饰者模式解决此问题应运而生,动态地给一个对象增加一些额外的职责。

装饰模式的组成

  • 抽象构件角色(Component):给出一个抽象接口,以规范准备接收附加责任的对象。

  • 具体构件角色(Concrete Component):定义一个将要接收附加责任的类。

  • 装饰角色(Decorator):持有一个构件(Component)对象的实例,并实现一个与抽象构件接口一致的接口。

  • 具体装饰角色(Concrete Decorator):负责给构件对象添加上附加的责任。
    image

装饰模式的实现

以装修房子为例,完成装饰着模式的代码实现

房子定义
  1. /// <summary>
  2. /// 该抽象类就是房子抽象接口的定义,该类型就相当于是Component类型,是饺子馅,需要装饰的,需要包装的
  3. /// </summary>
  4. public abstract class House
  5. {
  6. /// <summary>
  7. /// 房子的装修方法--该操作相当于Component类型的Operation方法
  8. /// </summary>
  9. public abstract void Renovation();
  10. }
  11. /// <summary>
  12. /// MyHouse的房子,我要按我的要求做房子,相当于ConcreteComponent类型
  13. /// </summary>
  14. public sealed class MyHouse : House
  15. {
  16. public override void Renovation()
  17. {
  18. Console.WriteLine("装修我的房子");
  19. }
  20. }
装饰类的定义
  1. /// <summary>
  2. /// 该抽象类就是装饰接口的定义,该类型就相当于是Decorator类型,如果需要具体的功能,可以子类化该类型
  3. /// </summary>
  4. public abstract class DecorationStrategy : House //关键点之二,体现关系为Is-a,有了这个关系,装饰的类也可以继续装饰了
  5. {
  6. //通过组合方式引用Decorator类型,该类型实施具体功能的增加
  7. //这是关键点之一,包含关系,体现为Has-a
  8. protected House _house;
  9. //通过构造器注入,初始化平台实现
  10. protected DecorationStrategy(House house)
  11. {
  12. this._house = house;
  13. }
  14. //该方法就相当于Decorator类型的Operation方法
  15. public override void Renovation()
  16. {
  17. if (this._house != null)
  18. {
  19. this._house.Renovation();
  20. }
  21. }
  22. }
安全需求类装饰定义
  1. /// <summary>
  2. /// 具有安全功能的设备,可以提供监视和报警功能,相当于ConcreteDecoratorA类型
  3. /// </summary>
  4. public sealed class HouseSecurityDecorator : DecorationStrategy
  5. {
  6. public HouseSecurityDecorator(House house) : base(house) { }
  7. public override void Renovation()
  8. {
  9. base.Renovation();
  10. Console.WriteLine("增加安全系统");
  11. }
  12. }
保暖需求类装饰定义
  1. /// <summary>
  2. /// 具有保温接口的材料,提供保温功能,相当于ConcreteDecoratorB类型
  3. /// </summary>
  4. public sealed class KeepWarmDecorator : DecorationStrategy
  5. {
  6. public KeepWarmDecorator(House house) : base(house) { }
  7. public override void Renovation()
  8. {
  9. base.Renovation();
  10. Console.WriteLine("增加保温的功能");
  11. }
  12. }
调用
  1. public void RunTest()
  2. {
  3. //这就是我们需要装饰的房子
  4. House myselfHouse = new MyHouse();
  5. DecorationStrategy securityHouse = new HouseSecurityDecorator(myselfHouse);
  6. securityHouse.Renovation();
  7. /*
  8. * 此时房子就有了安全系统了.....
  9. */
  10. //【1】如果我既要安全系统又要保暖呢,继续装饰就行
  11. //DecorationStrategy securityAndWarmHouse = new KeepWarmDecorator(myselfHouse);
  12. //securityAndWarmHouse.Renovation();
  13. Console.WriteLine("\r\n*****************************\r\n");
  14. //【2】如果我既要安全系统又要保暖呢,继续装饰就行【和上边的进行运行比对】
  15. //【对运行结果难理解的话,打断点单步执行进行理解】
  16. DecorationStrategy securityAndWarmHouse1 = new KeepWarmDecorator(securityHouse);
  17. securityAndWarmHouse1.Renovation();
  18. }

image

装饰模式的优缺点

优点
  • 把抽象接口与其实现解耦。

  • 抽象和实现可以独立扩展,不会影响到对方。

  • 实现细节对客户透明,对用户隐藏了具体实现细节。

缺点
  • 增加了系统的复杂度

原文链接:https://www.cnblogs.com/wml-it/p/17693849.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号