ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

设计模式之装饰者模式

2021-07-03 15:02:51  阅读:121  来源: 互联网

标签:函数 佐料 模式 饮料 调料 设计模式 装饰 策略


一、含义

动态地给一个对象添加一些额外的职责。就增加功能来说, Decorator模式相比生成子类更为灵活。装饰模式以对客户透明的方式动态地给一个对象附加上更多的责任。

分析含义:以前如果要扩展功能,一般都是使用继承基类,然后根据不同的特征进行拓展,这样做会使得代码不够灵活,因为继承是在运行之前就写好了的,当我们想要改变或者增加一些东西时,会直接改变类,这就破坏了开放与关闭原则,装饰者原则使用组合的思想,相对比继承只能纵向扩展,装饰者使得可以横向组合,装饰者和本身的组件从源头上都是继承同一个接口,这样就可以利用多态,使得类型达到相同,从而使得相互组合变得容易。

二、举例

应用场景:为咖啡店设计订单系统,使得满足不同饮料的需求。

  • 策略一:使用一个饮料抽象类,里面是一些公有的必须要子类实现的行为(比如:描述饮料函数、计算价格函数),其子类就是所有拥有的饮料。
  • 策略二:在饮料抽象类中,加入一些变量用于判断是否加入了这些佐料(bool值),同时还应加入设置是否加入某种调料的函数(set)、获取是否添加了某种调料的函数(get),计算总价的方法(这里不应该是抽象方法了,应该根据get函数的bool值得到不同的调料总价,然后对于一款具体的饮品类应该在覆盖基类cost函数时,返回基本的价格同时加上所有调料的总价)。
  • 策略三:与策略二有相似的地方,但是角度不同。策略二是让所有调料在基类中,每一个具体饮品返回自身基础价格和基类中调料总值。策略三是通过接口使得调料和主料达到类型相同(源头接口),使得调料可以包含住主料的同时,最后能够返回一个饮料类型,对于价格的计算,应该是从最外层的装饰者开始,每一层的计算价格的函数都调用内层的cost函数加上本层装饰的价格直到最后在基础组件时返回一个基础价格(与递归函数相似)。

策略评价:

  • 对于策略一:每新增一种饮料就需要对应写一种具体类,这就会造成类爆炸。如下图所示:

        

 

  • 对于策略二而言:虽然可以判断是否加了佐料,但是当加入的佐料是两份相同的佐料,用这种模式怎么实现呢?如果我要新增一个佐料,还需要在基本抽象类中新增对新的佐料的设置和获取。并且由于每一种饮品并不是都要有某种佐料,如果单纯直接继承,那么会继承一些可能不合适的特点,这种设计不是很合理。
  •  对于策略三,相对要好一点,我们要保证主要组件和装饰的源头保持一致,我们通过抽象类来实现主材料和装饰材料的用户匹配。主材料和装饰材料的不同主要是装饰材料内部有一个基本类,用来装主材料。

 *******************************************************************************************

代码实现:

 

 

 

 

 

 

 

 ****************************************************************************************************************

测试类:

 

 不论装饰者里面包裹的是装饰者还是基本材料,始终最里面包裹的是一个基本材料类,基本材料类相当于递归的出口,最后返回一个数值。

 ****************************************************************************

拓展:对于策略二中,cost函数应该如何写?

 

 

书中这个代码不完善我目前的思路是可以考虑设置一个枚举,装TALL、GRANDE、VENTI,然后在基本的set函数中需要对size字段传入相应的0、1、2进行传值,再进行对比。

标签:函数,佐料,模式,饮料,调料,设计模式,装饰,策略
来源: https://www.cnblogs.com/Nicela/p/14966345.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有