装饰模式(Decorator)
动态的给某一对象添加额外的职责。也可以叫做包装器(Wrapper)。
在GoF23种设计模式中,属于结构型模式( Structural patterns)
。
一般来说我们给一个类拓展新功能都会采用继承。但是继承的类都是静态的,也就说每支持一种新功能,就需要实现对应功能的继承类。当新功能之间有排列组合关系时,如果采用继承,那实现类就要爆炸了。
例如,我们想要做一个汉堡。该汉堡可以加热狗,芝士等配料。如果采用继承实现,我们就需要有汉堡,热狗汉堡,芝士汉堡,热狗芝士汉堡四个子类。如果再加上添加顺序,那么先加芝士或先加热狗就又不同了。因此,这么实现就会有上面所说的类爆炸情况了。
装饰模式就可以解决这个问题。装饰模式可以将汉堡与配料动态组合在一起。想要怎么搭配全交给顾客,顾客说怎么来就怎么搞。
-
优点
- 动态添加,灵活组合
- 符合开闭原则
-
缺点
- 系统设计中会产生许多小对象,增加了系统的复杂性
- 难排错和debug
实现
uml类图
角色说明
- Component
- 抽象接口,待被装饰的接口
- ConcreteComponent
- 具体实现类,可被装饰的具体类
- Decorator
- 抽象装饰类,所有装饰类的接口
- ConcreteDecorator
- 具体装饰类
code
我们就以做汉堡举例。
对应角色
- 汉堡 - Component
- 香辣汉堡 - ConcreteComponent
- 配料 - Decorator
- ConcreteDecorator
- 热狗
- 芝士
AbstractHamburg.java
public abstract class AbstractHamburg {
abstract void process();
}
SpicyHamburg.java
public class SpicyHamburg extends AbstractHamburg {
@Override
void process() {
System.out.println("做一个香辣汉堡");
}
}
AbstractFixing.java
public abstract class AbstractFixing extends AbstractHamburg{
private AbstractHamburg abstractHamburg;
public AbstractFixing(AbstractHamburg abstractHamburg) {
this.abstractHamburg = abstractHamburg;
}
@Override
void process() {
abstractHamburg.process();
}
}
Cheese.java
public class Cheese extends AbstractFixing {
public Cheese(AbstractHamburg abstractHamburg) {
super(abstractHamburg);
}
@Override
void process() {
super.process();
System.out.println("加一份芝士");
}
}
HotDog.java
public class HotDog extends AbstractFixing {
public HotDog(AbstractHamburg abstractHamburg) {
super(abstractHamburg);
}
@Override
void process() {
super.process();
System.out.println("加一份热狗");
}
}
Test.java
public class Test {
public static void main(String[] args) {
// 加了芝士热狗的汉堡 = 芝士(热狗(辛辣汉堡))
AbstractHamburg hamburg = new Cheese(new HotDog(new SpicyHamburg()));
hamburg.process();
}
}
output
做一个香辣汉堡
加一份热狗
加一份芝士
这种模式下,不管你是先要加热狗或者芝士,不管你要加几次,都可以任你组合,十分方便。
实例
- io流
总结
如果你需要一个可以动态拓展,自由组合的设计,装饰模式一定不要错过。
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名,转载请标明出处
最后编辑时间为: