装饰模式
1.装饰模式动机及定义
1.1模式动机
买了新房(毛胚房)需要装修,对新房进行装修并没有改变房子用于居住的本质,但它让房子变的更漂亮,更加满足居家的需求。在软件设计中,我们也可以用类似的技术对原有对象(新房)的功能进行扩展(装修),以获得更加符合用户需求的对象。这种技术在设计模式中被成为装饰模式,装饰模式可以动态地给父类增加功能。
装饰模式可以在不改变一个对象本身的基础上上给对象增加额外的新行为,在现实生活中,这种情况比比皆是,如一张照片,可以不改变照片本身,给它增加一个相框,使得它具有防潮的功能,而且用户可以根据需要给它增加不同类型的相框,甚至可以在一个小的相框的外面再套一个大相框。
在软件外发中,类似给照片加相框的情况也随处可见。如可以给一个图形界面构件增加边框、滚动等新的特性,给一个数据加密类增加更复杂的加密算法等。
一般有两种方式可以实现给一个类或对象增加行为:
1.继承机制
使用继承机制是给现有类添加功能的一种有效途径,通过继承一个现有类可以使得子类在拥有自身方法的同时还拥有父类的方法。但是这种方法是静态的,用户不能控制增加行为的方式和时机。
2.关联机制
关联机制是更加灵活的方法,即将一个类的对象嵌入另一个新对象中,由另一个对象类来决定是否调用嵌入对象的行为并扩展新的行为,我们称这个新的对象(即另一个对象)为装饰器(Decorator)。为了使得装饰器与它所装饰的对象对客户端来说透明,装饰器类和被装饰的类必须实现相同的接口,客户端使用时无须关心一个类的对象是否被装饰过,可以一致性地使用未被装饰的对象以及装饰好的对象。我们可以在被装饰的类中调用在装饰器类中定义的方法,实现更多复杂的功能,而且由于装饰器类和被装饰的类实现了相同的接口,已经被装饰过的对象可以继续作为新的被装饰对象进行装饰,这种透明性使得我们可以递归嵌套多个装饰,从而可以添加任意多的功能。
装饰模式以对客户透明的方式动态地给一个对象附加上更多的责任,换言之,客户端并不会觉得对象在装饰前和装饰后有什么不同。装饰模式可以在不需要创造更多子类的情况下,将对象的功能加以扩展。这就是装饰模式的动机。