装饰模式Decorator
1. 定义
动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式比生成子类更为灵活。
2. 结构图
Component:组件对象的接口,可以给这些对象动态地添加职责。
ConcreteComponent:具体的组件对象,实现组件对象接口,通常就是被装饰器装饰的原始对象,也就是可以给这个对象添加职责。
Decorator:所有装饰器的抽象父类,需要定义一个与组件接口一致的接口,并持有一个Component对象,其实就是持有一个被装饰的对象。注意这个被装饰的对象不一定是最原始的那个对象,也可能是被其他装饰器装饰过后的对象,反正都是实现的同一个接口,也就是同一类型。
ConcreteDecorator:实际的装饰器对象,实现具体要向被装饰器对象添加的功能。
3. 本质
装饰模式的本质:动态组合。
4. Code Demo
Component.java
package org.fool.decorator;
public interface Component {
public void doSomething();
}
ConcreteComponent.java
package org.fool.decorator;
public class ConcreteComponent implements Component {
@Override
public void doSomething() {
System.out.println("功能A");
}
}
Decorator.java
package org.fool.decorator;
public class Decorator implements Component {
private Component component;
public Decorator(Component component) {
this.component = component;
}
@Override
public void doSomething() {
component.doSomething();
}
}
ConcreteDecorator1.java
package org.fool.decorator;
public class ConcreteDecorator1 extends Decorator {
public ConcreteDecorator1(Component component) {
super(component);
}
@Override
public void doSomething() {
super.doSomething();
this.doAnotherThing();
}
private void doAnotherThing() {
System.out.println("功能B");
}
}
ConcreteDecorator2.java
package org.fool.decorator;
public class ConcreteDecorator2 extends Decorator {
public ConcreteDecorator2(Component component) {
super(component);
}
@Override
public void doSomething() {
super.doSomething();
this.doAnotherThing();
}
private void doAnotherThing() {
System.out.println("功能C");
}
}
Client.java
package org.fool.decorator;
public class Client {
public static void main(String[] args) {
/*
* //节点流 Component component = new ConcreteComponent();
*
* //过滤流 Component component2 = new ConcreteDecorator1(component);
*
* component2.doSomething();
*
* System.out.println("------------");
*
* //过滤流 Component component3 = new ConcreteDecorator2(component2);
*
* component3.doSomething();
*/
Component component = new ConcreteDecorator1(new ConcreteDecorator2(new ConcreteComponent()));
component.doSomething();
}
}