日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

結(jié)構(gòu)型設(shè)計(jì)模式 - 裝飾者模式詳解

 頭號(hào)碼甲 2021-07-20

基本定義

裝飾者模式屬于結(jié)構(gòu)型模式,它可以動(dòng)態(tài)的將新功能附加到對(duì)象上,同時(shí)又不改變其結(jié)構(gòu)。在對(duì)象功能擴(kuò)展方面,它比繼承更有彈性,裝飾者模式也體現(xiàn)了開閉原則(OCP)。

模式結(jié)構(gòu)

裝飾者和被裝飾者有相同的超類型,因?yàn)檠b飾者和被裝飾者必須是一樣的類型,利用繼承是為了達(dá)到類型的匹配,而不是利用繼承獲取行為

  • Component:裝飾者和被裝飾者共同的父類,是一個(gè)接口或者抽象類,用來定義基本行為

  • ConcreteComponent:定義具體對(duì)象,即被裝飾者

  • Decorator:抽象裝飾者,繼承自 Component,從外類來擴(kuò)展 ConcreteComponent。對(duì)于 ConcreteComponent來說,不需要知道Decorator的存在,Decorator 是一個(gè)接口或抽象類

  • ConcreteDecorator:具體裝飾者,用于擴(kuò)展 ConcreteComponent

舉例說明

在咖啡店客人想點(diǎn)一杯加兩份糖一份牛奶的摩卡咖啡,各個(gè)商品的價(jià)格如下,我們需要根據(jù)用戶點(diǎn)的咖啡、加的配料,動(dòng)態(tài)的計(jì)算價(jià)格

商品價(jià)格
拿鐵咖啡(LatteCoffee)4.5
摩卡咖啡(MochaCoffe)5.5
糖(Sugar)1.0
牛奶(Milk)2.0

「實(shí)體類」 Coffee

public abstract class Coffee{
    public String des = "咖啡"; //描述
    private float price = 0.0f; //價(jià)格

    protected abstract float cost(); //計(jì)算費(fèi)用
    
    //省略getter setter方法
}

「被裝飾者」LatteCoffee

public class LatteCoffee extends Coffee{
    public LatteCoffee() {
        setDes("拿鐵咖啡");
        setPrice(4.5f);
    }

    @Override
    protected float cost() {
        return getPrice();
    }
}

「被裝飾者」MochaCoffee

public class MochaCoffee extends Coffee {
    public MochaCoffee() {
        setDes("摩卡咖啡");
        setPrice(5.5f);
    }

    @Override
    protected float cost() {
        return getPrice();
    }
}

「抽象裝飾者」Decorator

public class Decorator extends Coffee {

    private Coffee coffee;

    public Decorator(Coffee drink) {
        this.coffee = drink;
    }

    @Override
    protected float cost() {
        return getPrice() + coffee.cost();
    }

    @Override
    public String getDes() {
        return coffee.getDes() + "加" + super.getDes();
    }
}

「具體裝飾者」SugarDecorator

public class SugarDecorator extends Decorator{
    public SugarDecorator(Coffee coffee) {
        super(coffee);
        setDes("糖");
        setPrice(1.0f);
    }
}

「具體裝飾者」MilkDecorator

public class MilkDecorator extends Decorator{
    public MilkDecorator(Coffee coffee) {
        super(coffee);
        setDes("牛奶");
        setPrice(2.0f);
    }
}

「測(cè)試類」Client

public class Client {
    /**
     * 點(diǎn)一杯 加兩份糖一份牛奶的摩卡咖啡
     */
    @Test
    public void test01() {
        Coffee order = new MochaCoffee();
        System.out.println(order.getDes() + ",價(jià)格:" + order.cost());
        //加兩份糖
        order = new SugarDecorator(new SugarDecorator(order));
        System.out.println(order.getDes() + ",價(jià)格:" + order.cost());
        //加一份牛奶
        order = new MilkDecorator(order);
        System.out.println(order.getDes() + ",價(jià)格:" + order.cost());
    }
}

「結(jié)果」result

摩卡咖啡,價(jià)格:5.5
摩卡咖啡加糖加糖,價(jià)格:7.5
摩卡咖啡加糖加糖加牛奶,價(jià)格:9.5

在 Java IO 流中的應(yīng)用

在上圖所示的關(guān)系中

  • 實(shí)體類是 InputStream

  • 被裝飾者是FileInputStream、StringBufferInputStream、ByteArrayInputStream

  • 抽象裝飾者是FilterInputStream

  • 具體裝飾者是BufferInputStream、DataInputStream、LineNumberInputStream

具體使用如下:

BufferedInputStream bis = new BufferedInputStream(new FileInputStream("G:\\a.txt"));

裝飾者模式總結(jié)

1、利用繼承設(shè)計(jì)子類,只能在編譯時(shí)靜態(tài)決定,并且所有子類都會(huì)繼承相同的行為;利用組合擴(kuò)展對(duì)象,就可以在運(yùn)行時(shí)動(dòng)態(tài)的進(jìn)行擴(kuò)展。

2、裝飾者和被裝飾者對(duì)象有相同的超類型,所以在任何需要原始對(duì)象(被裝飾者)的場(chǎng)合,都可以用裝飾過的對(duì)象代替原始對(duì)象。

3、可以用一個(gè)或多個(gè)裝飾者包裝一個(gè)對(duì)象(被裝飾者)。

4、裝飾者可以在所委托的裝飾者行為之前或之后加上自己的行為,以達(dá)到特定的目的。

5、被裝飾者可以在任何時(shí)候被裝飾,所以可以在運(yùn)行時(shí)動(dòng)態(tài)地、不限量地用你喜歡的裝飾者來裝飾對(duì)象。

6、裝飾者會(huì)導(dǎo)致出現(xiàn)很多小對(duì)象,如果過度使用,會(huì)讓程序變得復(fù)雜。


    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多