装饰者(Decorator)模式

第三章 装饰者(Decorator)模式

1.组合(Composite)和委托(delegation)可以在运行时具有继承行为的效果.
组合: 在类中引用另一个类,将其对象作为当前类的一个变量(类变量).
委托: 使程序员可以将方法引用封装在委托对象内。然后可以将该委托对象传递给可调用该引用方法的代码,而不必在编译时知道将调用哪个方法。

2.利用继承设计子类的行为,是在编译时静态决定的,而且所有的子类都会继承到相同的行为.然而,如果能够利用组合的做法扩展对象的行为,就可以运行时动态地进行扩展.

3.通过动态地组合对象,可以写新的代码添加新的功能,而无须修改现有代码.既然没有改变现有代码,那么引进bug或产生意外副作用的机会将大幅度减少.

4.代码应该如同晚霞中的莲花一样地关闭(免于改变),如同晨曦中的莲花一样地开放(能够扩展).

5.设计原则五: 类应该对扩展开放,对修改关闭(Open-Closed Principle,OCP).即在设计一个模块的时候,应当使这个模块可以在不被修改的前提下被扩展.

6.我们的目标是允许类容易扩展,在不修改代码的情况下,就可以搭配新的行为.这样的设计具有弹性可以应对改变,可以接受新的功能来应对改变的需求.

7.装饰者(Decorator)模式很好地遵循开放-关闭原则(OCP).

8.遵循开放-关闭原则,通常会引入新的抽象层次,增加代码的复杂度.在程序设计过程中,我们应当把注意力放在那些最有可能会变化的地方,然后应用开放-关闭原则(OCP).一般来说,不可能使(大的)程序完全地既对修改关闭又对扩展开放.并且往往对程序每一个部分实现这样的设计反而会得不偿失.

9.装饰者和被装饰者有相同的超类型.

10.既然装饰者和被装饰者有相同的超类型,所以在任何需要原始对象(被包装的)的场合,可以用装饰过的对象代替它.

11.对象可以在任何时候被装饰,所以可以在运行时动态地、不限量地用你喜欢的装饰者来装饰对象.

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

13.java.io包内的许多类都是装饰者.如: BufferedInputStream及LineNumberInputStream都扩展自FilterInputStream,而FilterInputStream是一个抽象的装饰类,这是InputStream的一个抽象装饰者.(LineNumberInputStream->BufferedInputStream->FilterInputStream)
FilterInputStream是被装饰的组件.Java I/O程序库提供了几个组件,包括了FileInputStream,StringBufferInputStream,ByteArrayInputStream...等.这些类都提供了最基本的字节读取功能.
BufferedInputStream是一个具体的装饰者,它加入了两种行为: 1.利用缓冲输入来改进性能 2.用一个readLine()方法(用来一次读取一行文本输入数据)来增强接口.
LineNumberInputStream是一个装饰者,它加上了计算行数的能力.
个人觉得,Scanner s = new Scanner(System.in);Scanner是System.in的一个装饰.

14.(缺点)装饰者模式的一个"缺点": 利用装饰者模式,常常造成设计中有大量的小类,数量实在太多,可能会造成使用些API程序员的困扰.

15.装饰者模式因为会在设计中加入了大量的小类,偶尔会导致不容易了解它的设计方式,造成混乱.就像Java I/O 库来说,人们第一次接触到这个库时,往往无法轻易理解它.

16.装饰者一个优点是,你通常可以透明地插入装饰者,客户程序甚至不需知道它是在和装饰者打交道。但是,如我刚刚所说的,有些代
码会依赖特定的类型,而这样的代码一导入装饰者,嘭!出状况了!

17.(缺点)采用装饰者在实例化组件时,将增加代码的复杂度.一旦使用装饰者模式,不只需要实例化组件,还要把此组件包装进装饰者中.

18.OO原则: 1.封闭变化 2.多用组合,少用继承 3.针对接口编程,不针对实现编程 4.为交互对象之间的松耦合而努力 5.对修改关闭,对扩展开放
OO模式: 装饰者模式: 动态地将责任附加到对象上.想要扩展功能,装饰者提供有别于继承的另一种选择.

19.组合和委托可用于在运行时动态地加上新的行为.而继承早在编译期就将对象的行为定好了.

20.(缺点)装饰者会导致设计中出现许多小对象,如果过度使用,会让程序变得很复杂.

21.装饰者类反映出被装饰的组件类型(事实上,他们具有相同的类型,都经过接口或继承实现).

你可能感兴趣的:(设计模式,编程,OO)