概念定义:
装饰模式是在不必改变原类文件和使用继承的情况下,动态的扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。
优点:
把类中的装饰功能从类中搬移出去,这样可以简化原有的类。有效地把类的核心功能和装饰功能区分开了。利用组合(composition)和委托(delegation)可以在运行时实现继承行为的效果,动态地给对象加上新的行为。利用继承扩展子类的行为,是在编译时静态决定的;利用组合的做法,可以在运行时动态地扩展对象的行为。
设计原则:
类应该对扩展开放,对修改关闭。这就是我们常说的开放-关闭原则。开放-关闭原则使类容易扩展,在不修改代码的情况下,通过搭配实现新的行为。这样的设计可以应对改变,比如增加新功能或需求发生变更。
适用场景:
1. 对于生活场景中有装扮的对象,如咖啡可以放各种调料,蛋糕可以增加各种口味.
2. 对已开发的代码做功能扩展,不修改原有代码,不用继承,采用装饰模式扩展.
实例实现:
原有类,有方法Operation():
Component:原有接口
ConcreteComponent:原有接口实现类
新加装饰类:
Decorator:装饰者抽象类
ConcreteDecoratorA:装饰者1
ConcreteDecoratorB:装饰者2
原有接口:
package decorator;
public interface Component {
public void operation();
}
原有类:
package decorator;
public class ConcreteComponent implements Component{
@Override
public void operation() {
System.out.println("我在做事情!");
}
}
扩展接口或抽象类:
package decorator;
public abstract class Decorator implements Component{
}
扩展类1:
package decorator;
public class ConcreteDecoratorA extends Decorator{
public Component component;
public ConcreteDecoratorA(Component component){
this.component = component;
}
public void operation() {
component.operation();
//添加新的行为
System.out.println("原来做的不够,我又增加了新的行为A.");
}
}
扩展类2:
package decorator;
public class ConcreteDecoratorB extends Decorator{
public Component component;
public ConcreteDecoratorB(Component component){
this.component = component;
}
publicvoid operation() {
component.operation();
//添加新的行为
System.out.println("原来做的不够,我又增加了新的行为B.");
}
}
测试类:
package decorator;
public class Test {
public static void main(String[] args) {
Component component = new ConcreteComponent();
component = new ConcreteDecoratorA(component);
component = new ConcreteDecoratorB(component);
component.operation();
}
}
输出结果:
我在做事情!
原来做的不够,我又增加了新的行为A.
原来做的不够,我又增加了新的行为B.
注意地方:
装扮者接口和原来的行为类要实现同样的接口,这样方便两者交互.
到底是用接口还是抽象类看具体情况.
个人觉得,功能扩展才是装饰模式的主要应用所在.