首頁 > 軟體

Java設計模式中的裝飾者模式

2022-07-19 14:02:51

模式介紹

23種設計模式之一,英文叫Decorator Pattern,又叫裝飾者模式。裝飾模式是在不必改變原類檔案和使用繼承的情況下,動態地擴充套件一個物件的功能。它是通過建立一個包裝物件,也就是裝飾來包裹真實的物件。

UML類圖

類圖解析:

  • Componet:主體
  • ConcreateComponent:主體具體實現類
  • Decorator:裝飾者
  • ConcreteDecorate:裝飾者具體實現類

裝飾者模式案例

背景介紹:有一家咖啡店,店中有許多品種的咖啡(ShortBlack、Decaf、Espresso…),咖啡可以新增不同口味(Chocolate、Milk、Soy等),採用裝飾者模式可以很好的解決該問題

裝飾者下單 (2份巧克力+1份牛奶+LangBlack) 如下圖所示:

類結構圖

Drink、Coffee及其子類程式碼如下:

public abstract class Drink {
    private String des;//描述
    private float price = 0.0f;
    /**
     * 計算價格的方法
     * @return
     */
    public abstract float cost();
    public String getDes() {
        return des;
    }
    public void setDes(String des) {
        this.des = des;
    }
    public float getPrice() {
        return price;
    }
    public void setPrice(float price) {
        this.price = price;
    }
}
public class Coffee extends Drink{
    @Override
    public float cost() {
        return super.getPrice();
    }
}
public class ShortBlack extends Coffee{
    public ShortBlack() {
        setDes("濃縮咖啡");
        setPrice(4);
    }
}
public class Espresso extends Coffee{
    public Espresso() {
        setPrice(6);
        setDes("義大利咖啡");
    }
}
public class LongBlack extends Coffee{
    public LongBlack() {
        setPrice(5);
        setDes("美式咖啡");
    }
}

Decorator及其子類

public class Decorator extends Drink {
    private Drink drink;
    public Decorator(Drink drink) { // 聚合
        this.drink = drink;
    }
    @Override
    public float cost() {
        // 調料的價格 + 咖啡的價格
        return super.getPrice() + drink.cost();
    }
    @Override
    public String getDes() {
        return super.getDes() + " && " + drink.getDes();
    }
}
public class Chocolate extends Decorator{
    public Chocolate(Drink drink) {
        super(drink);
        setDes("巧克力");
        setPrice(3);
    }
}
public class Milk extends Decorator{
    public Milk(Drink drink) {
        super(drink);
        setDes("牛奶");
        setPrice(2);
    }
}
public class Soy extends Decorator{
    public Soy(Drink drink) {
        super(drink);
        setDes("豆漿");
        setPrice(1.5f);
    }
}

CoffeeBar測試類

public class CoffeeBar {
    public static void main(String[] args) {
        // 點一份咖啡
        Drink order = new LongBlack();
        System.out.println(order.cost() + "$t" + order.getDes());

        // 加一份牛奶
        order = new Milk(order);
        System.out.println(order.cost() + "$t" + order.getDes());

        // 加兩份巧克力
        order = new Chocolate(order);
        System.out.println(order.cost() + "$t" + order.getDes());
        order = new Chocolate(order);
        System.out.println(order.cost() + "$t" + order.getDes());
    }
}

實現結果:

裝飾者模式優點

  • Decorator模式與繼承關係的目的都是要擴充套件物件的功能,但是Decorator可以提供比繼承更多的靈活性。
  • 通過使用不同的具體裝飾類以及這些裝飾類的排列組合,設計師可以創造出很多不同行為的組合。

裝飾者模式缺點

  • 這種比繼承更加靈活機動的特性,也同時意味著更加多的複雜性。
  • 裝飾模式會導致設計中出現許多小類,如果過度使用,會使程式變得很複雜。
  • 裝飾模式是針對抽象元件(Component)型別程式設計。但是,如果你要針對具體元件程式設計時,就應該重新思考你的應用架構,以及裝飾者是否合適。當然也可以改變Component介面,增加新的公開的行為,實現“半透明”的裝飾者模式。在實際專案中要做出最佳選擇。

到此這篇關於Java設計模式中的裝飾者模式的文章就介紹到這了,更多相關Java裝飾者模式內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com