vault backup: 2022-06-21 17:16:00
Affected files: 02. PARA/03. Resources(資源)/Design Pattern.md
This commit is contained in:
@@ -149,10 +149,9 @@ notify()則是當發生變化時,用來通知所有觀察者的實作。
|
|||||||
以書上的例子來說,我們多種飲料,每種飲料都可以加上不同的配料。例如,有奶茶、綠茶、紅茶3種飲料,另外有珍珠、紅豆、綠豆、仙草4種配料,我們要如何設計出適合的類別來讓每種飲料都可以隨寄的搭配配料呢?
|
以書上的例子來說,我們多種飲料,每種飲料都可以加上不同的配料。例如,有奶茶、綠茶、紅茶3種飲料,另外有珍珠、紅豆、綠豆、仙草4種配料,我們要如何設計出適合的類別來讓每種飲料都可以隨寄的搭配配料呢?
|
||||||
|
|
||||||
假設這樣寫:
|
假設這樣寫:
|
||||||
|
|
||||||
- !!!col
|
- !!!col
|
||||||
- 1
|
- 1
|
||||||
Ingredient class
|
### Ingredient class
|
||||||
```cpp
|
```cpp
|
||||||
class IngredientBubble { ... };
|
class IngredientBubble { ... };
|
||||||
class IngredientRedbean { ... };
|
class IngredientRedbean { ... };
|
||||||
@@ -161,7 +160,7 @@ notify()則是當發生變化時,用來通知所有觀察者的實作。
|
|||||||
```
|
```
|
||||||
|
|
||||||
- 1
|
- 1
|
||||||
Beverage class
|
### Beverage class
|
||||||
```cpp
|
```cpp
|
||||||
class Beverage {
|
class Beverage {
|
||||||
int32_t cost() { return cost; }
|
int32_t cost() { return cost; }
|
||||||
@@ -178,7 +177,7 @@ notify()則是當發生變化時,用來通知所有觀察者的實作。
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
每個飲料的class裡面都將每個配料定義為一個member,如果客人有加配料的話,我們就將配料實例化,假設奶茶加了珍珠:
|
每個飲料的class裡面都將每個配料定義為一個 member,如果客人有加配料的話,我們就將配料實例化,假設奶茶加了珍珠:
|
||||||
```cpp
|
```cpp
|
||||||
class BeverageBlackTea {
|
class BeverageBlackTea {
|
||||||
void addBubble() {
|
void addBubble() {
|
||||||
@@ -201,9 +200,9 @@ class BeverageBlackTea {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
這樣的問題是,每當有一種新配料出現,我們就要在奶茶類別裡修改至少2個function,addXXX()與cost(),目前我們有3種飲料,所以要修改6個function,更何況,如果客人要加2份珍珠怎麼辦?這明顯不利程式的維護,必須有一種方法讓程式的修改最小,讓寫好的程式不用被修改才行。
|
這樣的問題是,每當有一種新配料出現,我們就要在奶茶類別裡修改至少2個 function:`addXXX()` 與 `cost()`,目前我們有3種飲料,所以要修改6個 function,更何況,如果客人要加2份珍珠怎麼辦?這明顯不利程式的維護,必須有一種方法讓程式的修改最小,讓寫好的程式不用被修改才行。
|
||||||
|
|
||||||
讓裝飾者模式來改善這個問題。首先讓配料跟飲料有同樣的界面,但是修改一下配料的 constructor,當然也要實作cost(),畢竟每個配料的價格不同:
|
讓裝飾者模式來改善這個問題。首先讓配料跟飲料有同樣的界面,但是修改一下配料的 constructor,當然也要實作 `cost()`,畢竟每個配料的價格不同:
|
||||||
```cpp
|
```cpp
|
||||||
class IngredientBubble : public Beverage {
|
class IngredientBubble : public Beverage {
|
||||||
IngredientBubble(Beverage* beverage) {
|
IngredientBubble(Beverage* beverage) {
|
||||||
@@ -218,7 +217,7 @@ class IngredientBubble : public Beverage {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
珍珠這個class的 constructor 的參數是任何一個 Beverage,現在飲料被包在珍珠裡面,由珍珠來決定飲料最後的價格是多少。現在我們可以動態的決定飲料的組成,假設點一杯紅茶,加一些配料:
|
珍珠這個 class 的 constructor 的參數是任何一個 Beverage,現在飲料被包在珍珠裡面,由珍珠來決定飲料最後的價格是多少。現在我們可以動態的決定飲料的組成,假設點一杯紅茶,加一些配料:
|
||||||
```cpp
|
```cpp
|
||||||
int main() {
|
int main() {
|
||||||
...
|
...
|
||||||
@@ -237,6 +236,5 @@ int main() {
|
|||||||
|
|
||||||
可以看到第一個變數是飲料,然後被包珍珠裡面,變成珍珠紅茶,再被包到紅豆裡面,變成紅豆珍珠紅茶,再被包到仙草裡面,變成仙草紅豆珍珠紅茶,到這樣的好處是:
|
可以看到第一個變數是飲料,然後被包珍珠裡面,變成珍珠紅茶,再被包到紅豆裡面,變成紅豆珍珠紅茶,再被包到仙草裡面,變成仙草紅豆珍珠紅茶,到這樣的好處是:
|
||||||
1. 有新的配料就寫新配料的 class
|
1. 有新的配料就寫新配料的 class
|
||||||
2. 因為可以動態的組合,原本寫好的飲料class就不用在去動它了,愈少修改,愈少 bug
|
2. 因為可以動態的組合,原本寫好的飲料 class 就不用在去動它了,愈少修改,愈少 bug
|
||||||
3. 我們可以動態的組合配料,要加2份以上也沒有問題
|
3. 我們可以動態的組合配料,要加2份以上也沒有問題
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user