日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

Java 设计模式之装饰者模式

發(fā)布時間:2024/9/30 java 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java 设计模式之装饰者模式 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一、了解裝飾者模式

1.1 什么是裝飾者模式

裝飾者模式指的是在不必改變原類文件和使用繼承的情況下,動態(tài)地擴(kuò)展一個對象的功能。它是通過創(chuàng)建一個包裝對象,也就是裝飾者來包裹真實的對象。

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

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

  • 抽象構(gòu)件 (Component):給出抽象接口或抽象類,以規(guī)范準(zhǔn)備接收附加功能的對象。
  • 具體構(gòu)件 (ConcreteComponent):定義將要接收附加功能的類。
  • 抽象裝飾 (Decorator):裝飾者共同要實現(xiàn)的接口,也可以是抽象類。
  • 具體裝飾 (ConcreteDecorator):持有一個 Component 對象,負(fù)責(zé)給構(gòu)件對象“貼上”附加的功能。

1.3 裝飾者模式 UML 圖解

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

  • 需要擴(kuò)展一個類的功能,或給一個類添加附加職責(zé)。
  • 需要動態(tài)的給一個對象添加功能,這些功能可以再動態(tài)的撤銷。
  • 需要增加由一些基本功能的排列組合而產(chǎn)生的非常大量的功能,從而使繼承關(guān)系變的不現(xiàn)實。
  • 當(dāng)不能采用生成子類的方法進(jìn)行擴(kuò)充時。可能有大量獨立的擴(kuò)展,為支持每一種組合將產(chǎn)生大量的子類,使得子類數(shù)目呈爆炸性增長。

1.5 裝飾者模式特點

  • 裝飾者對象和具體構(gòu)件有相同的接口。這樣客戶端對象就能以和真實對象相同的方式和裝飾對象交互。
  • 裝飾者對象包含一個具體構(gòu)件的引用(reference)。
  • 裝飾者對象接受所有來自客戶端的請求。它把這些請求轉(zhuǎn)發(fā)給具體構(gòu)件。
  • 裝飾者對象可以在轉(zhuǎn)發(fā)這些請求以前或以后動態(tài)增加一些功能。

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

2.1 問題描述

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

2.2 使用繼承

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

2.3 繼承類圖

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

2.4 裝飾者模式登場

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

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

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

  • 拿一個深焙咖啡 (DarkRoast) 對象
  • 以摩卡 (Mocha) 裝飾它
  • 以豆?jié){ (Soy) 裝飾它
  • 調(diào)用 cost() 方法,并依賴委托將調(diào)料的價錢加上去
  • (1) 裝飾者模式設(shè)計圖

    (2)代碼實現(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 ";}@Overridepublic double cost() {return 1.99;} }

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

    package com.jas.decorator;public class HouseBlend extends Beverage {public HouseBlend(){description = "House Blend Coffee ";}@Overridepublic double cost() {return 0.80;} }

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

    package com.jas.decorator;public abstract class CondimentDecorator extends Beverage{@Overridepublic abstract String getDescription(); }

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

    package com.jas.decorator;public class Mocha extends CondimentDecorator {private Beverage beverage = null; //用一個實例變量來記錄飲料,也就是被裝飾者public Mocha(Beverage beverage){this.beverage = beverage; //通過構(gòu)造函數(shù)將被裝飾者實例化}@Overridepublic String getDescription() {return beverage.getDescription() + ", Mocha "; //用來加上調(diào)料,一起描述飲料}@Overridepublic double cost() {return 0.2 + beverage.cost(); //計算摩卡飲料的價錢,為摩卡價錢 + 飲料價錢} }

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

    package com.jas.decorator;public class Soy extends CondimentDecorator {private Beverage beverage = null;public Soy(Beverage beverage){this.beverage = beverage;}@Overridepublic String getDescription() {return beverage.getDescription() + ", Soy ";}@Overridepublic double cost() {return 0.1 + beverage.cost();} }

    測試代碼 StarbuzzCoffee 類

    package com.jas.decorator;public class StarbuzzCoffee {public static void main(String[] args) {//簡單要一杯濃咖啡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 裝飾者模式問題總結(jié)

    • 裝飾者與被裝飾對象有相同的超類型 (DarkRoast 與裝飾類 Mocha 和 Soy 都繼承自 Beverage(飲料))。
    • 可以使用一個或多個裝飾對象包裝一個對象。
    • 因為裝飾者與被裝飾者具有相同的超類型,所以在任何需要原始對象的情況下,都可以用裝飾過的對象去代替它。
    • 裝飾者可以在所委托被裝飾者的行為之前與之后,加上自己的行為,以達(dá)到特定的目的。
    • 對象可以在任何時候被裝飾,所以在運行時動態(tài)地、不限量地用你喜歡的裝飾者去裝飾對象。

    三、真實世界的裝飾者 Java I/O

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

    在了解了裝飾者模式之后,I/O 相關(guān)的類對你來說就更有意義了,因為這其中很多類都是裝飾者。比如下面相關(guān)的類

    裝飾 I/O 類

    3.2 自定義 Java I/O 裝飾者

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

    裝飾者 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);}@Overridepublic int read() throws IOException{int c = super.read();return (c == -1 ? c : Character.toLowerCase((char)c));}@Overridepublic 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;} }

    測試 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)缺點

    優(yōu)點

  • Decorator 模式與繼承關(guān)系的目的都是要擴(kuò)展對象的功能,但是 Decorator 可以提供比繼承更多的靈活性。
  • 通過使用不同的具體裝飾類以及這些裝飾類的排列組合,設(shè)計者可以創(chuàng)造出很多不同行為的組合。
  • 缺點

  • 這種比繼承更加靈活機動的特性,也同時意味著更加多的復(fù)雜性。
  • 裝飾模式會導(dǎo)致設(shè)計中出現(xiàn)許多小類 (I/O 類中就是這樣),如果過度使用,會使程序變得很復(fù)雜。
  • 裝飾模式是針對抽象組件(Component)類型編程。但是,如果你要針對具體組件編程時,就應(yīng)該重新思考你的應(yīng)用架構(gòu),以及裝飾者是否合適。
  • PS:點擊了解更多設(shè)計模式 http://blog.csdn.net/codejas/article/details/79236013

    參考文獻(xiàn)

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

    總結(jié)

    以上是生活随笔為你收集整理的Java 设计模式之装饰者模式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 午夜影院在线免费观看 | 大伊人久久 | 四虎永久在线精品免费一区二区 | 毛片av免费看 | 欧美综合激情 | 亚洲免费一区二区 | 拔萝卜91 | 日日操日日 | 日韩一区二区精品视频 | 久久伊人色 | 精品久久久一区 | 免费一级特黄毛大片 | 91传媒在线视频 | 中文字幕av在线免费观看 | 看污片网站 | 野外吮她的花蒂高h在线观看 | 中文字幕一区二区三区四区 | 日本理论片午伦夜理片在线观看 | 免费看裸体网站视频 | 国产一区二区观看 | 日韩精品视频在线 | 国产精品无码专区av在线播放 | 涩久久| 国产人妻大战黑人20p | 一级黄色片片 | 91涩漫成人官网入口 | 性感美女一区二区三区 | 一区二区福利电影 | 91成人品 | 亚洲天堂资源 | 2019最新中文字幕 | aaa天堂| www.插插插| 三级黄色av| 日本免费一区视频 | 欧美丰满熟妇bbbbbb百度 | 婷婷视频 | 大尺度做爰床戏呻吟舒畅 | 午夜777| 中文字幕一区二区在线观看 | 欧美一区二区三区成人久久片 | 秋霞毛片少妇激情免费 | 男人爱看的网站 | 日韩精品999 | 黄瓜视频色 | 国产一区二区免费在线观看 | 日本一区不卡在线 | 蜜桃无码一区二区三区 | 免费观看国产精品视频 | 亚欧三级 | 一区二区免费在线视频 | 成人在线观看网站 | 91蝌蚪91密月 | 性生活毛片 | 欧美性视频播放 | 国产又粗又硬又长又爽的演员 | 国产51精品 | 妖精视频在线观看免费 | 超碰在线个人 | 青青草超碰 | 午夜寂寞少妇 | 爱爱视频在线看 | 亚洲第一天堂网 | 国产一区二区欧美 | 精品一级少妇久久久久久久 | 久久99精品久久久久子伦 | 日韩黄网 | 91在线公开视频 | 免费看a网站 | 日韩大片免费在线观看 | 青青插 | 69欧美视频| 白石茉莉奈番号 | 麻豆视频在线看 | 97夜色| 国产爱搞 | 91精品一区二区三区综合在线爱 | 国产一级二级在线 | 又黄又骚的视频 | 91精品国产综合久久久密臀九色 | 黄色片网站免费在线观看 | a天堂中文在线 | 少妇av一区二区三区无码 | 久久久久99精品成人片试看 | www.狠狠 | 成人a视频在线观看 | 婷婷av在线 | 欧美色图网址 | jizzjizzjizz国产 | 在线免费看黄视频 | 成人免费看片在线观看 | 一级艳片新婚之夜 | 三级黄色片免费观看 | 亚洲一区在线电影 | 制服下的诱惑暮生 | 国产高清精品在线观看 | 综合一区在线 | 激情777| 姑娘第5集高清在线观看 |