Java設計模式之裝飾者模式
先考慮這樣一個生活場景,煎餅攤前面有三個人餓了要買煎餅,第一個只要煎餅,第二個煎餅加雞蛋,第三個煎餅加雞蛋加香腸。下面看代碼實現。
//新建一個類 煎餅
public class Battercake {
public String getDesc(){
return "煎餅";
}
public int price(){
return 5;
}
}
//新建類 煎餅 加雞蛋
public class BattercakeWithEgg extends Battercake {
@Override
public String getDesc() {
return super.getDesc() +" 加一個雞蛋";
}
@Override
public int price() {
return super.price() + 1;
}
}
//新建類 煎餅 加雞蛋 加香腸
public class BattercakeWithEggSausage extends BattercakeWithEgg {
@Override
public String getDesc() {
return super.getDesc() +" 加一根香腸";
}
@Override
public int price() {
return super.price() + 2;
}
}
//調用
public static void main(String [] a){
Battercake battercake=new Battercake();
System.out.println(battercake.getDesc()+";價格:"+battercake.price());
Battercake battercake2=new BattercakeWithEgg();
System.out.println(battercake2.getDesc()+";價格:"+battercake2.price());
Battercake battercake3=new BattercakeWithEggSausage();
System.out.println(battercake3.getDesc()+";價格:"+battercake3.price());
}
//結果
煎餅;價格:5
煎餅 加一個雞蛋;價格:6
煎餅 加一個雞蛋 加一根香腸;價格:8
看一下UML的類圖:
現在如果來了第四個人想買煎餅加2個蛋一根香腸或者煎餅加1個蛋兩根香腸呢?再考慮其他的組合呢?此時代碼的擴展性很差,很容易導致類爆炸。
下面看看裝飾者模式怎麼優雅的應對這種局面。
抽象的實體類,確定的實體類,抽象的裝飾者,確定的裝飾者。被裝飾者是煎餅,裝飾者是雞蛋和香腸。
//抽象的煎餅
public abstract class ABattercake {
public abstract String getDesc();
public abstract int price();
}
//實體的煎餅
public class Battercake extends ABattercake{
@Override
public String getDesc() {
return "煎餅";
}
@Override
public int price() {
return 5;
}
}
//抽象的裝飾者繼承抽象的煎餅
public class ADecorator extends ABattercake{
private ABattercake aBattercake;
//把要被裝飾的抽象類作爲構造的入參
public ADecorator(ABattercake aBattercake) {
this.aBattercake = aBattercake;
}
@Override
public String getDesc() {
return this.aBattercake.getDesc();
}
@Override
public int price() {
return this.aBattercake.price();
}
}
//雞蛋 實體裝飾者
public class EggDecorator extends ADecorator{
public EggDecorator(ABattercake aBattercake) {
super(aBattercake);
}
@Override
public String getDesc() {
return super.getDesc()+" 加一個雞蛋";
}
@Override
public int price() {
return super.price() + 1;
}
}
//香腸 實體裝飾者
public class SuasageDecorator extends ADecorator{
public SuasageDecorator(ABattercake aBattercake) {
super(aBattercake);
}
@Override
public String getDesc() {
return super.getDesc()+" 加一根香腸";
}
@Override
public int price() {
return super.price() + 2;
}
}
//調用
public static void main(String [] a){
ABattercake aBattercake;
aBattercake=new Battercake();
aBattercake=new EggDecorator(aBattercake);
aBattercake=new EggDecorator(aBattercake);
aBattercake=new SuasageDecorator(aBattercake);
System.out.println(aBattercake.getDesc()+"; 價格:"+aBattercake.price());
}
//結果
煎餅 加一個雞蛋 加一個雞蛋 加一根香腸; 價格:9
看看此時UML的類圖: