設計模式是一套被反覆使用、多數人知曉的、通過分類編目的、代碼設計經驗的總結,使用設計模式的目的是提升代碼的可重用性,讓代碼更容易被他人理解,並保證代碼可靠性。它是代碼編制真正實現工程化。html
四個關鍵元素:(1) Pattern Name, (2) Problem, (3) Solution, (4) Consequences.sql
From: 史上最全設計模式導學目錄(完整版)數據庫
Ref: 菜鳥教程之抽象工廠 json
六個建立型模式中的前三個。設計模式
簡單工廠模式-Simple Factory Pattern【學習難度:★★☆☆☆,使用頻率:★★★☆☆】安全
工廠三兄弟之簡單工廠模式(一):圖表庫的設計函數
工廠三兄弟之簡單工廠模式(二):簡單工廠模式概述學習
工廠三兄弟之簡單工廠模式(三):圖表庫的簡單工廠模式解決方案spa
工廠三兄弟之簡單工廠模式(四):圖表庫解決方案的改進,簡單工廠模式的簡化,簡單工廠模式總結.net
工廠方法模式-Factory Method Pattern【學習難度:★★☆☆☆,使用頻率:★★★★★】
工廠三兄弟之工廠方法模式(一):日誌記錄器的設計
工廠三兄弟之工廠方法模式(二):工廠方法模式概述
工廠三兄弟之工廠方法模式(三):日誌記錄器的工廠方法模式解決方案,反射與配置文件
工廠三兄弟之工廠方法模式(四):重載的工廠方法,工廠方法的隱藏,工廠方法模式總結
抽象工廠模式-Abstract Factory Pattern【學習難度:★★★★☆,使用頻率:★★★★★】
工廠三兄弟之抽象工廠模式(一):界面皮膚庫的初始設計
工廠三兄弟之抽象工廠模式(二):產品等級結構與產品族
工廠三兄弟之抽象工廠模式(三):抽象工廠模式概述
工廠三兄弟之抽象工廠模式(四):界面皮膚庫的抽象工廠模式解決方案
工廠三兄弟之抽象工廠模式(五):「開閉原則」的傾斜性,抽象工廠模式總結
Abstract Factory Pattern 是重難點
一個工廠通常會生產一系列具備相關性的產品,即產品族。
在不一樣的工廠(大環境下)可能生產同一系列的產品族,具備類似的產品等級結構。
首先,「鏈接數據庫」 的過程是對外「屏蔽的「;
接着,獲得的工廠所包含的方法是統一的。這裏對於靜態語言而言,每每經過接口實現。
def main():
# 但願 connect_to 能夠處理各類數據庫文件,那就返回合適的工廠 # 而工廠實際上是「包含了許多方法」的集合,也就是一個特殊的類 sqlite_factory = connect_to('data/person.sq3') print() xml_factory = connect_to('data/person.xml') xml_data = xml_factory.parsed_data
liars = xml_data.findall(".//{}[{}='{}']".format('person', 'lastName', 'Liar')) print('found: {} persons'.format(len(liars))) for liar in liars: print('first name: {}'.format(liar.find('firstName').text)) print('last name: {}'.format(liar.find('lastName').text)) [print('phone number ({})'.format(p.attrib['type']), p.text) for p in liar.find('phoneNumbers')] print() json_factory = connect_to('data/donut.json') json_data = json_factory.parsed_data
print('found: {} donuts'.format(len(json_data))) for donut in json_data: print('name: {}'.format(donut['name'])) print('price: ${}'.format(donut['ppu'])) [print('topping: {} {}'.format(t['id'], t['type'])) for t in donut['topping']]
factory 等價於 connection_factory(filepath) 初始化了一個 」特定的類「。
同時也就意味着:添加一個產品須要修改下面的函數,這不是很符合「開閉原則」。
# factory:根據參數返回合適的工廠產品 def connection_factory(filepath): if filepath.endswith('json'): connector = JSONConnector elif filepath.endswith('xml'): connector = XMLConnector else: # 由於有「爲保證安全」的connect_to層 raise ValueError('Cannot connect to {}'.format(filepath))
# 這裏返回的已是一個」實例」 return connector(filepath) # 看上去像是專門爲了factory變量的安全考慮 def connect_to(filepath): factory = None try: factory = connection_factory(filepath) # 簡單模式下,只有一個工廠 except ValueError as ve: print(ve) return factory
類圖符號的學習,參考:類圖
類名(Class):每一個類都必須有一個名字,類名是一個字符串。
屬性(Attributes):屬性是指類的性質,即類的成員變量。類能夠有任意多個屬性,也能夠沒有屬性。
操做(Operations):操做是類的任意一個實例對象均可以使用的行爲,操做是類的成員方法。
將一個類的對象做爲另外一個類的屬性。
單向關聯
雙向關聯
前者是弱關係;後者是強關係;
組合關係,表示總體與部分的關係。
可是與聚合不一樣此關係是總體與部分是同生共死關係,即若是總體對象銷燬了部分也會被銷燬。
Driver是一個總體,Car也是總體,不是總體與部分關係。
可是,Driver中使用了Car的move方法,從而造成了「依賴關係」。
繼承(extends)關係,父類與子類關係。
類實現(implements)了接口。當多個類有相似的行爲方式的時候咱們一般會使用接口。
首先,「遊戲開始play」 的過程是對外「屏蔽的「;
接着,獲得的工廠所包含的方法是統一的。這裏對於靜態語言而言,每每經過接口實現。
class GameEnvironment: # 工廠類 def __init__(self, factory): self.hero = factory.make_character() self.obstacle = factory.make_obstacle() def play(self): self.hero.interact_with(self.obstacle) # 創建好產品之間的關係
def main(): name = input("Hello. What's your name? ") valid_input = False while not valid_input: valid_input, age = validate_age(name) game = FrogWorld if age < 18 else WizardWorld # <---- 關鍵的一個句子 environment = GameEnvironment(game(name)) # <---- 抽象工廠的"工廠"是"類";參數是類的類! environment.play()
Goto: 抽象工廠模式和工廠模式的區別?【三種槍的例子比較不錯】
重要的兩個問題:
抽象工廠的工廠是類;工廠方法的工廠是方法。
抽象工廠的工廠類就作一件事情生產產品。生產的產品給客戶端使用,毫不給本身用。
普通工廠產出是一個產品(實例),抽象工廠產出是一個抽象(接口)。
區別在於,若添加一個新的產品,前者是修改工廠,後者是建立新工廠(符合「閉合原則」)。
其實,抽象工廠多了一個「抽象的部分」從而間接調用「參數類(產品)」的方法。
End.