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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

设计模式java装饰模式范例_Java设计模式之装饰模式详解

發布時間:2024/9/19 java 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 设计模式java装饰模式范例_Java设计模式之装饰模式详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

裝飾者模式是動態地將責任附加到對象上。若要擴展功能,裝飾者提供了比繼承更有彈性的替代方案。

假設我們有一個需求,是給一家飲料店做一個計算各種飲料價格的功能。聽起來很簡單,我們創建一個抽象父類Beverages,description用來描述飲料名字,price方法用來計算飲料的價格。

public abstract class Beverages {

private String description;

public String getDescription() {

return description;

}

public abstract double price();

}

每種飲料我們都創建一個子類去繼承父類,賦值給description,并且重寫price方法來設置自己的價格。看上去很完美,我們運行一下看看結果。

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());

}

結果:

咖啡

3.5

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

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

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;

}

}

然后我們在子類計算價格的時候加上父類中計算好的配料的價格。

public class CoffeeWithMilk extends Beverages {

public CoffeeWithMilk(String description){

this.description = description;

}

@Override

public double price() {

return 3.0 + super.price();

}

}

我們運行看一下,咖啡加牛奶加糖,結果沒有問題。

CoffeeWithMilk coffeeWithMilk = new CoffeeWithMilk("咖啡加牛奶加糖");

coffeeWithMilk.setMilk(true);

coffeeWithMilk.setSugar(true);

System.out.println(coffeeWithMilk.getDescription());

System.out.println(coffeeWithMilk.price());

結果:

咖啡加牛奶加糖

5.0

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

首先我們創建抽象父類Beverages,這個父類只是飲料的父類,不是配料的父類。我們創建一個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;

}

}

現在就缺配料的部分的代碼了,我們再創建一個配料的抽象類Seasonings,我們讓它繼承Berverages類,并且聲明了一個Berverages的引用和抽象的getDescription方法,這里我們稍后再作解釋。

public abstract class Seasonings extends Beverages{

public Beverages beverages;

public abstract String getDescription();

}

接下來我們看看配料的實現類怎么寫。我們讓他繼承了父類Seasonings,構造函數接收父類Beverages類型,其實也就是要被裝飾的對象,也就是各種各樣需要加配料的飲料。然后我們重寫了getDescription,我們在傳進來的那個Beverages對象的基礎上添加名字,price方法也是同理。這樣其實就在給傳進來的對象外面做了一層裝飾,也就是給飲料添加了配料。

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;

}

}

運行一下,看看結果。沒有問題,可以搭配成功。

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

Beverages ice = new Ice(cola);

System.out.println(ice.getDescription());

System.out.println(ice.price());

結果:

可樂加冰

2.2

我們還想再添加別的配料,再創建一個新的配料。

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();

}

}

我們在原來搭配好的基礎上再進行裝飾,結果也是沒有問題的。這個時候就要提到為什么我們的Seasonings類要繼承Beverages類了,因為每個配料的實現類里有一個Beverages類型的引用,這樣我們才可以對它的子類進行裝飾,我們讓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());

結果:

可樂加冰

2.2

可樂加冰加糖

2.7

在Java的類庫中就有很多實際應用到了裝飾模式,比如BufferedInputStream就可以用來裝飾FileInputStream,提供更加強大的功能。

總結:

裝飾模式就是裝飾者和被裝飾者都具有相同的超類,裝飾者拿到被裝飾者的引用之后,在調用被裝飾者的方法的同時再加上自己的新功能,從而實現了功能的增加,也不需要修改原來的代碼。而且因為是相同的超類,所以可以裝飾很多層。

總結

以上是生活随笔為你收集整理的设计模式java装饰模式范例_Java设计模式之装饰模式详解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。