装饰模式(DECORATOR模式),又称包装器Wrapper,属于对象结构型模式,用于动态地给一个对象添加一些额外的职责。就增加功能而言,Decorator模式比生成子类更为灵活。它通过使用对象之间的关联关系取代类之间的继承关系,引入的装饰类既可以调用被装饰类的方法,还可以添加新的业务逻辑,以达到扩充被装饰类的功能。装饰模式和适配器模式虽然都称为包装器,但两者还是不同的。装饰模式只是在原有对象的基础上增加新的职责,而不改变对外提供的接口。适配器模式用于解决接口之间的不兼容问题,必然会改变对外提供的接口。
一、使用场景
1、在不影响其他对象的情况下,以动态,透明的方式给单个对象添加职责。装饰模式采用对象组合而非类继承方式扩展功能,所以对于需要扩充的对象可以动态添加,切换,删除相应的职责而不影响其他对象。
2、处理那些可以撤销的职责,对于需要某项职责的对象只需关联相应的装饰对象即可。
3、当不能采用继承的方式对系统进行扩展或者采用继承不利于系统扩展和维护时。一种情况是系统中存在大量独立的扩展,为支持每一种扩展或者扩展之间的组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏或类不能被继承,比如Java中类定义为final类。
二、UML图
三、Java实现
运行结果:四、模式优缺点
优点:
1、 对于扩展一个对象的功能,装饰模式比继承更加灵活性,不会导致类的个数急剧增加。
2、可以通过一种动态的方式来扩展一个对象的功能,通过配置文件可以在运行时选择不同的具体装饰类,从而实现不同的行为。
3、可以对一个对象进行多次装饰,通过使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同行为的组合,得到功能更为强大的对象。
4、具体构件类与具体装饰类可以独立变化,用户可以根据需要增加新的具体构件类和具体装饰类,原有类库代码无须改变,符合“开闭原则”。
5、避免在层次结构高层的类有太多的特征。高层的类越简单,其可扩展性,灵活性越好。可以定义一个简单的类,然后使用Decorator类给它逐渐添加功能。
缺点:
1、 使用装饰模式进行系统设计时将产生很多小对象,这些对象的区别在于它们之间相互连接的方式有所不同,而不是它们的类或者属性值有所不同,大量小对象的产生势必会占用更多的系统资源,在一定程序上影响程序的性能,也增大了学习系统的复杂度。
2、装饰模式提供了一种比继承更加灵活机动的解决方案,但同时也意味着比继承更加易于出错,排错也很困难,对于多次装饰的对象,调试时寻找错误可能需要逐级排查,较为繁琐。
3、Decorator与它的Component不一样,Decorator只是透明的包装,所以客户端使用时不应该依赖Decorator。