分享

简单Java代码实例助你通俗易懂的理解什么是装饰(者)设计模式 (Decorator)

 格瑞思n5c5alhf 2018-08-30
版权声明:觉得此文有用的,不嫌麻烦的,就留个言呐,或者点个赞呐(额,就是文章底部的“顶”啦),要是嫌弃麻烦呢,也麻烦点个赞嘛,要是实在不想点赞呢,也不是不可以。 但是,你要是想踩一脚呢,那还是赶紧,马上,快快的闪人。 小心我手里三十米长的大刀。 哼哼。想想都怕 !!! https://blog.csdn.net/qq_27093465/article/details/53320859

首先抛开到处都有的文字概念。来看下面的例子。
现在以:人吃饭。这个需求为例。来讲解这个设计模式。
1.0:想当年,人们都比较朴实。吃饭就是简简单单的吃饭。
那么PersonBefore类里面一个简单的方法chifan();


2.0:现如今,人们生活水平高了。吃饭的花样也多了,简单的吃饭已经不能满足需求。
那么怎么修改原来的代码才合适呢。总不能分分钟推到重构吧。


先看下面代码实现:

PersonBefore类,最原始的需求实现。

  1. package com.lxk.designPattern.decorator;
  2. /**
  3. * 被装饰的类
  4. * (被增强对象)
  5. * <p>
  6. * Created by lxk on 2016/11/24
  7. */
  8. public class PersonBefore {
  9. public void eat() {
  10. System.out.println("吃饭");
  11. }
  12. }


PersonNow类,需求增强之后的实现类。

  1. package com.lxk.designPattern.decorator;
  2. /**
  3. * 装饰类
  4. * (要去增强目标对象的类)
  5. * 装饰类通常会通过构造方法接收被装饰的对象。
  6. * 并基于被装饰的对象的功能,提供更强的功能。
  7. * <p>
  8. * Created by lxk on 2016/11/24
  9. */
  10. public class PersonNow {
  11. private PersonBefore p;
  12. PersonNow(PersonBefore p) {
  13. this.p = p;
  14. }
  15. public void superChifan() {
  16. //简单扩展
  17. System.out.println("开胃酒");
  18. p.eat();
  19. System.out.println("甜点");
  20. System.out.println("来一根烟");
  21. }
  22. }

PersonDemo类,需求实际被调用的类。
  1. package com.lxk.designPattern.decorator;
  2. /**
  3. * 装饰设计模式:
  4. * 当想要对已有的对象进行功能增强时,
  5. * 可以定义类,将已有对象传入,基于已有的功能,并提供加强功能。
  6. * 那么自定义的该类称为装饰类。
  7. * <p>
  8. * 装饰类通常会通过构造方法接收被装饰的对象。
  9. * 并基于被装饰的对象的功能,提供更强的功能。
  10. */
  11. class PersonDemo {
  12. public static void main(String[] args) {
  13. PersonBefore p = new PersonBefore();
  14. //p.eat();//这个是需求1.0
  15. PersonNow sp = new PersonNow(p);
  16. sp.superChifan();
  17. }
  18. }

此代码只为简单易懂的理解这个装饰者设计模式。你可能会考虑到使用继承也可以实现类似效果,继承和装饰模式之间有什么差别呢?那是后话了。再说吧。
我还想问这个装饰者设计模式和代理模式的区别呢?和AOP的差别在哪?


下面是摘自某度文库的--装饰模式的概念的详细文字描述。真不是分分钟能明白说的都是啥。


装饰模式:
在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。

装饰模式的特点
(1) 装饰对象和真实对象有相同的接口。这样客户端对象就能以和真实对象相同的方式和装饰对象交互。
(2) 装饰对象包含一个真实对象的引用(reference)
(3) 装饰对象接受所有来自客户端的请求。它把这些请求转发给真实的对象。
(4) 装饰对象可以在转发这些请求以前或以后增加一些附加功能。这样就确保了在运行时,不用修改给定对象的结构就可以在外部增加附加的功能。在面向对象的设计中,通常是通过继承来实现对给定类的功能扩展。

适用性
以下情况使用Decorator模式
1. 需要扩展一个类的功能,或给一个类添加附加职责。
2. 需要动态的给一个对象添加功能,这些功能可以再动态的撤销。
3. 需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变的不现实。
4. 当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。

优点
1. Decorator模式与继承关系的目的都是要扩展对象的功能,但是Decorator可以提供比继承更多的灵活性。
2. 通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合。

缺点
1. 这种比继承更加灵活机动的特性,也同时意味着更加多的复杂性。
2. 装饰模式会导致设计中出现许多小类,如果过度使用,会使程序变得很复杂。
3. 装饰模式是针对抽象组件(Component)类型编程。但是,如果你要针对具体组件编程时,就应该重新思考你的应用架构,以及装饰者是否合适。当然也可以改变Component接口,增加新的公开的行为,实现“半透明”的装饰者模式。在实际项目中要做出最佳选择。


实际使用
java IO 流是典型的装饰模式。

这倒是真的,看前2篇 BufferedReader BufferedWriter 都是把字符读写流资源作为参数,传进类内部,对其进行功能增强。使得读写的效率得到提高。果然是实际使用此模式的好例子。






请选中你要保存的内容,粘贴到此文本框

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多