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

Java裝飾者模式的深入了解

 更新時間:2022年01月05日 16:13:41   作者:空山新雨后~  
這篇文章主要為大家介紹了Java裝飾者模式,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助

一、裝飾模式的定義和特點

在軟件開發(fā)過程中,有時想用一些現(xiàn)存的組件。這些組件可能只是完成了一些核心功能。但在不改變其結(jié)構(gòu)的情況下,可以動態(tài)地擴展其功能。所有這些都可以釆用裝飾器模式來實現(xiàn)。

就像我們做菜,需要用到調(diào)料,菜,刀,火等一系列抽象的組件來最終完成一道菜。

裝飾模式的定義:

指在不改變現(xiàn)有對象結(jié)構(gòu)的情況下,動態(tài)地給該對象增加一些職責(zé)(即增加其額外功能)的模式,它屬于對象結(jié)構(gòu)型模式。就增加功能來說,裝飾模式比生成子類更加靈活。

特點:

裝飾器是繼承的有力補充,比繼承靈活,在不改變原有對象的情況下,動態(tài)的給一個對象擴展功能,即插即用
通過使用不用裝飾類及這些裝飾類的排列組合,可以實現(xiàn)不同效果
 裝飾器模式完全遵守開閉原則

缺點

 裝飾器模式會增加許多子類,過度使用會增加程序得復(fù)雜性。

二、裝飾模式的結(jié)構(gòu)

裝飾模式的結(jié)構(gòu)一般包含以下幾個角色

1. 抽象構(gòu)件(Component)角色:定義一個抽象接口以規(guī)范準(zhǔn)備接收附加責(zé)任的對象。
2. 具體構(gòu)件(ConcreteComponent)角色:實現(xiàn)抽象構(gòu)件,通過裝飾角色為其添加一些職責(zé)。
3. 抽象裝飾(Decorator)角色:繼承抽象構(gòu)件,并包含具體構(gòu)件的實例,可以通過其子類擴展具體構(gòu)件的功能。
4. 具體裝飾(ConcreteDecorator)角色:實現(xiàn)抽象裝飾的相關(guān)方法,并給具體構(gòu)件對象添加附加的責(zé)任。

圖示

三、咖啡點單案例演示

有一個需求,點一杯咖啡需要咖啡,材料等等,這個案例就很適合裝飾模式,類似于穿衣,點餐,買包子,等等,我們怎么把他設(shè)計成裝飾模式呢?

看類圖

這個結(jié)構(gòu)就是我已經(jīng)設(shè)計好的一個裝飾模式的類圖,idea自動生成的,這里的Drink就是我們上面說的抽象構(gòu)建角色,裝飾者是Decorator,他是一個抽象裝飾,下面他的子類就是具體的裝飾者,那么具體構(gòu)建中間我們提供了一個中間構(gòu)建,提供了coffee的一些共性,可以放在這里,用的時候直接繼承,他的下面就是相應(yīng)的具體構(gòu)件,具體被裝飾者角色,裝飾者與被裝飾者共同繼承自component抽象構(gòu)件,需要用到裝飾的就是我們點一杯咖啡,用裝飾去包裹即可,層層包裹,案例如下:

比如我要點一份加糖加奶的拿鐵咖啡

代碼實例:

component抽象構(gòu)件角色:

package com.decoratorPattern.starBucks;
 
/**
 * @author wang
 * @version 1.0
 * @packageName com.decoratorPattern.starBucks
 * @className Drink
 * @date 2021/12/28 10:28
 * @Description 飲料構(gòu)件類抽象component
 */
public abstract class Drink {
    private String description;
    private float price = 0.0f;
 
    public String getDescription() {
        return description;
    }
 
    public void setDescription(String description) {
        this.description = description;
    }
 
    public float getPrice() {
        return price;
    }
 
    public void setPrice(float price) {
        this.price = price;
    }
 
    /**
     * @Date  2021/12/28 10:30
     * @Param
     * @Return float
     * @MetodName cost
     * @Author wang
     * @Description 計算花費,訂單價格
     */
    public abstract float cost();
}

裝飾者類:

package com.decoratorPattern.starBucks;
 
/**
 * @author wang
 * @version 1.0
 * @packageName com.decoratorPattern.starBucks
 * @className Decorator
 * @date 2021/12/28 10:40
 * @Description 裝飾者定義類,配料
 */
public class Decorator extends Drink {
 
    private Drink drink;
 
    /**
     * @param drink
     * @Date 2021/12/28 10:42
     * @Param
     * @Return null
     * @MetodName Decorator
     * @Author wang
     * @Description 傳入一個被裝飾者,由裝飾者進行裝飾
     */
    public Decorator(Drink drink) {
        this.drink = drink;
    }
 
    /**
     * @Date 2021/12/28 10:43
     * @Param
     * @Return float
     * @MetodName cost
     * @Author wang
     * @Description 裝飾者的價格加上被裝飾者的價格
     */
    @Override
    public float cost() {
        return super.getPrice() + drink.cost();
    }
 
    /**
     * @Date 2021/12/28 10:44
     * @Param
     * @Return String
     * @MetodName getDescription
     * @Author wang
     * @Description 輸出訂單信息,包含裝飾者,裝飾者的價格,以及被裝飾者的信息
     */
    @Override
    public String getDescription() {
        return drink.getDescription() + "\n加入的材料:" + super.getDescription()
                + "\t材料價格:" + super.getPrice() ;
    }
}

裝飾者類:

package com.decoratorPattern.starBucks;
 
/**
 * @author wang
 * @version 1.0
 * @packageName com.decoratorPattern.starBucks
 * @className Decorator
 * @date 2021/12/28 10:40
 * @Description 裝飾者定義類,配料
 */
public class Decorator extends Drink {
 
    private Drink drink;
 
    /**
     * @param drink
     * @Date 2021/12/28 10:42
     * @Param
     * @Return null
     * @MetodName Decorator
     * @Author wang
     * @Description 傳入一個被裝飾者,由裝飾者進行裝飾
     */
    public Decorator(Drink drink) {
        this.drink = drink;
    }
 
    /**
     * @Date 2021/12/28 10:43
     * @Param
     * @Return float
     * @MetodName cost
     * @Author wang
     * @Description 裝飾者的價格加上被裝飾者的價格
     */
    @Override
    public float cost() {
        return super.getPrice() + drink.cost();
    }
 
    /**
     * @Date 2021/12/28 10:44
     * @Param
     * @Return String
     * @MetodName getDescription
     * @Author wang
     * @Description 輸出訂單信息,包含裝飾者,裝飾者的價格,以及被裝飾者的信息
     */
    @Override
    public String getDescription() {
        return drink.getDescription() + "\n加入的材料:" + super.getDescription()
                + "\t材料價格:" + super.getPrice() ;
    }
}

具體構(gòu)件類:拿鐵

package com.decoratorPattern.starBucks;
 
/**
 * @author wang
 * @version 1.0
 * @packageName com.decoratorPattern.starBucks
 * @className latte
 * @date 2021/12/28 10:32
 * @Description 拿鐵咖啡實類,被裝飾者
 */
public class Latte extends Coffee{
    public Latte() {
        setDescription("拿鐵咖啡");
        setPrice(15.0f);
    }
}

具體構(gòu)件類:摩卡

package com.decoratorPattern.starBucks;
 
/**
 * @author wang
 * @version 1.0
 * @packageName com.decoratorPattern.starBucks
 * @className Mocha
 * @date 2021/12/28 10:36
 * @Description 摩卡咖啡實類,被裝飾者
 */
public class Mocha extends Coffee {
    public Mocha() {
        setDescription("摩卡咖啡");
        setPrice(12.2f);
    }
}

其他同上,不過多展示

 具體裝飾類:牛奶

package com.decoratorPattern.starBucks;
 
/**
 * @author wang
 * @version 1.0
 * @packageName com.decoratorPattern.starBucks
 * @className Milk
 * @date 2021/12/28 10:47
 * @Description 牛奶調(diào)味品,具體裝飾者
 */
public class Milk extends Decorator{
 
    /**
     * @param drink
     * @Date 2021/12/28 10:42
     * @Param
     * @Return null
     * @MetodName Decorator
     * @Author wang
     * @Description 傳入一個被裝飾者,由裝飾者進行裝飾
     */
    public Milk(Drink drink) {
        super(drink);
        setDescription("牛奶");
        setPrice(1.0f);
    }
}

具體裝飾:糖

package com.decoratorPattern.starBucks;
 
/**
 * @author wang
 * @version 1.0
 * @packageName com.decoratorPattern.starBucks
 * @className sugar
 * @date 2021/12/28 10:50
 * @Description 糖,裝飾者
 */
public class Sugar extends Decorator{
    /**
     * @param drink
     * @Date 2021/12/28 10:42
     * @Param
     * @Return null
     * @MetodName Decorator
     * @Author wang
     * @Description 傳入一個被裝飾者,由裝飾者進行裝飾
     */
    public Sugar(Drink drink) {
        super(drink);
        setDescription("糖");
        setPrice(0.5f);
    }
}

訂單測試代碼:

package com.decoratorPattern.starBucks;
 
/**
 * @author wang
 * @version 1.0
 * @packageName com.decoratorPattern.starBucks
 * @className OrderTest
 * @date 2021/12/28 10:51
 * @Description 前臺訂單類
 */
public class OrderTest {
    public static void main(String[] args) {
        //點一份加糖加奶的拿鐵咖啡
 
        System.out.println("+++++++沒加任何東西+++++++");
        Drink latte = new Latte();
        System.out.println("當(dāng)前總價:" + latte.cost());
        System.out.println("coffee:" +latte.getDescription());
        //加糖
        System.out.println("+++++++加糖后+++++++");
        latte = new Sugar(latte);
        System.out.println("當(dāng)前總價:" + latte.cost());
        System.out.println("coffee:" + latte.getDescription());
 
        System.out.println("+++++++加奶后+++++++");
        latte = new Milk(latte);
        System.out.println("當(dāng)前總價:" + latte.cost());
        System.out.println("coffee:" +latte.getDescription());
    }
}
/**
 * +++++++沒加任何東西+++++++
 * 當(dāng)前總價:15.0
 * coffee:拿鐵咖啡
 * +++++++加糖后+++++++
 * 當(dāng)前總價:15.5
 * coffee:拿鐵咖啡
 * 加入的材料:糖	材料價格:0.5
 * +++++++加奶后+++++++
 * 當(dāng)前總價:16.5
 * coffee:拿鐵咖啡
 * 加入的材料:糖	材料價格:0.5
 * 加入的材料:牛奶	材料價格:1.0
 *
 * Process finished with exit code 0
 */

綜上, 如果我們需要新的咖啡種類或者是新的調(diào)料,只需要新增類去繼承coffee或者decorator類即可。

四、總結(jié)

裝飾模式是為已有的功能動態(tài)的添加更多功能的一種方式,當(dāng)系統(tǒng)需要新功能的時候,向舊的類中添加新的代碼,這些新加的代碼通常裝飾了原有類的核心職責(zé)或主要行為。

優(yōu)點:

把類中裝飾功能從類中移除,這樣可以簡化原來的類,

有效的把類的核心職責(zé)和裝飾功能分開了,而且可以去除相關(guān)類中的重復(fù)裝飾邏輯

可代替繼承。

總結(jié)

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

相關(guān)文章

  • Java中的PreparedStatement對象使用解析

    Java中的PreparedStatement對象使用解析

    這篇文章主要介紹了Java中的PreparedStatement對象使用解析,PreparedStatement對象采用了預(yù)編譯的方法,會對傳入的參數(shù)進行強制類型檢查和安全檢查,進而避免了SQL注入的產(chǎn)生,使得操作更加安全,需要的朋友可以參考下
    2023-12-12
  • Java中的使用及連接Redis數(shù)據(jù)庫(附源碼)

    Java中的使用及連接Redis數(shù)據(jù)庫(附源碼)

    這篇文章主要介紹了Java中的使用及連接Redis數(shù)據(jù)庫(附源碼),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • Spring Boot集成MyBatis-Plus 自定義攔截器實現(xiàn)動態(tài)表名切換功能

    Spring Boot集成MyBatis-Plus 自定義攔截器實現(xiàn)動態(tài)表名切換功能

    本文介紹了如何在SpringBoot項目中集成MyBatis-Plus,并通過自定義攔截器實現(xiàn)動態(tài)表名切換,此外,還探討了MyBatis攔截器在其他場景中的應(yīng)用,如SQL日志記錄、多租戶數(shù)據(jù)隔離、數(shù)據(jù)權(quán)限控制等,感興趣的朋友跟隨小編一起看看吧
    2024-11-11
  • 如何對jdk版本升級或降級

    如何對jdk版本升級或降級

    這篇文章主要介紹了如何對jdk版本升級或降級方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • 在springboot項目中同時接收文件和多個參數(shù)的方法總結(jié)

    在springboot項目中同時接收文件和多個參數(shù)的方法總結(jié)

    在開發(fā)接口中,遇到了需要同時接收文件和多個參數(shù)的情況,可以有多種方式實現(xiàn)文件和參數(shù)的同時接收,文中給大家介紹了兩種實現(xiàn)方法,感興趣的同學(xué)跟著小編一起來看看吧
    2023-08-08
  • 淺談Java變量的初始化順序詳解

    淺談Java變量的初始化順序詳解

    本篇文章是對Java變量的初始化順序進行了詳細的分析介紹,需要的朋友參考下
    2013-06-06
  • SpringBoot統(tǒng)計、監(jiān)控SQL運行情況的方法詳解

    SpringBoot統(tǒng)計、監(jiān)控SQL運行情況的方法詳解

    這篇文章主要給大家介紹了關(guān)于SpringBoot統(tǒng)計、監(jiān)控SQL運行情況的相關(guān)資料,文中通過實例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2022-02-02
  • SpringBoot實戰(zhàn)項目之谷歌瀏覽器全屏效果實現(xiàn)

    SpringBoot實戰(zhàn)項目之谷歌瀏覽器全屏效果實現(xiàn)

    這篇文章主要介紹了通過 Java SpringBoot來實現(xiàn)谷歌瀏覽器的全屏效果,希望頁面展示時可以實現(xiàn)全屏效果以提高用戶體驗。感興趣的小伙伴跟著小編往下看吧
    2021-09-09
  • SpringMVC中使用Thymeleaf模板引擎實例代碼

    SpringMVC中使用Thymeleaf模板引擎實例代碼

    這篇文章主要介紹了SpringMVC中使用Thymeleaf模板引擎實例代碼,分享了相關(guān)代碼示例,小編覺得還是挺不錯的,具有一定借鑒價值,需要的朋友可以參考下
    2018-02-02
  • SpringBoot自動裝配之Condition深入講解

    SpringBoot自動裝配之Condition深入講解

    @Conditional表示僅當(dāng)所有指定條件都匹配時,組件才有資格注冊。該@Conditional注釋可以在以下任一方式使用:作為任何@Bean方法的方法級注釋、作為任何類的直接或間接注釋的類型級別注釋@Component,包括@Configuration類、作為元注釋,目的是組成自定義構(gòu)造型注釋
    2023-01-01

最新評論

辽宁省| 拉萨市| 垦利县| 涡阳县| 瓦房店市| 琼结县| 宜阳县| 达州市| 阳春市| 监利县| 白水县| 五大连池市| 长沙市| 陇川县| 长武县| 合作市| 崇明县| 凤翔县| 浪卡子县| 阜阳市| 佛冈县| 九龙坡区| 扎赉特旗| 建阳市| 阳朔县| 平罗县| 九龙县| 绥阳县| 福州市| 甘南县| 容城县| 会宁县| 通州区| 夏河县| 福安市| 甘南县| 赫章县| 通化市| 兴义市| 交城县| 璧山县|