要实现装饰者模式,注意以下几点内容:
a.装饰者类要实现真实类同样的接口
b.装饰者类内有一个真实对象的引用(可以通过装饰者类的构造器传入)
c.装饰类对象在主类中接受请求,将请求发送给真实的对象(相当于已经将引用传递到了装饰类的真实对象)
d.装饰者可以在传入真实对象后,增加一些附加功能(因为装饰对象和真实对象都有同样的方法,装饰对象可以添加一定操作在调用真实对象的方法,或者先调用真实对象的方法,再添加自己的方法)
e.不用继承
需求
假设要制造添加甜蜜素和着色剂的馒头:
a.需要生产一个正常馒头
b.为节省成本(不使用玉米面),使用染色剂加入到正常馒头中
c.和面,最后生产出染色馒头
实现
- 做面包的接口:
public interface IBread {
void prepair();
void kneadFlour();
void steamed();
void process();
}
- 制作正常馒头:
public class NormalBread implements IBread {
@Override
public void prepair() {
System.out.println("准备面粉,水以及发酵粉...");
}
@Override
public void kneadFlour() {
System.out.println("和面...");
}
@Override
public void steamed() {
System.out.println("蒸馒头...香喷喷的馒头出炉了");
}
@Override
public void process() {
prepair();
kneadFlour();
steamed();
}
}
- 定义出制作面包的抽象类:
public class AbstractBread implements IBread {
private final IBread bread;
public AbstractBread(IBread bread) {
super();
this.bread = bread;
}
@Override
public void prepair() {
this.bread.prepair();
}
@Override
public void kneadFlour() {
this.bread.kneadFlour();
}
@Override
public void steamed() {
this.bread.steamed();
}
@Override
public void process() {
prepair();
kneadFlour();
steamed();
}
}
- 生产有着色剂的“玉米馒头”:
public class CornDecorator extends AbstractBread {
public CornDecorator(IBread bread) {
super(bread);
}
public void paint() {
System.out.println("添加柠檬黄的着色剂");
}
@Override
public void kneadFlour() {
//添加着色剂后和面
this.paint();
super.kneadFlour();
}
}
- 生产有甜蜜素的“甜馒头”:
public class SweetDecorator extends AbstractBread {
public SweetDecorator(IBread bread) {
super(bread);
}
public void paint() {
System.out.println("添加甜蜜素...");
}
@Override
public void kneadFlour() {
//添加甜蜜素后和面
this.paint();
super.kneadFlour();
}
}
- 测试类:
public class TestA {
public static void main(String[] args) {
System.out.println("=======开始装饰馒头");
IBread normalBread = new NormalBread();
normalBread = new SweetDecorator(normalBread);
normalBread = new CornDecorator(normalBread);
normalBread.process();
System.out.println("=======装饰馒头结束");
}
}
运行结果: