成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

Java設(shè)計(jì)模式之裝飾模式詳解

sewerganger / 2457人閱讀

摘要:裝飾者模式是動(dòng)態(tài)地將責(zé)任附加到對(duì)象上。然后我們?cè)谧宇愑?jì)算價(jià)格的時(shí)候加上父類中計(jì)算好的配料的價(jià)格。結(jié)果可樂加冰可樂加冰加糖在的類庫(kù)中就有很多實(shí)際應(yīng)用到了裝飾模式,比如就可以用來裝飾,提供更加強(qiáng)大的功能。

裝飾者模式是動(dòng)態(tài)地將責(zé)任附加到對(duì)象上。若要擴(kuò)展功能,裝飾者提供了比繼承更有彈性的替代方案。

假設(shè)我們有一個(gè)需求,是給一家飲料店做一個(gè)計(jì)算各種飲料價(jià)格的功能。聽起來很簡(jiǎn)單,我們創(chuàng)建一個(gè)抽象父類Beverages,description用來描述飲料名字,price方法用來計(jì)算飲料的價(jià)格。

public abstract class Beverages {
    private String description;

    public String getDescription() {
        return description;
    }

    public abstract double price();
}

每種飲料我們都創(chuàng)建一個(gè)子類去繼承父類,賦值給description,并且重寫price方法來設(shè)置自己的價(jià)格??瓷先ズ芡昝?,我們運(yùn)行一下看看結(jié)果。

public class Coffee extends Beverages {

    public Coffee(String description){
        this.description = description;
    }

    @Override
    public String getDescription() {
        return description;
    }

    @Override
    public double price() {
        return 3.5;
    }
}

public static void main(String[] args){
    Coffee coffee = new Coffee("咖啡");
    System.out.println(coffee.getDescription());
    System.out.println(coffee.price());
}

結(jié)果:
咖啡
3.5

但是問題來了,飲料店里不僅僅只有一種飲料,還有可樂、七喜、奶茶其他各種各樣的飲料,難道我們要每個(gè)都創(chuàng)建一個(gè)子類嗎?好吧,就算你覺得幾十種飲料還不算多,那如果各種飲料直接再進(jìn)行搭配呢?咖啡加牛奶、咖啡加巧克力、加糖、不加糖,因?yàn)楦鞣N配料的不同價(jià)格和描述也不同,我的天呀,難道要?jiǎng)?chuàng)建幾百個(gè)類嗎?這個(gè)時(shí)候我們突然想到了不是可以用繼承來解決這個(gè)問題嗎?那我們就來試一下。

我們改造一下Beverages類,把要加的配料用boolean值聲明,如果需要添加配料就調(diào)用set方法設(shè)置為true,在price方法中計(jì)算的時(shí)候來判斷哪一些配料添加了需要計(jì)算價(jià)格。

public class Beverages {
    public String description;

    public boolean milk;
    public boolean sugar;

    public double milkPrice = 1.5;
    public double sugarPrice = 0.5;

    public boolean isMilk() {
        return milk;
    }

    public void setMilk(boolean milk) {
        this.milk = milk;
    }

    public boolean isSugar() {
        return sugar;
    }

    public void setSugar(boolean sugar) {
        this.sugar = sugar;
    }

    public String getDescription() {
        return description;
    }

    public double price(){
        double basePrice = 0.0;
        if (isMilk()){
            basePrice += milkPrice;
        }
        if (isSugar()){
            basePrice += sugarPrice;
        }
        return basePrice;
    }
}

然后我們?cè)谧宇愑?jì)算價(jià)格的時(shí)候加上父類中計(jì)算好的配料的價(jià)格。

public class CoffeeWithMilk extends Beverages {

    public CoffeeWithMilk(String description){
        this.description = description;
    }

    @Override
    public double price() {
        return 3.0 + super.price();
    }
}

我們運(yùn)行看一下,咖啡加牛奶加糖,結(jié)果沒有問題。

CoffeeWithMilk coffeeWithMilk = new CoffeeWithMilk("咖啡加牛奶加糖");
coffeeWithMilk.setMilk(true);
coffeeWithMilk.setSugar(true);
System.out.println(coffeeWithMilk.getDescription());
System.out.println(coffeeWithMilk.price());

結(jié)果:
咖啡加牛奶加糖
5.0

這樣一來我們解決了新建無數(shù)個(gè)子類的問題,但是我們發(fā)現(xiàn)單純繼承的做法還是有太多弊端,比如說如果我們想要新添加配料,我們得修改在父類Beverages中添加新的調(diào)料字段,還要修改price方法,這嚴(yán)重違反了開發(fā)-關(guān)閉的設(shè)計(jì)原則,類應(yīng)該對(duì)擴(kuò)展開發(fā),對(duì)修改關(guān)閉。而且有些飲料和配料是沒辦法搭配的,例如啤酒加糖,但是子類還是會(huì)繼承到這些配料,并且如果是要同一份配料要加雙份又該怎么改呢?所以單純繼承的方法還是不行。這時(shí)候我們就要使用到裝飾者模式。

首先我們創(chuàng)建抽象父類Beverages,這個(gè)父類只是飲料的父類,不是配料的父類。我們創(chuàng)建一個(gè)Cola類直接繼承它。

public abstract class Beverages {
    public String description;

    public String getDescription() {
        return description;
    }

    public abstract double price();
}

public class Cola extends Beverages {

    public Cola(String description) {
        this.description = description;
    }

    @Override
    public double price() {
        return 2.0;
    }
}

現(xiàn)在就缺配料的部分的代碼了,我們?cè)賱?chuàng)建一個(gè)配料的抽象類Seasonings,我們讓它繼承Berverages類,并且聲明了一個(gè)Berverages的引用和抽象的getDescription方法,這里我們稍后再作解釋。

public abstract class Seasonings extends Beverages{
    public Beverages beverages;
    public abstract String  getDescription();
}

接下來我們看看配料的實(shí)現(xiàn)類怎么寫。我們讓他繼承了父類Seasonings,構(gòu)造函數(shù)接收父類Beverages類型,其實(shí)也就是要被裝飾的對(duì)象,也就是各種各樣需要加配料的飲料。然后我們重寫了getDescription,我們?cè)趥鬟M(jìn)來的那個(gè)Beverages對(duì)象的基礎(chǔ)上添加名字,price方法也是同理。這樣其實(shí)就在給傳進(jìn)來的對(duì)象外面做了一層裝飾,也就是給飲料添加了配料。

public class Ice extends Seasonings {

    public Ice(Beverages beverages) {
        this.beverages = beverages;
    }

    @Override
    public String getDescription() {
        return beverages.getDescription() + "加冰";
    }

    @Override
    public double price() {
        return beverages.price() + 0.2;
    }
}

運(yùn)行一下,看看結(jié)果。沒有問題,可以搭配成功。

Cola cola = new Cola("可樂");

Beverages ice = new Ice(cola);
System.out.println(ice.getDescription());
System.out.println(ice.price());

結(jié)果:
可樂加冰
2.2

我們還想再添加別的配料,再創(chuàng)建一個(gè)新的配料。

public class Sugar extends Seasonings {

    public Sugar(Beverages beverages) {
        this.beverages = beverages;
    }

    @Override
    public String getDescription() {
        return beverages.getDescription() + "加糖";
    }

    @Override
    public double price() {
        return 0.5 + beverages.price();
    }
}

我們?cè)谠瓉泶钆浜玫幕A(chǔ)上再進(jìn)行裝飾,結(jié)果也是沒有問題的。這個(gè)時(shí)候就要提到為什么我們的Seasonings類要繼承Beverages類了,因?yàn)槊總€(gè)配料的實(shí)現(xiàn)類里有一個(gè)Beverages類型的引用,這樣我們才可以對(duì)它的子類進(jìn)行裝飾,我們讓Seasonings也繼承Beverages那它的子類也是Beverages類型,我們就可以想裝飾幾層就裝飾幾層。

Beverages ice = new Ice(cola);
System.out.println(ice.getDescription());
System.out.println(ice.price());

Beverages sugar = new Sugar(ice);
System.out.println(sugar.getDescription());
System.out.println(sugar.price());

結(jié)果:
可樂加冰
2.2
可樂加冰加糖
2.7

在Java的類庫(kù)中就有很多實(shí)際應(yīng)用到了裝飾模式,比如BufferedInputStream就可以用來裝飾FileInputStream,提供更加強(qiáng)大的功能。

總結(jié):
裝飾模式就是裝飾者和被裝飾者都具有相同的超類,裝飾者拿到被裝飾者的引用之后,在調(diào)用被裝飾者的方法的同時(shí)再加上自己的新功能,從而實(shí)現(xiàn)了功能的增加,也不需要修改原來的代碼。而且因?yàn)槭窍嗤某?,所以可以裝飾很多層。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/69053.html

相關(guān)文章

  • Java 設(shè)計(jì)模式裝飾模式

    摘要:裝飾者模式組成結(jié)構(gòu)抽象構(gòu)件給出抽象接口或抽象類,以規(guī)范準(zhǔn)備接收附加功能的對(duì)象。裝飾者模式圖解裝飾者模式應(yīng)用場(chǎng)景需要擴(kuò)展一個(gè)類的功能,或給一個(gè)類添加附加職責(zé)。裝飾者對(duì)象接受所有來自客戶端的請(qǐng)求。參考資料設(shè)計(jì)模式 一、了解裝飾者模式 1.1 什么是裝飾者模式 裝飾者模式指的是在不必改變?cè)愇募褪褂美^承的情況下,動(dòng)態(tài)地?cái)U(kuò)展一個(gè)對(duì)象的功能。它是通過創(chuàng)建一個(gè)包裝對(duì)象,也就是裝飾者來包裹真實(shí)的對(duì)...

    kumfo 評(píng)論0 收藏0
  • 設(shè)計(jì)模式裝飾模式

    摘要:于是乎,老李家去車行把車進(jìn)行了改裝,車速上去了,媳婦也領(lǐng)到了,皆大歡喜這其實(shí)就是一個(gè)裝飾器的使用案例,原來的車已經(jīng)沒法滿足了,所以進(jìn)行了速度增強(qiáng),其他功能并沒有改變。 裝飾器設(shè)計(jì)模式的概念 在實(shí)際生產(chǎn)中,某個(gè)類的行為(它所提供的方法)已經(jīng)沒法滿足當(dāng)前的需要了,但是又需要使用原有的部分功能,因此需要對(duì)原有對(duì)象進(jìn)行增強(qiáng)——裝飾器設(shè)計(jì)模式(Decorator Pattern)也叫包裝器模式就...

    30e8336b8229 評(píng)論0 收藏0
  • Java學(xué)習(xí)路線總結(jié),搬磚工逆襲Java架構(gòu)師(全網(wǎng)最強(qiáng))

    摘要:哪吒社區(qū)技能樹打卡打卡貼函數(shù)式接口簡(jiǎn)介領(lǐng)域優(yōu)質(zhì)創(chuàng)作者哪吒公眾號(hào)作者架構(gòu)師奮斗者掃描主頁左側(cè)二維碼,加入群聊,一起學(xué)習(xí)一起進(jìn)步歡迎點(diǎn)贊收藏留言前情提要無意間聽到領(lǐng)導(dǎo)們的談話,現(xiàn)在公司的現(xiàn)狀是碼農(nóng)太多,但能獨(dú)立帶隊(duì)的人太少,簡(jiǎn)而言之,不缺干 ? 哪吒社區(qū)Java技能樹打卡?【打卡貼 day2...

    Scorpion 評(píng)論0 收藏0
  • 「碼個(gè)蛋」2017年200篇精選干貨集合

    摘要:讓你收獲滿滿碼個(gè)蛋從年月日推送第篇文章一年過去了已累積推文近篇文章,本文為年度精選,共計(jì)篇,按照類別整理便于讀者主題閱讀。本篇文章是今年的最后一篇技術(shù)文章,為了讓大家在家也能好好學(xué)習(xí),特此花了幾個(gè)小時(shí)整理了這些文章。 showImg(https://segmentfault.com/img/remote/1460000013241596); 讓你收獲滿滿! 碼個(gè)蛋從2017年02月20...

    wangtdgoodluck 評(píng)論0 收藏0
  • 設(shè)計(jì)模式裝飾模式

    摘要:相關(guān)設(shè)計(jì)模式裝飾者模式和代理模式裝飾者模式關(guān)注再一個(gè)對(duì)象上動(dòng)態(tài)添加方法代理模式關(guān)注再對(duì)代理對(duì)象的控制訪問,可以對(duì)客戶隱藏被代理類的信息裝飾著模式和適配器模式都叫包裝模式關(guān)于新職責(zé)適配器也可以在轉(zhuǎn)換時(shí)增加新的職責(zé),但主要目的不在此。 0x01.定義與類型 定義:裝飾模式指的是在不必改變?cè)愇募褪褂美^承的情況下,動(dòng)態(tài)地?cái)U(kuò)展一個(gè)對(duì)象的功能。它是通過創(chuàng)建一個(gè)包裝對(duì)象,也就是裝飾來包裹真實(shí)的...

    chuyao 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<