国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

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

kumfo / 838人閱讀

摘要:裝飾者模式組成結(jié)構(gòu)抽象構(gòu)件給出抽象接口或抽象類,以規(guī)范準(zhǔn)備接收附加功能的對(duì)象。裝飾者模式圖解裝飾者模式應(yīng)用場(chǎng)景需要擴(kuò)展一個(gè)類的功能,或給一個(gè)類添加附加職責(zé)。裝飾者對(duì)象接受所有來(lái)自客戶端的請(qǐng)求。參考資料設(shè)計(jì)模式

一、了解裝飾者模式

1.1 什么是裝飾者模式

裝飾者模式指的是在不必改變?cè)愇募褪褂美^承的情況下,動(dòng)態(tài)地?cái)U(kuò)展一個(gè)對(duì)象的功能。它是通過(guò)創(chuàng)建一個(gè)包裝對(duì)象,也就是裝飾者來(lái)包裹真實(shí)的對(duì)象。

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

1.2 裝飾者模式組成結(jié)構(gòu)

抽象構(gòu)件 (Component):給出抽象接口或抽象類,以規(guī)范準(zhǔn)備接收附加功能的對(duì)象。

具體構(gòu)件 (ConcreteComponent):定義將要接收附加功能的類。

抽象裝飾 (Decorator):裝飾者共同要實(shí)現(xiàn)的接口,也可以是抽象類。

具體裝飾 (ConcreteDecorator):持有一個(gè) Component 對(duì)象,負(fù)責(zé)給構(gòu)件對(duì)象“貼上”附加的功能。

1.3 裝飾者模式 UML 圖解

1.4 裝飾者模式應(yīng)用場(chǎng)景

需要擴(kuò)展一個(gè)類的功能,或給一個(gè)類添加附加職責(zé)。

需要?jiǎng)討B(tài)的給一個(gè)對(duì)象添加功能,這些功能可以再動(dòng)態(tài)的撤銷。

需要增加由一些基本功能的排列組合而產(chǎn)生的非常大量的功能,從而使繼承關(guān)系變的不現(xiàn)實(shí)。

當(dāng)不能采用生成子類的方法進(jìn)行擴(kuò)充時(shí)。可能有大量獨(dú)立的擴(kuò)展,為支持每一種組合將產(chǎn)生大量的子類,使得子類數(shù)目呈爆炸性增長(zhǎng)。

1.5 裝飾者模式特點(diǎn)

裝飾者對(duì)象和具體構(gòu)件有相同的接口。這樣客戶端對(duì)象就能以和真實(shí)對(duì)象相同的方式和裝飾對(duì)象交互。

裝飾者對(duì)象包含一個(gè)具體構(gòu)件的引用(reference)。

裝飾者對(duì)象接受所有來(lái)自客戶端的請(qǐng)求。它把這些請(qǐng)求轉(zhuǎn)發(fā)給具體構(gòu)件。

裝飾者對(duì)象可以在轉(zhuǎn)發(fā)這些請(qǐng)求以前或以后動(dòng)態(tài)增加一些功能。

二、裝飾者模式具體應(yīng)用

2.1 問(wèn)題描述

星巴茲咖啡訂單系統(tǒng):星巴茲店提供了各式各樣的咖啡,以及各種咖啡調(diào)料。為了適應(yīng)飲料需求供應(yīng),所以讓你設(shè)計(jì)一個(gè)更新訂單系統(tǒng)。

2.2 使用繼承


在購(gòu)買(mǎi)咖啡時(shí),可以要求在咖啡中添加各種調(diào)料,例如:豆?jié){ (Soy)、摩卡 (Mocha)、奶泡等。由于各種調(diào)料的價(jià)格不相同,所以訂單系統(tǒng)必須要考慮這些因素。于是就有了下面的嘗試

2.3 繼承類圖

這還只是列出了一部分的類,這簡(jiǎn)直是類爆炸,可以看出這樣做顯然是不行的。所以我們要慎用繼承,盡量用組合和委托。

2.4 裝飾者模式登場(chǎng)

裝飾者模式涉及到的一個(gè)重要的設(shè)計(jì)原則 (當(dāng)然還涉及到了其他的設(shè)計(jì)原則,比如多用組合,少用繼承等):類應(yīng)該對(duì)擴(kuò)展開(kāi)放,對(duì)修改關(guān)閉。

在設(shè)計(jì)過(guò)程中,我們?cè)试S類容易擴(kuò)展,在不修改原有代碼的情況下,就可以擴(kuò)展新的行為。這樣的設(shè)計(jì)具有彈性可以應(yīng)對(duì)改變,可以接受新的功能來(lái)應(yīng)對(duì)新的需求。

將裝飾者模式應(yīng)用到問(wèn)題中去:假如我們想要摩卡和豆?jié){深焙咖啡,那么,要做的是:

拿一個(gè)深焙咖啡 (DarkRoast) 對(duì)象

以摩卡 (Mocha) 裝飾它

以豆?jié){ (Soy) 裝飾它

調(diào)用 cost() 方法,并依賴委托將調(diào)料的價(jià)錢(qián)加上去

(1) 裝飾者模式設(shè)計(jì)圖

(2)代碼實(shí)現(xiàn)

飲料 Beverage 抽象類 (抽象構(gòu)件)

package com.jas.decorator;

public abstract class Beverage {
    String description = "Unknown Beverage";

    public String getDescription() {
        return description;
    }
    
    public abstract double cost();
}

濃咖啡 Espresso 類 (具體構(gòu)件)

package com.jas.decorator;

public class Espresso extends Beverage {
    public Espresso(){
        description = "Espresso ";
    }
    
    @Override
    public double cost() {
        return 1.99;
    }
}

黑咖啡 HouseBlend 類 (具體構(gòu)件)

package com.jas.decorator;

public class HouseBlend extends Beverage {
    public HouseBlend(){
        description = "House Blend Coffee ";
    }
    
    @Override
    public double cost() {
        return 0.80;
    }
}

調(diào)料 CondimentDecorator 抽象類 (抽象裝飾構(gòu)件)

package com.jas.decorator;

public abstract class CondimentDecorator extends Beverage{
    @Override
    public abstract String getDescription();
}

摩卡 Mocha 類 (具體裝飾構(gòu)件)

package com.jas.decorator;

public class Mocha extends CondimentDecorator {
    private Beverage beverage = null;    //用一個(gè)實(shí)例變量來(lái)記錄飲料,也就是被裝飾者
    
    public Mocha(Beverage beverage){
        this.beverage = beverage;    //通過(guò)構(gòu)造函數(shù)將被裝飾者實(shí)例化
    }
    
    @Override
    public String getDescription() {
        return beverage.getDescription() + ", Mocha ";    //用來(lái)加上調(diào)料,一起描述飲料
    }

    @Override
    public double cost() {
        return 0.2 + beverage.cost();    //計(jì)算摩卡飲料的價(jià)錢(qián),為摩卡價(jià)錢(qián) + 飲料價(jià)錢(qián)
    }
}

豆?jié){ Soy 類 (具體裝飾構(gòu)件)

package com.jas.decorator;

public class Soy extends CondimentDecorator {
    private Beverage beverage = null;
    
    public Soy(Beverage beverage){
        this.beverage = beverage;
    }
    
    @Override
    public String getDescription() {
        return beverage.getDescription() + ", Soy ";
    }

    @Override
    public double cost() {
        return 0.1 + beverage.cost();
    }
}

測(cè)試代碼 StarbuzzCoffee

package com.jas.decorator;

public class StarbuzzCoffee {
    public static void main(String[] args) {
        
        //簡(jiǎn)單要一杯濃咖啡
        Beverage beverage1 = new Espresso();
        System.out.println(beverage1.getDescription() + "$" +  beverage1.cost());
        
        //兩份摩卡加一份豆?jié){的濃咖啡
        Beverage beverage2 = new Espresso();
        beverage2 = new Mocha(beverage2);
        beverage2 = new Mocha(beverage2);
        beverage2 = new Soy(beverage2);
        System.out.println(beverage2.getDescription() + "$" + beverage2.cost());
        
        //一份摩卡加一份豆?jié){的黑咖啡
        Beverage beverage3 = new HouseBlend();
        beverage3 = new Mocha(beverage3);
        beverage3 = new Soy(beverage3);
        System.out.println(beverage3.getDescription() + "$" +  beverage3.cost());
    }
}

    /**
     * 輸出
     * Espresso $1.99
     * Espresso , Mocha , Mocha , Soy $2.49
     * House Blend Coffee , Mocha , Soy $1.1
     */

2.5 裝飾者模式問(wèn)題總結(jié)

裝飾者與被裝飾對(duì)象有相同的超類型 (DarkRoast 與裝飾類 MochaSoy 都繼承自 Beverage(飲料))。

可以使用一個(gè)或多個(gè)裝飾對(duì)象包裝一個(gè)對(duì)象。

因?yàn)檠b飾者與被裝飾者具有相同的超類型,所以在任何需要原始對(duì)象的情況下,都可以用裝飾過(guò)的對(duì)象去代替它。

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

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

三、真實(shí)世界的裝飾者 Java I/O

3.1 了解 Java I/O 裝飾者模式

在了解了裝飾者模式之后,I/O 相關(guān)的類對(duì)你來(lái)說(shuō)就更有意義了,因?yàn)檫@其中很多類都是裝飾者。比如下面相關(guān)的類

裝飾 I/O 類

3.2 自定義 Java I/O 裝飾者

問(wèn)題描述:讀取文件,把輸入流內(nèi)的所有大寫(xiě)字符轉(zhuǎn)為小寫(xiě)。

裝飾者 LowerCaseInputStream

package com.jas.decorator;

import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * 擴(kuò)展 FilterInputStream,這是所有 InputStream 的抽象裝飾者
 */
public class LowerCaseInputStream extends FilterInputStream {
    
    public LowerCaseInputStream(InputStream inputStream){
        super(inputStream);
    }
    
    @Override
    public int read() throws IOException{
        int c = super.read();
        return (c == -1 ? c : Character.toLowerCase((char)c));
    }
    
    @Override
    public int read(byte[] bytes, int offset, int len) throws IOException{
        int result = super.read(bytes, offset, len);
        for (int i = offset; i < offset + result; i++) {
            bytes[i] = (byte) Character.toLowerCase((char)bytes[i]);
        }
        return result;
    }
}

測(cè)試 InputTest

package com.jas.decorator;

import java.io.*;

public class InputTest {
    public static void main(String[] args) {
        
        int c = 0;
        InputStream in = null;

        try {
            //設(shè)置 FileInputStream ,先用 BufferedInputStream 裝飾它,再用 LowerCaseInputStream 進(jìn)行裝飾
            in = new LowerCaseInputStream(
                    new BufferedInputStream(
                            new FileInputStream("test.txt")));
            while ((c = in.read()) >= 0){
                System.out.print((char)c);
            }
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

     /**在文件中為“HELLO WORLD”
     *
     * 輸出
     * hello world
     */
四、裝飾者模式總結(jié)

4.1 裝飾者模式的優(yōu)缺點(diǎn)

優(yōu)點(diǎn)

Decorator 模式與繼承關(guān)系的目的都是要擴(kuò)展對(duì)象的功能,但是 Decorator 可以提供比繼承更多的靈活性。

通過(guò)使用不同的具體裝飾類以及這些裝飾類的排列組合,設(shè)計(jì)者可以創(chuàng)造出很多不同行為的組合。

缺點(diǎn)

這種比繼承更加靈活機(jī)動(dòng)的特性,也同時(shí)意味著更加多的復(fù)雜性。

裝飾模式會(huì)導(dǎo)致設(shè)計(jì)中出現(xiàn)許多小類 (I/O 類中就是這樣),如果過(guò)度使用,會(huì)使程序變得很復(fù)雜。

裝飾模式是針對(duì)抽象組件(Component)類型編程。但是,如果你要針對(duì)具體組件編程時(shí),就應(yīng)該重新思考你的應(yīng)用架構(gòu),以及裝飾者是否合適。

參考資料

《Head First 設(shè)計(jì)模式》

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

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

相關(guān)文章

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

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

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

    摘要:裝飾者模式是動(dòng)態(tài)地將責(zé)任附加到對(duì)象上。然后我們?cè)谧宇愑?jì)算價(jià)格的時(shí)候加上父類中計(jì)算好的配料的價(jià)格。結(jié)果可樂(lè)加冰可樂(lè)加冰加糖在的類庫(kù)中就有很多實(shí)際應(yīng)用到了裝飾模式,比如就可以用來(lái)裝飾,提供更加強(qiáng)大的功能。 裝飾者模式是動(dòng)態(tài)地將責(zé)任附加到對(duì)象上。若要擴(kuò)展功能,裝飾者提供了比繼承更有彈性的替代方案。 假設(shè)我們有一個(gè)需求,是給一家飲料店做一個(gè)計(jì)算各種飲料價(jià)格的功能。聽(tīng)起來(lái)很簡(jiǎn)單,我們創(chuàng)建一個(gè)抽象...

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

    摘要:測(cè)試類設(shè)計(jì)模式裝飾者模式工廠模式只能讀啦會(huì)報(bào)錯(cuò)只讀異常可以正確運(yùn)行第二部分定義抽象組件是具體組件和抽象裝飾類的共同父類,聲明了在具體組件中實(shí)現(xiàn)的方法。 前言 本篇文章分為四個(gè)部分:第一部分會(huì)舉一個(gè)例子引出裝飾者模式,讓讀者對(duì)裝飾者模式有個(gè)感官上的認(rèn)識(shí);第二部分會(huì)給出裝飾者模式的定義(當(dāng)然我們主要不是來(lái)背定義,就當(dāng)做積累專業(yè)名詞來(lái)記吧,我個(gè)人是很不喜歡下定義的);第三部分,我會(huì)拿jdk中...

    ytwman 評(píng)論0 收藏0
  • 開(kāi)發(fā)路(設(shè)計(jì)模式三:裝飾模式

    摘要:若要擴(kuò)展功能,裝飾者提供了比繼承更有彈性的替代方案。裝飾者模式意味著一群裝飾者類,這些類用來(lái)包裝具體組件。裝飾者類反映出被裝飾組件類型。裝飾者會(huì)導(dǎo)致設(shè)計(jì)中出現(xiàn)許多小對(duì)象,如果過(guò)度使用,會(huì)讓程序變得很復(fù)雜。 嘿嘿嘿,你是不是很喜歡用繼承呢?感覺(jué)沒(méi)什么事情是一個(gè)爸爸類搞不定的,有的話就兩個(gè),快來(lái)跟我看看這個(gè)模式吧,它能讓你斷奶,給愛(ài)用繼承的人一個(gè)全新的設(shè)計(jì)眼界。 直奔主題,你是否有聽(tīng)說(shuō)...

    Vicky 評(píng)論0 收藏0
  • 設(shè)計(jì)模式結(jié)構(gòu)型

    摘要:適配器模式不應(yīng)在設(shè)計(jì)階段考慮,它是為了解決已經(jīng)上線的問(wèn)題的存在。組合模式將對(duì)象組合成樹(shù)形結(jié)構(gòu)以表示部分整體的層次結(jié)構(gòu),使得用戶對(duì)單個(gè)對(duì)象和組合對(duì)象的使用具有一致性。 代理模式 代理模式之前已經(jīng)講過(guò),附上鏈接代理模式 裝飾者模式 裝飾者模式定義:動(dòng)態(tài)地給一個(gè)對(duì)象添加一些額外的職責(zé)。就增加功能來(lái)說(shuō),裝飾模式相比生成子類更為靈活。 裝飾模式博主在第一次學(xué)習(xí)是懵逼的,是因?yàn)榇砟J街写韺?duì)象和...

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

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

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<