装饰模式:动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更灵活。
就是套娃模式,书中举了穿衣服的例子,装配的顺序不固定(比如把内裤穿里面还是外面(超人和正常人)),但是装配的细节需要对外隐藏(不阔能光着身子在其他人面前穿衣服吧),出于隐私考虑穿衣服时只能有穿衣服的人和衣服相互作用。
我们来设想一个场景,有一些肉…然后要料理这块肉,我们可以先切片,加入调料,再加热诸如此类的操作,当然如果是个新手可能就出现先加热再切片然后撒调料这种情况。这就挺符合装饰模式的。
烹饪接口(或者说决定干这么一件事)
interface Cooking_{
void deal();
}
获取食材类
class Meat implements Cooking_{
private String name ;
public Meat(String name) {
this.name = name;
}
@Override
public void deal() {
System.out.println("获取"+name);
}
}
烹饪方式类:
abstract class Handle implements Cooking_{
private Cooking_ cooking_;
public void to(Cooking_ cooking_){
this.cooking_ = cooking_;
}
@Override
public void deal() {
cooking_.deal();
}
}
class Cut extends Handle{
@Override
public void deal() {
super.deal();
System.out.println("切");
}
}
class Spices extends Handle {
@Override
public void deal() {
super.deal();
System.out.println("加调料");
}
}
class Heating extends Handle{
@Override
public void deal() {
super.deal();
System.out.println("加热");
}
}
测试类
@Test
public void test(){
Meat meat = new Meat("牛肉");
Cut cut = new Cut();
Spices spices = new Spices();
Heating heating = new Heating();
cut.to(meat);
spices.to(cut);
heating.to(spices);
heating.deal();
meat = new Meat("猪肉");
heating.to(meat);
spices.to(heating);
cut.to(spices);
cut.deal();
}
这个模式的应用场景是为已有功能添加一些新的措施时的一种方式(比如我们的生牛肉->切片生牛肉->加了调料的切片生牛肉->加了调料的切片熟牛肉)。
虽然装配顺序是可自由组合的,不过有时候还是需要控制顺序的(加调料再加热,肉才入味)。
好处是将类的装饰功能和核心功能分离开。
坏处是如果某一层装饰出了问题,定位的时间会有点长,不清楚是具体哪层。