从我们的穿衣打扮开始
如果我们要按照如下的方式对自己进行穿衣打扮:
这样造成的问题是:
如果要增加其他装扮,那么就需要修改Person类,违背了开放封闭原则
我们可以用装饰者模式来进行解决这个问题
装饰者模式对客户端以透明的方式扩展对象的功能,是继承关系的一个替代方案
具体的实现代码:
总的抽象类:
人实现的接口:
Person实现一个抽象的接口,实现的抽象方法是,Show方法
衣服的接口:
在初始化的时候就已经完成了一个包装的方式:
具体的衣服接口:
等等....
客户端中的调用:
这一种方式是通过在实例化类的时候就完成了一个装饰的功能
还有另外一种方式,我觉得更有装饰者的味道:
首先也是抽象的接口:
然后是人的具体类:
所有衣服的父类:
这里面定义了专门的装饰者模式,也就是不需要在实例化的时候就完成装饰者的功能
具体的衣服类:
等等....
客户端的调用:
明显可见,我们需要怎么装饰在客户端调用相应的组件即可
装饰者模式常常被称为包裹模式,就是因为每一个具体装饰类都将下一个具体装饰类或者具体构建类包裹起来
抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加责任的对象
具体构件(Concrete Component)角色:实现组件对象的接口,通常来说就是被装饰的对象
装饰角色(Decorator):持有一个构件对象的实例,并定义一个与抽象构建接口一致的接口
具体装饰角色(Concrete Decorator):负责给构建对象贴上附加责任
装饰模式为对象添加额外责任的方式就像做蛋糕一样,一圈一圈的加上去,中间的面包是核心,是被装饰的对象,是核心人物,外围的都是装饰对象
也就是说装饰者模式包含两部分模式,即装饰对象和被装饰对象
装饰者模式的效果是:
让我们可以创建以decorator对象(负责新的功能的对象)开始的一条对象“链”,并结束于最初的对象
也就是说是生成了一条链,然后按照链的方式一步一步传递下去:
装饰者模式用到的最多的是:
继承与多态
在实际的应用是:JAVA中的I/O流,我们在进行文件输入与输出的时候,可以进行相应的包装
我们知道文件输出的时候,都是继承自OutputStream,那么我们可以这样来考虑,再写一个类继承OutputStream,进行相应的文件修改
这样就实现了文件的英文加密操作
客户端代码:
在初始化的时候就使用了装饰者模式
-
装饰模式的功能:弄够实现动态地为对象添加功能,是从一个对象外部给对象增加功能,相当于是改变了对象的外观
-
装饰器与组件类的关系:装饰器是用来装饰组件的,装饰器一定要实现和组件类一致的接口,保证他们是同一个类型,并且具有同一个外观,,这样组合完成的装饰才能够递归调用下去
本质:
动态是手段,组合是目的
优点:
-
装饰者模式比继承可以提供更多的灵活性
-
通过使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多种的组合
缺点:
会产生很多的细粒度对象
装饰者模式与策略模式的不同:
策略模式 | 改变的是对象的内核 | 一层调用 |
装饰者模式 | 改变的是对象的外壳 | 递归调用 |
两者可以有机结合
装饰模式与AOP
AOP是OOP的延续,意思是面向方面编程
这个地方就简单说一下我自己的理解,AOP是面对切面编程,比如我们在写银行的管理的系统的时候,我们需要有取钱,转账,查询余额的功能
在实行这些功能的前提都是需要输入账号和密码,那么我们在进行写的时候,可以把输入账号和密码写成一个包之类,在使用的时候我们直接进行调用包里面的功能即可
主要的意图就是:
将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑中划分出来,通过对这些行为的分离,我们希望将它们独立到非指导业务逻辑的方法中,进而进行改变这些行为的时候不影响业务逻辑的代码
在复杂的奖金计算的时候,我们也可以使用装饰者模式:
要求:
我们可以使用装饰者模式完成对于不同奖金包装,使用策略模式实现不同的计算奖金的算法
这样就实现了装饰者模式与策略模式的有机结合