《Head First 設計模式》筆記3

2021-08-18 01:11:06 字數 2843 閱讀 9190

動態地將責任附加到物件上。若要擴充套件功能,裝飾者提供了比繼承更有彈性的替代方案。

設計原則四:類應該對擴充套件開放,對修改關閉。

如果使用過 python,應該聽過裝飾器,雖然概念有點不同,但都是通過動態新增的方式給物件擴充套件功能。

星巴克的訂單系統系統中有個飲料抽象類 beverage,店內的飲料都必須繼承該類:

abstract class beverage 

// 飲料價錢

public

abstract

float

cost();

}

其中一些飲料:

class coffee extends beverage 

@override

public

float

cost()

}class milk extends beverage

@override

public

float

cost()

}// ...

現在,客戶想要在買的飲料裡加點調味料,比如買了杯咖啡,要加點牛奶、豆漿、巧克力等。這就需要訂單系統在統計飲料**時加上調味料的**。

每種可能的調味料的飲料都新建乙個類:

class coffeewithmilk extends beverage 

}class milkwithcoffee extends beverage

}// ....

很明顯,調味料有很多,飲料也有很多,如果只加一種調味料,那搭配起來也有非常多的可能,如果都新建乙個類,那麼就會造成「類**」。而且這些調味料的**如果發生變化,就要將涉及的飲料都修改一遍,嚴重違反了設計原則中的「將變化與不變化的**分開」。

既然違反了變化的原則,那麼嘗試把這些變化的調味料都放在飲料抽象類 beverage 中?

abstract class beverage 

// 計算好新增的調味料**,讓子類直接呼叫

public

float

cost()

if (hasmilk())

return sum;

}protected

boolean

hascoffee()

protected

void

setcoffee(boolean coffee)

protected

boolean

hasmilk()

protected

void

setmilk(boolean milk)

}

飲料只要設定好新增的調味料,最後計算下自身花費就好了:

class coffee extends beverage 

}class milk extends beverage

}

呼叫:

public

class

main

}

現在沒有了「類**」,就算調料**發生變化,只要修改下抽象類就好了,但是真的沒問題了嗎?

有問題,而且挺多的:

1. 如果出現新的調味料,就需要在抽象類新增新的布林值成員,cost 方法也需要新增新的判斷,還要分別新增乙個 setter 和乙個 getter,如果是刪除乙個調味料呢?

2. 對於有些飲料來說,某些調味料並不能加(會拉肚子的!),比如冰紅茶 + 牛奶?

3. 如果客戶要一杯咖啡,加兩份牛奶呢?

不改變原有的飲料抽象和具體的飲料:

abstract class beverage 

public

abstract

float

cost();

}

class coffee extends beverage 

@override

public

float

cost()

}

新增調味料(condiment)裝飾者:

abstract class condimentdecorator extends beverage
調味料繼承調味料裝飾者:

class milk extends condimentdecorator 

@override

public string getdescription()

@override

public

float

cost()

}class mocha extends condimentdecorator

@override

public string getdescription()

@override

public

float

cost()

}

public

class

main

}

輸出:

coffee

3.2cof

fee+

milk

+moc

ha3.2co

ffee

+mil

k+mo

ch

a3.9

coffee + milk + milk + milk + mocha + mocha $5.0999994

Head First 設計模式筆記

將變化部分和不變部分分離出來,讓 適應變化 封裝變化 針對介面程式設計,而不是針對實現程式設計 即,將一類行為抽象成行為類介面,可以應對變化,符合原則1 多用組合,少用繼承 這條原則,是建立在原則2的基礎上的,好處是系統有很大的彈性,執行時可以動態改變物件的行為 例如 策略模式 定義演算法簇 學會使...

Head First 設計模式筆記

1.找出應用中可能變化的地方,將它們獨立出來。不要和那些不需要變化的部分混在一起 2.針對介面程式設計,而不是針對實現程式設計 針對 介面程式設計 的意思是 針對超型別程式設計 針對介面程式設計關鍵在於多型。利用多型程式設計師可以針對超型別程式設計,編譯器執行會根據實際情況執行到真正的行為,而不會將...

head first 設計模式 工廠模式筆記

工廠模式 是舉了個做pizza的例子 有pizzastore抽象類裡邊有個pizza物件變數,orderpizza中裡面有個方法 叫做createpizza,同時外面定義了乙個createpizza抽象方法,然後實現裡面有個方法 叫做createpizza,此方法更具不同的引數new不同的對 象,如...