设计模式之二装饰者模式
一 概述
1.什么是装饰者模式?
在不修改类,不使用继承的前提下,用一个对象来装饰另一个对象,以扩展目标对象的功能。
2.装饰者模式的作用:
继承也可以扩展类的功能,装饰者模式比继承更加灵活,因为继承时子类受父类的约束,比如子类方法不能降低访问权限,返回值必须是父类方法返回值的子类,而装饰模式就不受这些约束,比较灵活。
二 基本装饰者模式
结构:
- 父类:可以是接口、抽象类、一般类,保证能够以操作目标对象的方式操作装饰者,即保证装饰者拥有与目标对象相同的方法结构。
- 目标类;
- 装饰者类:其中包含目标对象引用,往往通过构造器注入。
三 高级装饰者模式
1.不仅可以对目标对象进行多种形式的增强,而且可以构建装饰者链将多种增强形式同时施加到目标对象上。
2.结构
- 父类。
- 目标类:实现或者继承了父类。
- 装饰者基类:实现或继承了父类,只是实现了目标对象方法,并未增强,作为后续增强的基础。
- 具体装饰者A类:继承了装饰者基类,对目标类进行一种形式的增强。
- 具体装饰者B类:继承了装饰者基类,对目标类进行一种形式的增强。
3.按照功能模块化原则,一个模块只负责单一的功能,每一种具体装饰者类,只负责实现一种增强形式。
4.具体装饰者类对目标类的增强建立在基类处理结果的基础上,因此在代码中通过先super获取基类的结果,然后再进行增强。
5.构建装饰者链
⑴基本原理:
首先将目标对象传入一个具体装饰者对象中,再将该具体装饰者对象传入下一个具体装饰者对象中,以此推进,形成一个装饰者链,对目标对象逐级增强。
⑵构建关键:
在具体装饰者类中通过super获取基类处理结果,将基类作为中间环节构建装饰者链。
⑶实现Demo
接口
package com.designmode.decorator.senior; public interface ISomeService { String doSome(); }
目标类
package com.designmode.decorator.senior; public class SomeServiceImpl implements ISomeService { @Override public String doSome() { return " abc "; } }
装饰者基类
package com.designmode.decorator.senior; public class SomeServiceWrapper implements ISomeService { private ISomeService target; public SomeServiceWrapper(ISomeService target) { super(); this.target = target; } @Override public String doSome() { return target.doSome(); } }
具体装饰者A类
package com.designmode.decorator.senior; public class TrimDecorator extends SomeServiceWrapper { public TrimDecorator(ISomeService target) { super(target); // TODO Auto-generated constructor stub } @Override public String doSome() { // TODO Auto-generated method stub return super.doSome().trim(); } }
具体装饰者B类
package com.designmode.decorator.senior; public class UpperDecorator extends SomeServiceWrapper { public UpperDecorator(ISomeService target) { super(target); // TODO Auto-generated constructor stub } @Override public String doSome() { // TODO Auto-generated method stub return super.doSome().toUpperCase(); } }
测试类
package com.designmode.decorator.senior; import org.junit.Test; public class DecoratorTest { /** * 装饰者基类,原样实现了目标对象的方法,并未增强 */ @Test public void test01() { ISomeService target = new SomeServiceImpl(); ISomeService decorator = new SomeServiceWrapper(target); String result = decorator.doSome(); System.out.println("result=" + result); } /** * 一次增强,对装饰者基类增强 */ @Test public void test02() { ISomeService target = new SomeServiceImpl(); ISomeService decorator = new TrimDecorator(target); String result = decorator.doSome(); System.out.println("result=" + result); } /** * 形成装饰者链,逐级增强 */ @Test public void test03() { ISomeService target = new SomeServiceImpl(); ISomeService trimDecorator = new TrimDecorator(target);// 一级增强 ISomeService service = new UpperDecorator(trimDecorator);// 二级增强 String result = service.doSome(); System.out.println("result=" + result); } }
三 常见装饰者应用
IO流中广泛使用装饰者模式,一些类正是装饰了基本输入输出流创建的,如XMLWriter\DateOutputStream\BufferedInputstream\
ObjectInputstream等。
四 与静态代理模式对比
1.相同点:
- 都与目标类实现共同的接口。
- 都可以动态地扩展目标类的功能。
- 都需要在自身类中包含目标对象。
2.不同点
⑴设计目的不同:
- 装饰者模式是为了增强目标类的功能。
- 静态代理是为了隐藏与保护目标类。
⑵包含目标对象的方式不同:
- 在装饰者模式中,目标对象由用户创建,通过构造器传入装饰者中,目标对用户可见。
- 在静态代理模式中,目标对象在装饰者类的无参构造方法中创建,对用户不可见。
不能仅仅停滞在实现上,应该去追求代价更小、性能更优的实现