`

装饰者模式(Decorator Pattern) 追MM

阅读更多

装饰者模式

MM们要过生日了 ,怎么也得表示下吧。最起码先送个蛋糕。蛋糕多种多样了。巧克力,冰淇淋,奶油等等。这都是基本的了 ,再加点额外的装饰,如蛋糕里放点花。放贺卡。放点干果吃着更香等等。看看我是如何设计的。

      我想既然是蛋糕,那我就把蛋糕作为一个抽象类,剩下的蛋糕子类型来继承它,每个子类都有吃该蛋糕的感觉 ^_^,看起来真的不错。蛋糕的子类分别是奶酪蛋糕,巧克力蛋糕,冰淇淋蛋糕,插花的冰淇淋蛋糕,放贺卡的冰淇淋蛋糕。某个MM的生日蛋糕喜欢带花的冰淇淋蛋糕。还好我早有准备。但是有几次失策了。。她们要的蛋糕我这都没有。比如带鲜花的巧克力蛋糕。带果仁的牛奶蛋糕。带鲜花带果仁的蛋糕。。。。那我还要继续添加蛋糕的子类。。问题出现了。这样会造成大量的蛋糕子类 。真是噩梦啊。

 

那么我要好好思考这个问题了。发现了刚才的设计确实有问题。。发现了真正的要关注的主体是蛋糕。。而贺卡,花,果仁等等只不过是装饰 的作用。

 

思路来了。蛋糕作为主体,其他的东西都加到蛋糕上。MM要啥我就加啥呗。呵呵。

到现在我们要明确的是:

  • 蛋糕是主体。
  • 花,贺卡,果仁等等是装饰者。
  • 可以用装饰者包装蛋糕。

来看看什么是装饰器模式吧:

动态的将责任附加到对象上,若要扩展功能,装饰者提供了比继承更有弹性的替代方案。

 


  • Component:抽象出的主体对象。
  • ConcreteComponent:是要动态扩展的对象,它继承自Component.
  • Decorator:是装饰器的接口。(这里的接口并不是指java的interface)。
  • ConcreteDecoratorA:实现Decorator的类,包含了一个Component引用,这样就可以扩展Component的方法了。

说完理论了。可能还一头雾水吧。。。还是接着蛋糕的例子继续说。先看图吧。



基本符合了上面所提到的装饰者模式的框架结构了。再看看代码:

Cake

Java代码 复制代码
  1. package decorator.demo;   
  2.   
  3. /**  
  4.  * 蛋糕基类  
  5.  * @author Nicholas  
  6.  *  
  7.  */  
  8. public abstract class Cake {   
  9.     String remark = "蛋糕";   
  10.     public String getRemark() {   
  11.         return remark;   
  12.     }   
  13.     public abstract String getImpression();//用来描述吃蛋糕的感觉。。。。   
  14. }  
package decorator.demo;

/**
 * 蛋糕基类
 * @author Nicholas
 *
 */
public abstract class Cake {
	String remark = "蛋糕";
	public String getRemark() {
		return remark;
	}
	public abstract String getImpression();//用来描述吃蛋糕的感觉。。。。
}

 Cake是个抽象类,它已经实现了getRemark的方法。但没有实现getImpression.这个方法必须被子类实现。

 

再看看装饰器的抽象类

OtherDecorator

Java代码 复制代码
  1. package decorator.demo;   
  2.   
  3. /**  
  4.  * 其他用来添加蛋糕的东西  
  5.  * @author Nicholas  
  6.  *  
  7.  */  
  8. public abstract class OtherDecorator extends Cake{   
  9.     Cake cake;   
  10.     /**  
  11.      * 引用一个Cake.  
  12.      * 让被装饰者进入装饰者之中。这里用的是构造方法注入。  
  13.      * 这样就可以调用Cake实例的方法了。  
  14.      * @param cake  
  15.      */  
  16.     public OtherDecorator(Cake cake){   
  17.         this.cake=cake;   
  18.     }   
  19.     /**  
  20.      * 让装饰器的子类都去实现getRemark方法。业务需要每个装饰器都要有描述。  
  21.      */  
  22.     public abstract String getRemark();   
  23. }  
package decorator.demo;

/**
 * 其他用来添加蛋糕的东西
 * @author Nicholas
 *
 */
public abstract class OtherDecorator extends Cake{
	Cake cake;
	/**
	 * 引用一个Cake.
	 * 让被装饰者进入装饰者之中。这里用的是构造方法注入。
	 * 这样就可以调用Cake实例的方法了。
	 * @param cake
	 */
	public OtherDecorator(Cake cake){
		this.cake=cake;
	}
	/**
	 * 让装饰器的子类都去实现getRemark方法。业务需要每个装饰器都要有描述。
	 */
	public abstract String getRemark();
}

 

下面让我们实现一个蛋糕吧。^_^。。

Java代码 复制代码
  1. package decorator.demo;   
  2. /**  
  3.  * 乳酪蛋糕  
  4.  * @author Nicholas  
  5.  *  
  6.  */  
  7. public class CheeseCake extends Cake{   
  8.     /**  
  9.      * 乳酪蛋糕的构造方法  
  10.      */  
  11.     public CheeseCake(){   
  12.         super.remark="乳酪蛋糕";//修改乳酪蛋糕的描述。   
  13.     }   
  14.   
  15.     /**  
  16.      * 实现了Cake抽象类的getImpression  
  17.      * 吃乳酪蛋糕的感觉。。  
  18.      */  
  19.     public String getImpression() {   
  20.         return "香甜感受";   
  21.     }   
  22.   
  23. }  
package decorator.demo;
/**
 * 乳酪蛋糕
 * @author Nicholas
 *
 */
public class CheeseCake extends Cake{
	/**
	 * 乳酪蛋糕的构造方法
	 */
	public CheeseCake(){
		super.remark="乳酪蛋糕";//修改乳酪蛋糕的描述。
	}

	/**
	 * 实现了Cake抽象类的getImpression
	 * 吃乳酪蛋糕的感觉。。
	 */
	public String getImpression() {
		return "香甜感受";
	}

}

 

其他实现Cake的类就不列出了,道理是一样的。

下面我们要开始实现具体的装饰器了。

Java代码 复制代码
  1. package decorator.demo;   
  2.   
  3. /**  
  4.  * 给蛋糕添加的花  
  5.  * @author Nicholas  
  6.  *  
  7.  */  
  8. public class FlowerDecorator extends OtherDecorator{   
  9.        
  10.     /**  
  11.      * 构造函数  
  12.      * 传入一个cake实例,也就是前面所实现的Cake的子类,如奶酪蛋糕,巧克力蛋糕等等。  
  13.      * @param cake  
  14.      */  
  15.     public FlowerDecorator(Cake cake){   
  16.         super(cake);//调用父类的构造方法,可以获取Cake的实例了。就可以调用Cake实例的方法.   
  17.         super.remark="一朵玫瑰花";   
  18.     }   
  19.        
  20.     /**  
  21.      * 实现了装饰器抽象类的getImpression方法。  
  22.      */  
  23.     public String getImpression() {   
  24.         //这是重点。我们通过构造方法传入的cake实例。对cake进行了装饰,增加了新的功能。   
  25.         return cake.getImpression()+","+"看到一朵花真是happy";   
  26.     }   
  27.   
  28.     public String getRemark() {   
  29.         return cake.getRemark()+"+"+super.remark;   
  30.     }   
  31. }  
package decorator.demo;

/**
 * 给蛋糕添加的花
 * @author Nicholas
 *
 */
public class FlowerDecorator extends OtherDecorator{
	
	/**
	 * 构造函数
	 * 传入一个cake实例,也就是前面所实现的Cake的子类,如奶酪蛋糕,巧克力蛋糕等等。
	 * @param cake
	 */
	public FlowerDecorator(Cake cake){
		super(cake);//调用父类的构造方法,可以获取Cake的实例了。就可以调用Cake实例的方法.
		super.remark="一朵玫瑰花";
	}
	
	/**
	 * 实现了装饰器抽象类的getImpression方法。
	 */
	public String getImpression() {
		//这是重点。我们通过构造方法传入的cake实例。对cake进行了装饰,增加了新的功能。
		return cake.getImpression()+","+"看到一朵花真是happy";
	}

	public String getRemark() {
		return cake.getRemark()+"+"+super.remark;
	}
}

 到现在终于大功告成了。。这样方便了很多,可以通过装饰器生成很多种类的蛋糕。

Java代码 复制代码
  1. package decorator.demo;   
  2.   
  3. public class MyGirlB {   
  4.     public static void main(String[] args){   
  5.         //用果仁,花包装巧克力蛋糕。   
  6.         Cake nutsFlowerChocolateCake = new NutsDecorator(new FlowerDecorator(new ChocolateCake()));   
  7.         System.out.println("remark "+nutsFlowerChocolateCake.getRemark());   
  8.         //吃蛋糕的感受已经发生了改变。   
  9.         System.out.println("impression "+nutsFlowerChocolateCake.getImpression());   
  10.     }   
  11. }  
package decorator.demo;

public class MyGirlB {
	public static void main(String[] args){
		//用果仁,花包装巧克力蛋糕。
		Cake nutsFlowerChocolateCake = new NutsDecorator(new FlowerDecorator(new ChocolateCake()));
		System.out.println("remark "+nutsFlowerChocolateCake.getRemark());
		//吃蛋糕的感受已经发生了改变。
		System.out.println("impression "+nutsFlowerChocolateCake.getImpression());
	}
}

 

这个模式的缺点也挺明显的 ,看看如下图片


 

 

为了扩展cake的功能,加入了许多的装饰类。。当然用户也可以继承OtherDecorator来继续扩展。但是对API使用者是个困扰。。所以API要说明哪些类是用来包装的。。

 

分享到:
评论
发表评论

文章已被作者锁定,不允许评论。

相关推荐

    java23种设计模式与追MM下载地址

    ### 装饰器模式(Decorator Pattern) 装饰器模式允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。在Java中,装饰器模式经常用于处理流...

    23种设计模式趣解.txt

    #### 装饰器模式(Decorator Pattern) 装饰器模式允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。在文中提供的例子中,Mike需要为Mary...

    23种设计模式超级经典解释!!

    9. **装饰器模式**(Decorator Pattern) 装饰器模式在不改变原有对象的基础上,动态地给对象添加新的功能。例如,给照片添加祝福语,以创建独特的生日礼物。装饰器模式避免了大量子类的生成,保持了类的封装性。 ...

    谈Java的23种设计模式

    除了以上这些模式,还有许多其他的设计模式,如装饰器模式(Decorator)、观察者模式(Observer)、代理模式(Proxy)、桥接模式(Bridge)、责任链模式(Chain of Responsibility)、命令模式(Command)、解释器...

    毕业设计-门店微商城1.2.0小程序+前端-整站商业源码.zip

    毕业设计-门店微商城1.2.0小程序+前端-整站商业源码.zip

    无刷双馈电机(BDFM)与BDFIG模型的构建及仿真验证:电动机与发电机模型研究

    内容概要:本文详细介绍了无刷双馈电机(BDFM)及其变频调速系统(BDFIG)模型的研究进展。首先概述了BDFM的基本原理,强调其双馈特性和无刷驱动方式的优势。接着介绍了BDFIG模型的具体构建,包括电动机和发电机模型的建立。文中特别提到发电机模型采用两种不同方法搭建,分别是基于传统电机理论的参数计算法和基于实测数据的方法。随后,通过对不同工况下的仿真实验,验证了BDFIG模型的有效性和准确性。最后展示了复现的一篇论文中的电机控制算法模型,涵盖功率、速度和转矩控制等方面的内容。 适合人群:从事电机设计、制造以及相关领域的科研人员和技术工程师。 使用场景及目标:适用于需要深入了解无刷双馈电机工作原理及其建模方法的研究者;帮助工程师优化现有电机系统的性能并探索新的应用场景。 其他说明:文章还探讨了未来研究方向,指出随着科技进步,无刷双馈电机及其控制系统将拥有更广泛的发展前景。

    毕业设计-古力乐简易网址导航综合搜索引擎站-整站商业源码.zip

    毕业设计-古力乐简易网址导航综合搜索引擎站-整站商业源码.zip

    154BC-压阻式硅压力传感器-中文数据手册.pdf

    154BC-压阻式硅压力传感器-中文数据手册

    网络规划设计师历年案例总结.xlsx

    软考初级程序员相关文档

    毕业设计-花粥云商城V1.03-整站商业源码.zip

    毕业设计-花粥云商城V1.03-整站商业源码.zip

    广义多粒度粗糙集特征选择算法研究.pdf

    广义多粒度粗糙集特征选择算法研究.pdf

    易优CMS响应式电子商务公司网站模板-EyouCMS商业服务类企业网站模板

    易优CMS响应式电子商务公司网站模板,EyouCMS商业服务类企业网站模板。适用于财务、管理、法律、政府类企业网站开发使用。 模板自带eyoucms内核,无需再下载eyou系统,原创设计、手工书写DIV+CSS,完美兼容IE7+、Firefox、Chrome、360浏览器等;主流浏览器;结构容易优化;多终端均可正常预览。

    毕业设计-叮咚-超级外卖餐饮V6.2.4+跑腿V2.0.1 小程序前端+后端-整站商业源码.zip

    毕业设计-叮咚-超级外卖餐饮V6.2.4+跑腿V2.0.1 小程序前端+后端-整站商业源码.zip

    毕业设计-美容美发营销版小程序 2.0.0-整站商业源码.zip

    毕业设计-美容美发营销版小程序 2.0.0-整站商业源码.zip

    Python实现的CNN卷积神经网络手写数字识别项目代码及详尽注释和数据集(适用于毕业设计与期末大作业)

    基于Python实现的CNN卷积神经网络手写数字识别项目,包含源码、详细注释和数据集。该项目是经导师指导并认可通过的高分毕业设计项目,评审分为98分。适合计算机相关专业的毕设学生及需要项目实战练习的学习者使用,也可作为课程设计或期末大作业。。内容来源于网络分享,如有侵权请联系我删除。

    基于Attention-Bi-LSTM的微博评论情感 分析研究.pdf

    基于Attention-Bi-LSTM的微博评论情感 分析研究.pdf

    iOS自动布局实战教程

    本书《Auto Layout by Tutorials》是一本专注于在iOS平台上构建动态用户界面的教程书籍。作者Jayven Nhan和Libranner Santos通过详细的步骤和实例,介绍了Auto Layout的基础知识、使用界面构建器和代码实现自动布局的方法,以及如何处理滚动视图、自适应布局、动态类型等中级和高级主题。书中还探讨了堆叠视图、内容拥抱与压缩阻力优先级、动画化约束、国际化和本地化等概念,并提供了优化Auto Layout性能和为外部显示器设计的高级技巧。最后,作者还介绍了如何使用Playgrounds进行布局原型设计,以及设计自定义控件的方法。

    机器学习(预测模型):人推文数据集(真实推文与人工智能生成推文)

    一个用于研究和分析名人推文的数据集,它包含真实推文和人工智能生成的推文,旨在帮助研究人员和开发者探索自然语言处理技术在文本生成和真实性检测方面的应用。数据集背景:推特作为全球知名的社交媒体平台,每天都有海量的推文发布。其中,名人的推文因其影响力和关注度而备受关注。然而,随着人工智能技术的发展,尤其是自然语言生成(NLG)技术的进步,越来越多的虚假内容开始在社交媒体上传播。为了应对这一挑战,研究人员需要一个包含真实推文和AI生成推文的数据集,以开发和测试能够有效检测虚假内容的算法。 数据集内容:该数据集由两部分组成:真实推文和AI生成的推文。真实推文是从推特上收集的,由名人亲自发布的消息,涵盖了各种主题和风格。AI生成的推文则是利用先进的自然语言生成模型,根据名人的写作风格和语言习惯生成的模拟推文。这些推文在内容和形式上尽量贴近真实推文,但并非名人本人所写。 数据集的结构通常包括推文的文本内容、发布时间、发布者(名人姓名)、推文类型(真实或AI生成)等信息。此外,部分数据集可能还会包含一些额外的元数据,如推文的情感倾向、语言风格特征等,以帮助研究人员更全面地分析和理解数据。 数据集用途:这个数据集的主要用途是帮助研究人员和开发者:研究AI生成文本的质量:通过对比真实推文和AI生成的推文,评估当前AI生成技术在模仿人类写作风格方面的表现。开发真实性检测算法:利用真实推文和AI生成推文的对比,训练机器学习模型,以识别虚假内容,提高社交媒体平台的信息安全性和可信度。探索自然语言处理技术的应用:研究如何利用自然语言处理技术分析名人推文的语言风格、情感倾向等,为社交媒体分析、舆情监测等领域提供支持。数据集的价值:为自然语言处理领域的研究提供了宝贵的资源。它不仅有助于提高AI生成文本的质量和可信度,还能帮助开发更有效的虚假信息检测工具,保护社交媒体用户免受虚假信息的误导。

    三相VIENNA整流器仿真研究:基于MATLAB的双闭环PI控制与SPWM调制技术 MATLABSimulink 三相VIENNA整流器仿真与T型vienna整流器仿真:中点电位平衡控制与SPWM调制

    内容概要:本文详细介绍了三相VIENNA整流器的仿真研究,重点探讨了T型整流器的双闭环PI控制及中点电位平衡控制策略,以及SPWM调制技术的应用。文中展示了具体的MATLAB/Simulink建模方法,包括电流环控制、中点平衡补偿和锁相环配置,并通过实验数据验证了系统的高性能表现,如THD仅为1.01%,功率因数达到99%以上,直流侧电压稳定在750V。此外,作者分享了一些参数调试的小技巧,如初始Kp和Ki的选择,以及锁相环滤波截止频率的调整。 适合人群:从事电力电子、电机驱动等领域研究的技术人员,特别是对三相VIENNA整流器及其控制策略感兴趣的工程师。 使用场景及目标:适用于需要高功率因数、低谐波失真的工业电源系统的设计与优化。目标是提高系统的效率和稳定性,减少谐波污染。 其他说明:文中提供的MATLAB代码片段有助于读者理解和实现相关控制算法,同时强调了实际应用中的权衡与优化问题。

    七自由度车辆动力学Matlab Simulink仿真模型及Dugoff轮胎模型解析与应用 多刚体动力学 七自由度车辆动力学Simulink模型详解及Dugoff轮胎模型探讨——附带三自由度车辆动力学模

    内容概要:本文详细介绍了七自由度车辆动力学的Matlab Simulink仿真模型及其关键组成部分,如动力学模型、轮胎模型(特别是Dugoff轮胎模型)和路面模型。文章不仅涵盖了模型的构建步骤和技术要点,还提供了实例代码解析和实际应用技巧。此外,文中还附赠了二/三自由度车辆动力学仿真模型,帮助读者更好地理解和应用这一复杂的仿真技术。主要内容分为五个部分:主题背景与引出、模型说明、实例代码解析、实际应用技巧与经验分享、总结与展望。 适合人群:从事车辆动力学研究、汽车研发及相关领域的工程师和技术人员,尤其是那些希望深入了解并应用Simulink进行车辆动力学仿真的专业人士。 使用场景及目标:适用于汽车研发、交通运输等领域,旨在帮助工程师们进行动力性能仿真、动态响应分析等工作,提升仿真模型的精度和效率。 其他说明:文章强调了选择合适仿真软件、注重模型精度和效率、持续学习和实践的重要性,为未来的技术发展指明方向。

Global site tag (gtag.js) - Google Analytics