装饰者模式概述
装饰者模式指在无须改变原有类及类的继承关系的情况下,动态扩展一个类的功能。它通过装饰者来包裹真实的对象,并动态地向对象添加或者撤销功能。
装饰者模式包含Source和Decorator两种角色,Source是被装饰者,Decorator是装饰者。装饰者模式通过装饰者可以为被装饰者Source添加一些功能。
(1)定义Sourceable接口
public interface Sourceable {
public void createComputer();
}
以上代码定义了一个Sourceable接口,该接口定义了一个生产电脑的方法createComputer()。
(2)定义Sourceable接口的实现类Source:
public class Source implements Sourceable{
private final static Log logger = LogFactory.getLog(Source.class);
@Override
public void createComputer() {
logger.info("create computer by Source");
}
}
以上代码定义了Sourceable接口的实现类Source并实现了其createComputer()。
(3)定义装饰者类Decorator:
public class Decorator implements Sourceable{
private Sourceable source;
private final static Log logger = LogFactory.getLog(Decorator.class);
public Decorator(Sourceable source){
super();
this.source = source;
}
@Override
public void createComputer() {
source.createComputer();
//在创建完电脑后给电脑装上系统
logger.info("make system.");
}
}
以上代码定义了装饰者类Decorator,装饰者类通过构造函数将Sourceable实例初始化到内部,并在其方法createComputer()中调用原方法后加上了装饰者逻辑,这里的装饰指在电脑创建完成后给电脑装上相应的系统。注意,之前的Sourceable没有给电脑安装系统的步骤,我们引入装饰者为Sourceable扩展了安装系统的功能。
(4)使用装饰者模式:
public static void main(String[] args) {
Sourceable source = new Source();
Sourceable obj = new Decorator(source);
obj.createComputer();
}
在使用装饰者模式时,需要先定义一个待装饰的Source类的source对象,然后初始化构造器Decorator并在构造函数中传入source对象,最后调用createComputer(),程序在创建完电脑后还为电脑安装了系统。运行结果如下:
[INFO] Source - create computer by Source
[INFO] Decorator - make system.
装饰者模式实例
抽象构件角色(对应动物类)
public interface Component {
void function();
}
具体构件角色(对应狗)
public class ConcreteComponent implements Component {
@Override
public void function() {
System.out.println("基本功能:呼吸+觅食+睡觉");
}
}
装饰角色
public class Decorator implements Component {
private Component component; //持有一个Component类型的对象引用
public Decorator(Component component) {
this.component = component;
}
@Override
public void function() {
component.function(); //客户端的调用委派给具体的子类
}
}
具体装饰角色(对应吼叫和吃肉这两个功能)
public class ConcreteDecorator extends Decorator {
public ConcreteDecorator(Component component) {
super(component);
}
@Override
public void function() {
super.function();
System.out.println("附加功能:");
this.eat();
this.bellow();
}
private void eat() {
System.out.println("吃肉");
}
private void bellow() {
System.out.println("吼叫");
}
}
客户端测试:
public class ClientTest {
public static void main(String[] args) {
Component component = new ConcreteComponent();
System.out.println("------装饰前:-------");
component.function();
Component newComponent = new ConcreteDecorator(component);
System.out.println("------装饰后:-------");
newComponent.function();
}
}
输出:
------装饰前:-------
基本功能:呼吸+觅食+睡觉
------装饰后:-------
基本功能:呼吸+觅食+睡觉
附加功能:吃肉+吼叫