前言(一些廢話,可以忽略)
- 又是一個通過聚合方式來展現設計模式思想的一個典型案例,直接進入正題
- PS.部分類實現見文末
解決一個問題
- 咖啡店點咖啡,如果我們要一份美式,要加糖,加牛奶,很簡單,但是不僅有美式,還有其他不同種的咖啡單品,那麼就有多重組合方式,如果這時我們需要增加伴侶,如加珍珠,那麼就會遇到和上一個結構型模式一樣的問題,類爆炸
- 如果解決這個問題呢,當然是裝飾者模式,將咖啡用戶各種伴侶靈活的封裝起來,這樣就可以不用擔心在擴展的時候類爆炸的問題了
裝飾者模式
- 裝飾者的核心,就是裝飾者要繼承和聚合同一個類,個人感覺這也就是和橋接模式最大的不同
- 我們的飲料類,有描述和每一種飲料的花費,也就是我們的伴侶要包含和繼承的類
/**
* @program: ade-someproblem
* @author: cade franklin
* @create: 2019-12-28 28:19
**/
public abstract class Drink {
private String desc;
public Drink(String desc) {
this.desc = desc;
}
String getDesc(){
return desc;
}
abstract float cost();
}
-接下來看我們的單品咖啡,價格2.0,名字就叫LongBlack
/**
* @program: ade-someproblem
* @author: cade franklin
* @create: 2019-12-28 28:19
**/
public class LongBlack extends Drink {
public LongBlack() {
super("LongBlack");
}
@Override
float cost() {
return 2.0f;
}
}
- 而伴侶,如牛奶伴侶,繼承我們的裝飾者,那裝飾者又有什麼呢
/**
* @program: ade-someproblem
* @author: cade franklin
* @create: 2019-12-28 28:20
**/
public class Milk extends Decorator {
public Milk(Drink drink) {
super(drink);
}
@Override
String getDesc() {
return "加牛奶1份+"+drink.getDesc();
}
@Override
float cost() {
return drink.cost()+0.5f;
}
}
- 裝飾者當然就是我們之前說的,繼承飲料同時聚合飲料,這樣,我們在使用的時候就可以隨意加我們想要的伴侶了
/**
* 調料
* @program: ade-someproblem
* @author: cade franklin
* @create: 2019-12-28 28:20
**/
public abstract class Decorator extends Drink{
Drink drink;
public Decorator(Drink drink) {
super(drink.getDesc());
this.drink = drink;
}
}
- 裝飾者模式的使用如下,方便靈活好擴展
/**
* @program: ade-someproblem
* @author: cade franklin
* @create: 2019-12-28 28:20
**/
public class DecoratorMode {
public static void main(String[] args) {
Drink drink = new Milk(new Chocolate(new LongBlack()));
System.out.println(drink.getDesc());
System.out.println(drink.cost());;
}
}
總結
- 此模式與上一篇介紹的橋接模式比較相似,都是通過聚合的方式來實現,但是對象之間的關係不同,這個是多個裝飾者,一個單品,一對多的關係,而上一篇橋接模式,是多對多的關係,多個手機品牌,多個屏幕類型,在學習時,可以進行適當的區分
- 另外此模式的核心邏輯在前面已經說了,就是裝飾者要聚和一個被裝飾者,他們當然也要繼承同樣的類
願你不捨愛與自由。