这两天本来是自在学习java collection Framework的Fail Fast底层机制,看到核心的部分时,突然意识到设计模式的问题,上大学到现在我还没有真正理解过设计模式的概念,于是用了大半天好好的学习了一下装饰器模式,回头再看jdk的源码,舒服多了,的确验证了那句话,设计模式非学不可啊,可以说自己是个十足的菜鸟,连基本的java接口机制和继承都忘得差不多了,这一天全拾起来了~

首先解释一下忘记接口的同学难点,接口其实就是java的抽象机制,不提供方法的具体实现,但是可以有多个类来实现这个接口,一个类也可以实现多个接口,接口带来的好处是创建实例时,用户不必关注具体的实现,比如我例子中的DecoratorPattern.java文件中 ,创建实现Basket接口的一个实例时,返回值是接口,下面再使用show方法时,我们就不必去关注谁实现了。接口作为返回值的一个经典的应用是使用ArrayList时,他的iterator方法会返回一个Iterator接口。这样开发者使用it.next方法,再不用去研究每一种list是怎么实现查询了。

下面解释装饰器模式是如何引起的,深入浅出模式设计的例子很好,就是喝咖啡,有个调料的类,你可以加糖、冰、牛奶等等好多原料,那么生成调配方案时,可以通过继承来实现,但是大家也都知道排列组合,继承的类系统庞大可想而知了。

这就诞生了装饰器模式,他的原则是,保持原有的接口,并为原来的动态的添加新的功能。

下面是维基百科的解释:相信大家都可以看懂

“通过使用修饰模式,可以在运行时扩充一个类的功能。原理是:增加一个修饰类包裹原来的类,包裹的方式一般是通过在将原来的对象作为修饰类的构造函数的参数。装饰类实现新的功能,但是,在不需要用到新功能的地方,它可以直接调用原来的类中的方法。修饰类必须和原来的类有相同的接口。

修饰模式是类继承的另外一种选择。类继承在编译时候增加行为,而装饰模式是在运行时增加行为。

当有几个相互独立的功能需要扩充时,这个区别就变得很重要。在有些面向对象的编程语言中,类不能在运行时被创建,通常在设计的时候也不能预测到有哪几种功能组合。这就意味着要为每一种组合创建一个新类。相反,修饰模式是面向运行时候的对象实例的,这样就可以在运行时根据需要进行组合。一个修饰模式的示例是JAVA里的Java I/O Streams的实现”

//补充一下,还有个经典的例子是java Collection framework也就是我们经常使用的ArrayList的底层实现机制,也是利用了装饰器模式。

再引用网上的一个设计图,很清晰了,我在代码中的实现,并没有实现装饰器基类,而是直接去装饰了。

下面介绍我这个演示的demo,假设我们有一个水果篮子,厘米可以装苹果,香蕉、或者橘子。这是可以典型的应用装饰器模式,比如我们用三个修饰器来修饰水果篮子里面装的内容。假设我们使用继承的话,那么要想获得所有情况,根据排列组合那么就有8种可能,需要有7个子类(空篮子就是本身,不需继承了)。装饰器模式就简单多了

第一个是Basket接口

1 package uni.pattern.decorator;  2 /* 3  * 创建一个对象的抽象也就是接口 4 */  5 public interface Basket {  6     public void show();  7       8 } 

下面是被装饰的对象,也就是对接口的一个实现,注意可以有多个实现

 1 package uni.pattern.decorator;   2    3 /**  4  *身份:被装饰的对象  5  *一个对接口的实现,这个对象表示要我们将来要修饰的篮子里装内容,如果想修饰篮子的造型,还可以创建其他类实现Basket的接口,比如Shape  6  * 不理解的话可以查看java语言的接口抽象机制  7 */   8 public class Original implements Basket{   9     public void show(){  10       System.out.println("The original Basket contains");  11     }  12 }  

接下来是三个装饰器的实现

 1 package uni.pattern.decorator;   2    3 /**  4  *身份:装饰器  5  *为原来的类添加新的功能  6 */   7 public class AppleDecorator implements Basket{   8     private Basket basket;   9     public AppleDecorator( Basket basket){  10       super();  11       this.basket = basket;  12     }  13       14     public void show(){  15       basket.show();  16       System.out.println("An Apple");  17     }  18       19 }  

 1 package uni.pattern.decorator;   2    3 /**  4  *身份:装饰器  5 */   6 public class BananaDecorator implements Basket{   7     private Basket basket;   8     public BananaDecorator(Basket basket){   9         super();  10         this.basket = basket;  11     }  12       13     public void show(){  14         basket.show();  15         System.out.println("A Banana");  16     }  17       18 }  

 1 package uni.pattern.decorator;   2    3 /**  4  *身份:装饰器  5 */   6 public class OrangeDecorator implements Basket{   7     private Basket basket;   8     public OrangeDecorator(Basket basket){   9         super();  10         this.basket = basket;  11     }  12       13     public void show(){  14         basket.show();  15         System.out.println("An Oranage");  16     }  17       18 }  

最后就是实现的效果,我们三个修饰器全部用到,装满了篮子,当然也可以只装一个苹果或香蕉

 1 /*  2  * 设计模式:装饰器模式  3  * java 简单的演示  4 */   5 package decoratorpattern;   6 import uni.pattern.decorator.Original;   7 import uni.pattern.decorator.*;   8    9 /** 10  * 11  * @author octobershiner 12  * 2011 7 25 13  * SE.HIT 14 */  15 public class DecoratorPattern {  16   17     /** 18      * @param args the command line arguments 19 */  20     public static void main(String[] args) {  21         // TODO code application logic here  22         Basket basket = new Original();  23         //一个装饰的过程  24         Basket myBasket =new AppleDecorator(new BananaDecorator(new OrangeDecorator(basket)));   25         myBasket.show();  26     }  27 }  

演示的结果:

run:
The original Basket contains
An Oranage
A Banana
an Apple
成功生成(总时间:0 秒)

实训期间时间比较紧张,写的不清晰,所以大家有疑问可以私下联系我吧,欢迎留言

作者:leeon

出处:http://www.cnblogs.com/octobershiner/
http://www.cnblogs.com/octobershiner/archive/2011/11/04/2236730.html

设计模式学习----装饰器模式相关推荐

  1. 零基础学习设计模式之装饰器模式(配套视频)

    零基础学习设计模式之装饰器模式 定义 在不改变目标结构的情况下,动态的给对象增加功能 举例 如房子装修.相片加相框等,都是装饰器模式. 基本组件 抽象构件(Component)角色:定义一个抽象接口以 ...

  2. 【设计模式】装饰器模式的使用

    问题来源 我们在进行软件系统设计的时候,有一些业务(如下图,一些通用的非功能性需求)是多个模块都需要的,是跨越模块的.把它们放到什么地方呢? 最简单的办法就是把这些通用模块的接口写好,让程序员在实现业 ...

  3. go设计模式之装饰器模式

    go设计模式之装饰器模式 再写这篇文章时,我已经看了很多其他人发表的类似文章,大概看了这么多吧. 亓斌的设计模式-装饰者模式(Go语言描述) jeanphorn的Golang设计模式之装饰模式 七八月 ...

  4. python中的装饰器、装饰器模式_python 设计模式之装饰器模式 Decorator Pattern

    #写在前面 已经有一个礼拜多没写博客了,因为沉醉在了<妙味>这部小说里,里面讲的是一个厨师苏秒的故事.现实中大部分人不会有她的天分.我喜欢她的性格:总是想着去解决问题,好像从来没有怨天尤人 ...

  5. python 设计模式之装饰器模式 Decorator Pattern

    #写在前面 已经有一个礼拜多没写博客了,因为沉醉在了<妙味>这部小说里,里面讲的是一个厨师苏秒的故事.现实中大部分人不会有她的天分.我喜欢她的性格:总是想着去解决问题,好像从来没有怨天尤人 ...

  6. 详解设计模式:装饰器模式

    装饰器模式(Decorator Pattern)也称为包装模式(Wrapper Pattern),是 GoF 的 23 种设计模式中的一种结构型设计模式.装饰器模式 是指在不改变原有对象的基础之上,将 ...

  7. javascript设计模式之装饰器模式(结构型模式)

    javascript设计模式之装饰器模式 js的设计模式分为创建型模式,结构型模式和行为模式 结构模式描述了如何组合对象以提供新的功能. 装饰器模式是一种常见的结构型模式,我们可以以一个基础对象为基础 ...

  8. 设计模式之装饰器模式详解

    设计模式之装饰器模式详解 文章目录 设计模式之装饰器模式详解 一.什么是装饰器模式 二.装饰器模式的角色组成 三.装饰器模式通用写法示例 四.装饰器模式业务中的应用举例 五.装饰器模式优缺点 一.什么 ...

  9. c++设计模式之装饰器模式 学习笔记

    装饰器模式的意义和字面意思相差不多--就是装饰的方法.比如人穿不同的衣服,在花园里栽种不同的花,游戏中的英雄带不同的装备等等.其中,人/花园/英雄是主体,是你要装备的东西:衣服/花/装备是装备物,是你 ...

最新文章

  1. Linux那些事儿 之 戏说USB(34)接口的驱动
  2. JavaScript中正则表达式学习(一)
  3. [YTU]_2640(编程题:运算符重载---矩阵求和)
  4. ipython源代码怎么打开_CentOS 6.4 中IPython如何启动Qt控制台和NoteBook?
  5. python中硬要写抽象类和抽象方法
  6. SqlSugar与Fluent NHibernate的性能测试对比
  7. VxWorks基本OS介绍
  8. 3分钟搞懂MySQL事务隔离级别及SET TRANSACTION影响事务
  9. 【iOS开发必备指南合集二】申请IDP/真机调试/GameCenter 指南/OpenFeint指南
  10. linux jetty 配置文件,linux中Jetty的安装和配置方法
  11. 链接标签(HTML)
  12. 2017年值得学习的3个CSS特性
  13. 详解tf.Session()和tf.InteractiveSession()的区别
  14. Linux应用层24点小游戏,C++ Builder构建算二十四点小游戏
  15. linux下c语言读写文件操作,Linux下C语言之文件操作
  16. 服务器是如何被入侵的
  17. 二极管三极管 模电
  18. sysbios挂钩函数使用_使用动作挂钩自定义WordPress主题
  19. mysql oder by 注入_Order by排序注入方法小总结
  20. 前嗅教你大数据:采集孔夫子旧书网

热门文章

  1. 深入理解maven及应用--转
  2. 【科技金融】互金风控大数据盘点
  3. 华为,15万大军孤独行走在世界上
  4. 从自我学习到深层网络
  5. Google:狡兔三窟
  6. Redis-07Redis数据结构--有序集合ZSet
  7. Java学习笔记(十)--控制台输入输出
  8. 【线索二叉树详解】数据结构06(java实现)
  9. RocketMQ:NameServer路由管理源码分析
  10. 项目实战-解决AES(java.security.InvalidKeyException: Illegal key size)