装饰者(Decorator)模式
装饰模式又名包装(Wrapper)模式。装饰模式是继承关系的一个替代方案。装饰模式是在不必改变原类文件和使用继承的情况下,动态的扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。
举一个生活中的例子,
去奶茶店点奶茶,奶茶的种类有很多种,珍珠奶茶、绿茶、红茶...然后每一种茶都可以有不同的配置方案,比如常见的:去冰、加糖、打包等。
那么,假设每种类型的奶茶都是一个实体类,可以在每种奶茶包装不同的属性(配置方案)。
1.创建父类
这里设定为接口,每种奶茶都实现了该接口
public interface Tea {
void describe();
}
describe()函数简单的模拟该tea包含的属性。
2.定义每种奶茶的实体类
/**
* 珍珠奶茶
*/
public class PearlTea implements Tea {
@Override
public void describe() {
System.out.print("珍珠奶茶\t");
}
}
/**
* 红茶
*/
public class BlackTea implements Tea {
@Override
public void describe() {
System.out.print("红茶\t");
}
}
/**
* 绿茶
*/
public class GreenTea implements Tea {
@Override
public void describe() {
System.out.print("绿茶\t");
}
}
3.定义装饰基础类
处理装饰者公共逻辑部分,在构造函数中,传入需要包装的Tea对象,对其进行“装饰操作”
/**
* tea装饰基础类
*/
public abstract class CommenTeaDecorate implements Tea {
protected Tea tea;
public CommenTeaDecorate(Tea tea) {
this.tea = tea;
}
@Override
public void describe() {
tea.describe();
}
}
4.装饰属性的实现类
/**
* 去冰
*/
public class NoIceTeaDecorate extends CommenTeaDecorate {
public NoIceTeaDecorate(Tea tea) {
super(tea);
}
@Override
public void describe() {
super.describe();
System.out.print("去冰\t");
}
}
/**
* 加糖
*/
public class SugarTeaDecorate extends CommenTeaDecorate {
public SugarTeaDecorate(Tea tea) {
super(tea);
}
@Override
public void describe() {
super.describe();
System.out.print("加糖\t");
}
}
/**
* 打包
*/
public class PackTeatDecorate extends CommenTeaDecorate {
public PackTeatDecorate(Tea tea) {
super(tea);
}
@Override
public void describe() {
super.describe();
System.out.print("打包\t");
}
}
5.调用方法
例子1:分别包装三种类型的奶茶,
PearlTea pearlTea = new PearlTea();
GreenTea greenTea = new GreenTea();
BlackTea blackTea = new BlackTea();
NoIceTeaDecorate noIceTeaDecorate = new NoIceTeaDecorate(pearlTea);
SugarTeaDecorate sugarTeaDecorate = new SugarTeaDecorate(greenTea);
PackTeatDecorate packTeatDecorate = new PackTeatDecorate(blackTea);
noIceTeaDecorate.describe();
sugarTeaDecorate.describe();
packTeatDecorate.describe();
打印:
珍珠奶茶 去冰
绿茶 加糖
红茶 打包
例子2:针对一种奶茶多重属性包装,
PearlTea pearlTea = new PearlTea();
NoIceTeaDecorate noIceTeaDecorate = new NoIceTeaDecorate(pearlTea);
SugarTeaDecorate sugarTeaDecorate = new SugarTeaDecorate(noIceTeaDecorate);
PackTeatDecorate packTeatDecorate = new PackTeatDecorate(sugarTeaDecorate);
sugarTeaDecorate.describe();
packTeatDecorate.describe();
输出结果:
珍珠奶茶 去冰 加糖
珍珠奶茶 去冰 加糖 打包
很明显,针对一种奶茶,可以包装很多种属性,相当于文前所说“动态的扩展一个对象的功能”。