最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java設(shè)計(jì)模式-裝飾者模式詳解

 更新時(shí)間:2021年07月19日 17:02:08   作者:吾仄lo咚鏘  
這篇文章主要介紹了Java設(shè)計(jì)模式之裝飾者模式詳解和代碼實(shí)例,Decorator模式(別名Wrapper):動(dòng)態(tài)將職責(zé)附加到對(duì)象上,若要擴(kuò)展功能,裝飾者提供了比繼承更具彈性的代替方案,需要的朋友可以參考下

引例

需求:設(shè)現(xiàn)在有單品咖啡:Espresso(意大利濃咖啡)和LongBlack(美式咖啡),調(diào)料有Milk(牛奶)和sugar(糖),客戶可以點(diǎn)單品咖啡或單品咖啡+調(diào)料的組合,計(jì)算相應(yīng)費(fèi)用。要求在擴(kuò)展新的咖啡種類時(shí),具有良好的擴(kuò)展性、改動(dòng)維護(hù)方便。

拋磚引玉,我們先看看兩種一般解法。

一般解法

方案一、

枚舉創(chuàng)建每一種組合可能,Drink抽象類表示飲料,cost()方法計(jì)算價(jià)格,子類如Longblack_Milk表示美式咖啡加牛奶:

在這里插入圖片描述

這樣設(shè)計(jì)十分不明智,會(huì)有很多類,當(dāng)新增一個(gè)單品咖啡或調(diào)料時(shí),類的數(shù)量就會(huì)倍增,出現(xiàn)類爆炸。

方案二、

把調(diào)料內(nèi)置到Drink類,減少類數(shù)量過多:

在這里插入圖片描述

方案二雖然不至于造成很多類,但是增加或刪除調(diào)料時(shí),代碼維護(hù)量仍舊很大。

裝飾者模式

裝飾者模式(Decorator Pattern)是結(jié)構(gòu)型模式,也稱裝飾器模式/修飾模式。它可以動(dòng)態(tài)的將新功能附加到對(duì)象上,同時(shí)又不改變其結(jié)構(gòu)。在對(duì)象功能擴(kuò)展方面,它比繼承更有彈性。這種模式創(chuàng)建了一個(gè)裝飾類,用來包裝原有的類,并在保持類方法簽名完整性的前提下,提供了額外的功能。

類圖:

在這里插入圖片描述

  1. Component抽象類:主體,比如類似前面的Drink。
  2. ConcreteComponent類:具體的主體,比如前面的單品咖啡。
  3. Decorator類:裝飾者,比如前面的調(diào)料
  4. ConcreteDecorator類:具體的裝飾者,比如前面的牛奶。

如果ConcreteComponent具體子類很多,那么可以再加一個(gè)中間層,提取共同部分,通過繼承實(shí)現(xiàn)更多不同的具體子類。

裝飾者解法

類圖:

在這里插入圖片描述

Drink 類就是前面說的抽象類Decorator 是一個(gè)裝飾類,含有一個(gè)被裝飾的對(duì)象(Drink obj)和的cost()方法進(jìn)行一個(gè)費(fèi)用的疊加計(jì)算,遞歸的計(jì)算價(jià)格Milk和Suger是具體的裝飾者Coffee是被裝飾者主體LongBlack和Espresso是具體實(shí)現(xiàn)的被裝飾者實(shí)體

代碼:

抽象類

public abstract class Drink {//抽象類
    public String des; // 描述
    private float price = 0.0f;
    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;
    }
    //計(jì)算費(fèi)用的抽象方法
    public abstract float cost();
}

裝飾者

public class Decorator extends Drink {//裝飾者
    private Drink obj;
    public Decorator(Drink obj) { //組合
        this.obj = obj;
    }
    @Override
    public float cost() {
        // getPrice 自己價(jià)格
        return super.getPrice() + obj.cost();
    }
    @Override
    public String getDes() {
        // obj.getDes() 輸出被裝飾者的信息
        return des + " " + getPrice() + " && " + obj.getDes();
    }
}
public class Milk extends Decorator {//裝飾者子類
    public Milk(Drink obj) {
        super(obj);
        setDes(" 牛奶 ");
        setPrice(2.0f);
    }
}
public class Suger extends Decorator {//裝飾者子類
    public Suger(Drink obj) {
        super(obj);
        setDes(" 糖 ");
        setPrice(1.0f);
    }
}

被裝飾者

public class Coffee  extends Drink {//被裝飾者
    @Override
    public float cost() {
        return super.getPrice();
    }
}
public class Espresso extends Coffee {//被裝飾者子類
    public Espresso() {
        setDes(" 意式咖啡 ");
        setPrice(6.0f);
    }
}
public class LongBlack extends Coffee {//被裝飾者子類
    public LongBlack() {
        setDes(" 美式咖啡 ");
        setPrice(5.0f);
    }
}

客戶端測(cè)試

public class Client {
    public static void main(String[] args) {
        // 阿姨的卡布奇諾:意式加兩份牛奶、一份糖
        // 1. 點(diǎn)一份Espresso
        Drink order = new Espresso();
        System.out.println("order1 費(fèi)用=" + order.cost());
        System.out.println("order1 描述=" + order.getDes());
        // 2.1 order 加一份牛奶
        order = new Milk(order);
        System.out.println("order 加入一份牛奶 費(fèi)用 =" + order.cost());
        System.out.println("order 加入一份牛奶 描述 = " + order.getDes());
        // 2.2 order 再加一份牛奶
        order = new Milk(order);
        System.out.println("order 加入兩份牛奶 費(fèi)用 =" + order.cost());
        System.out.println("order 加入兩份牛奶 描述 = " + order.getDes());
        // 3. order 加一份糖
        order = new Suger(order);
        System.out.println("order 兩份牛奶、一份糖 費(fèi)用 =" + order.cost());
        System.out.println("order 兩份牛奶、一份糖 描述 = " + order.getDes());
        System.out.println("===========================");
        //美式咖啡加一份牛奶
        //1. 點(diǎn)一份LongBlack
        Drink order2 = new LongBlack();
        System.out.println("order2 費(fèi)用 =" + order2.cost());
        System.out.println("order2 描述 = " + order2.getDes());
        //2. order2 加一份牛奶
        order2 = new Milk(order2);
        System.out.println("order2 加入一份牛奶 費(fèi)用 =" + order2.cost());
        System.out.println("order2 加入一份牛奶 描述 = " + order2.getDes());
    }
}

運(yùn)行結(jié)果:

在這里插入圖片描述

總結(jié):

裝飾者模式就像打包一個(gè)快遞,不斷的動(dòng)態(tài)添加新的功能,可以組合出所有情況:

在這里插入圖片描述

第一份Milk包含一份Espresso

第二份Milk包含(Milk+Espresso)

Suger包含(Milk+Milk+Espresso)

本篇文章就到這里了,希望能給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!

相關(guān)文章

最新評(píng)論

霞浦县| 正阳县| 沂水县| 乌兰县| 广河县| 都匀市| 昌宁县| 白城市| 白城市| 宁乡县| 嘉义县| 长宁区| 西畴县| 潮州市| 汾阳市| 惠东县| 名山县| 涞源县| 呼图壁县| 中卫市| 伊金霍洛旗| 天峻县| 崇文区| 洞口县| 兴宁市| 周至县| 鹤庆县| 昭觉县| 淮安市| 尼木县| 塘沽区| 桐柏县| 贵定县| 余庆县| 茂名市| 松潘县| 子洲县| 湖南省| 南澳县| 南安市| 通城县|