一、引言
9月30號上映,《我和我的祖國》這個電影,小編不知道你們看了沒,還挺不錯的。
其中講述了新中國成立、中國女排、香港迴歸、首顆原子彈爆炸等等歷史性的事件,小編再一次體會到中國的強大。
國慶節假期現在是第四天了,去年這個時候小編還記得再寫redis相關操作,年復一年。
二、裝飾者定義
結構型設計模式,動態的將新功能附加到對象上,在對象功能擴展方面,他比繼承更加有彈性,裝飾者模式也體現了開閉原則。
那裝飾者有什麼優點呢? 可能剛一開始說還看不太明白,看完具體案例分析實現,再回頭來看,是否理解。
1、擴展一個類的功能,或者給一個類增加附加職責。
2、通過這些不同的裝飾者,可以使被裝飾者實現不同的效果。
3、符合開閉原則,可以在不改變原有類的情況下,給個對象添加新的功能。
三、裝飾者案例分析
你們喜歡喫手抓餅嘛?
小編喫手抓餅喜歡加培根和肉鬆,再外加一瓶牛奶,完美解決早餐。
那就以這個生活爲案例,假設現在有一款手抓餅的產品,可以加多份不同的配料,然後計算最後的價格。
小夥伴們可以先想想,如果要你現在設計這麼一個功能,你會怎麼去設計?
注意:一個手抓餅可以加兩份培根,一份肉鬆等等,還需要注意程序的可擴展性、維護性。
裝飾者就比較適合這種場景來使用,下面進行角色分析
1、抽象產品:被裝飾者基類,用來定義被裝飾者的行爲和方法
2、被裝飾者:具體的裝飾者類,可以動態添加新的功能(比如一個手抓餅可以加雞蛋、火腿等等)。
3、抽象裝飾者:需要聚合或者組合具體被裝飾者,還需要繼承或者實現抽象產品
4、裝飾者:持有被裝飾者對象,並且進行新功能的添加
四、裝飾者案例實現
步驟一:首先我們需要創建產品,產品是主要內容,裝飾是其次(首先你要有煎餅果子可以賣,纔可以加火腿之類的)。
/**
* @Auther: IT賤男
* @Date: 2019/8/21 13:54
* @Description: 產品抽象類
*/
public interface Apancake {
/**
* 產品描述
* @return
*/
String getDesc();
/**
* 產品價格
* @return
*/
int cost();
}
/**
* @Auther: IT賤男
* @Date: 2019/8/21 13:56
* @Description: 被裝飾者 - 煎餅果子
*/
public class BatterCake implements Apancake {
@Override
public String getDesc() {
return "煎餅果子";
}
@Override
public int cost() {
return 5;
}
}
步驟二:現在具體產品有了,那麼光一個煎餅果子也不夠喫呀,商家還提供了可以加火腿、雞蛋這個配料。
/**
* @Auther: IT賤男
* @Date: 2019/8/21 13:57
* @Description: 抽象裝飾者 - 實現產品接口
*/
public class AbstractDecorate implements Apancake {
// 聚合一個具體的被裝飾者
protected Apancake apancake;
public AbstractDecorate(Apancake apancake) {
this.apancake = apancake;
}
@Override
public String getDesc() {
// 調用被裝飾者的方法
return this.apancake.getDesc();
}
@Override
public int cost() {
// 調用被裝飾者的方法
return this.apancake.cost();
}
}
/**
* @Auther: IT賤男
* @Date: 2019/8/21 14:02
* @Description: 火腿腸裝飾者 -> 繼承抽象抽象裝飾者
*/
public class SausageDecorate extends AbstractDecorate {
public SausageDecorate(Apancake apancake) {
super(apancake);
}
@Override
public String getDesc() {
// 首先需要調用父類的方法,獲取原本結果的基礎之上,新增新功能
return super.getDesc() + "加一個火腿腸加兩元";
}
@Override
public int cost() {
// 首先需要調用父類的方法,獲取原本的價格,加一根火腿的價格
return super.cost() + 2;
}
}
/**
* @Auther: IT賤男
* @Date: 2019/8/21 13:59
* @Description: 雞蛋裝飾者 -> 繼承抽象抽象裝飾者
*/
public class EggDecorate extends AbstractDecorate {
public EggDecorate(Apancake apancake) {
super(apancake);
}
@Override
public String getDesc() {
return super.getDesc() + "加一個雞蛋一元";
}
@Override
public int cost() {
return super.cost() + 1;
}
}
步驟三:測試,現在來了一個客人,需要一個加雞蛋、火腿的煎餅果子。 原本只是一個普通的煎餅果子,經過裝飾者這麼一操作之後,就變得不普通了。
/**
* @Auther: IT賤男
* @Date: 2019/8/21 14:03
* @Description:
*/
public class Test {
public static void main(String[] args) {
// 商家先做一個煎餅果子出來
Apancake batterCake = new BatterCake();
System.out.println(batterCake.getDesc() + " 價格:" + batterCake.cost());
System.out.println("-------------------------");
// 把做出來的煎餅果子加雞蛋
batterCake = new EggDecorate(batterCake);
System.out.println(batterCake.getDesc() + " 價格:" + batterCake.cost());
// 把已經加好雞蛋的煎餅果子,再加一個火腿
System.out.println("-------------------------");
batterCake = new SausageDecorate(batterCake);
System.out.println(batterCake.getDesc() + " 價格:" + batterCake.cost());
}
}
煎餅果子 價格:5
-------------------------
煎餅果子加一個雞蛋一元 價格:6
-------------------------
煎餅果子加一個雞蛋一元加一個火腿腸加兩元 價格:8
三、裝飾者模式和橋接模式區別
橋接模式的定義是將抽象與實現分離(用組合聚合的方式,而不是使用繼承),使得兩者可以獨立變化,可以減少創建新的類。這樣看起來和裝飾者模式差不多,但是兩者還是有一些區別。
1、橋接模式中所指的分離,是將抽象和實現分離,而裝飾者只是基於屬性的行爲進行封裝成獨立的類。
2、橋接模式中的行爲之間是沒有關聯的,而裝飾者模式中的行爲具有可疊加性,其表現出來的結果是一個整體。
3、兩者都可以減少子類過多的問題。