黑马程序员技术交流社区

标题: 关于装饰设计模式 [打印本页]

作者: 王敏NO.09    时间: 2012-4-17 18:06
标题: 关于装饰设计模式
之前看过一遍视频,今天复习,看完后感觉还是一头雾水,请高手点拨
作者: 曾虓    时间: 2012-4-17 18:41
请参考这个帖子:http://bbs.itheima.com/forum.php ... amp;page=1#pid64775
希望对你有所帮助。
作者: 黑马-刘昌文    时间: 2012-4-17 20:07
所谓的装饰模式实际上是用一个类去装饰另一个类,提高它的性能。这个类必须接受一个构造参数,这个构造参数就是它要装饰的类,这个类可以可以对外提供它装饰的类的方法,还可以再定义一些方法,用于提高它的性能,IO流中的BufferedInputStream 就用到了装饰的设计模式,它装饰的类是InputStream。
作者: liuyang    时间: 2012-4-17 21:02
“装饰模式(Decorator)”又名“包装模式(Wrapper)”,包装模式也就是一层一层包装的,就是老师所说的像蛋壳一样.对于装饰模式,我还不是怎么理解,一般模式写程序需要建多个类,甚至是几十个,用装饰模式就不用那那么多,它可以通过类似排列组合来组合成新的类,只建几个基类和子类就可以,不用那么繁琐,使代码看起来也更加的清晰易懂.通常用来灵活地扩充对象的功能。
  在此之前我们可以通过类的继承来扩充父类的功能,但这种继承方式缺乏灵活性,并且会导到子类数量的快速膨胀。恰当地使用装饰模式我们会轻松实现在控制子类数量的基础上,灵活地实现对象功能的扩展。装饰模式比类的继承更灵活。
概述

(1)模式功能

    装饰模式能够实现动态的为对象添加功能,是从一个对象外部来给对象增加功能,相当于是改变了对象的外观。当装饰过后,从外部使用系统的角度看,就不再是使用原始的那个对象了,而是使用被一系列的装饰器装饰过后的对象。

    这样就能够灵活的改变一个对象的功能,只要动态组合的装饰器发生了改变,那么最终所得到的对象的功能也就发生了改变。

    变相的还得到了另外一个好处,那就是装饰器功能的复用,可以给一个对象多次增加同一个装饰器,也可以用同一个装饰器装饰不同的对象。

(2)对象组合

    前面已经讲到了,一个类的功能的扩展方式,可以是继承,也可以是功能更强大、更灵活的对象组合的方式。

    其实,现在在面向对象设计中,有一条很基本的规则就是“尽量使用对象组合,而不是对象继承”来扩展和复用功能。装饰模式的思考起点就是这个规则,可能有些朋友还不太熟悉什么是“对象组合”,下面介绍一下“对象组合”。

什么是对象组合

(3)装饰器

装饰器实现了对被装饰对象的某些装饰功能,可以在装饰器里面调用被装饰对象的功能,获取相应的值,这其实是一种递归调用。

在装饰器里不仅仅是可以给被装饰对象增加功能,还可以根据需要选择是否调用被装饰对象的功能,如果不调用被装饰对象的功能,那就变成完全重新实现了,相当于动态修改了被装饰对象的功能。

另外一点,各个装饰器之间最好是完全独立的功能,不要有依赖,这样在进行装饰组合的时候,才没有先后顺序的限制,也就是先装饰谁和后装饰谁都应该是一样的,否则会大大降低装饰器组合的灵活性。

(4)装饰器和组件类的关系

装饰器是用来装饰组件的,装饰器一定要实现和组件类一致的接口,保证它们是同一个类型,并具有同一个外观,这样组合完成的装饰才能够递归的调用下去。

组件类是不知道装饰器的存在的,装饰器给组件添加功能是一种透明的包装,组件类毫不知情。需要改变的是外部使用组件类的地方,现在需要使用包装后的类,接口是一样的,但是具体的实现类发生了改变。

(5)退化形式

如果仅仅只是想要添加一个功能,就没有必要再设计装饰器的抽象类了,直接在装饰器里面实现跟组件一样的接口,然后实现相应的装饰功能就可以了。但是建议最好还是设计上装饰器的抽象类,这样有利于程序的扩展。

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

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

l 抽象装饰(Decorator)角色:持有一个构件(Component)对象的实例,以用来对它进行装饰,并定义一个与抽象构件接口一致的接口。

l 具体装饰(Concrete Decorator)角色:负责给构件对象"加上"附加的功能。
Java IO流中的装饰模式解析

该模式和继承有什么区别呢?

它比继承有更好的灵活性。

通常装饰类和被装饰类都同属与一个父类或者接口。

Writer

|--MediaWriter

|--TextWriter

需求:想要对数据的操作提高效率,就用到了缓冲技术。

通过所学习的继承特性。可以建立子类复写父类中的write方法。即可

Writer:不要误解,以下两个对象不存在,只为举例。

|--MediaWriter

|--BufferedMediaWriter

|--TextWriter

|--BufferedTextWriter

当Writer中子类对象过多,那么为了提高每一个对象效率,每一个对象都有 一个自己的子类Buffered。

虽然可以实现,但是继承体系变的很臃肿。

那么是否可以对其进行一下优化呢?

其实增期都是在使用缓冲技术。

可不可以对缓冲技术进行描述,将需要增强的对象传递给缓冲区即可。

下面便是对于装饰模式的一个简单的说明

M

--------------------------

普通继承模式实现

A 发镖

B 变身

C 无敌

M1: A

M2: B

M3: C

M4:A B      

M5:A C

M6:B C

M7:A B C

---------------------------

装饰模式

M

|--M1

|--M2

|--M3

A B      : new M2(M1)

A C      : new M3(M1)

B C      : new M3(M2)

A B C    : new M3(M2(M1))
作者: 方江    时间: 2012-4-18 07:54
其实你这样理解,装饰模式是一种优化代码结构的模式。更多的是,它能够让类与类之间的联系减少,减少子类代码的臃肿。
就拿与继承来比,它更多的是提取继承父类的子类代码的共性生成一个父类,让调用者更为简单,目的更为明确。
他只是说把面对对象的这种思想换一个角度来考虑。不知道你看到那章装饰与继承的区别没。你可以理解到装饰模式的好处。
希望对你有帮助。
老貟。楼上像是百度的啊~~~{:soso__771663216932030145_2:}
作者: 方江    时间: 2012-4-18 07:55
不对,楼上是自己写的。我靠,好威武。顶起~~




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2