装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。 这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。
这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。
回到我们的辣条工厂,在 桥接模式 中我们将辣条的生产和包装分开了,工厂运作的很好,一转眼工厂开了好几年了,现在想在之前的辣条基础上推出周年版的包装。
- 之前的辣条
public interface HotStrip {
String getType();//保存辣条的种类信息
}
public class KissHotStrip implements HotStrip {
@Override
public String getType() {
return "这是亲嘴烧!";
}
}
public class BigHotStrip implements HotStrip {
@Override
public String getType() {
return "这是大面筋!";
}
}
- 抽象出包装类
public interface Packer {
void pack();
}
- 调整之前的生产线
public abstract class Bridge implements Packer{
private HotStrip hotStrip;
public HotStrip getHotStrip() {
return hotStrip;
}
public void setHotStrip(HotStrip hotStrip) {
this.hotStrip = hotStrip;
}
//public abstract void pack();
}
public class PackageBridge extends Bridge {
@Override
public void pack() {
System.out.println("包装辣条:" + getHotStrip().getType());
}
}
- 创建周年版包装生产线
public class Decorator implements Packer {
private Packer packer;
public Decorator(Packer packer) {
this.packer = packer;
}
@Override
public void pack() {
packer.pack();
System.out.println("周年纪念装!");
}
}
- 测试新生产线
public class DecoratorTest {
@Test
public void testDecorator() {
Bridge bridge = new PackageBridge();
HotStrip hotStrip1 = new KissHotStrip();
bridge.setHotStrip(hotStrip1);
bridge.pack();//继续生产之前的
HotStrip hotStrip2 = new BigHotStrip();
bridge.setHotStrip(hotStrip2);
//生产周年纪念装
Decorator decorator = new Decorator(bridge);
decorator.pack();
}
}
可以看出,通过装饰类在不改变之前结构的情况下,扩展了生产线。
- 扩展一个类的功能。
- 动态增加功能,动态撤销。
一般的,我们为了扩展一个类经常使用继承方式实现,由于继承为类引入静态特征,并且随着扩展功能的增多,子类会很膨胀。
装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。
多层装饰比较复杂。
可代替继承。