1. 程式人生 > >第一天:建立型模式--工廠方法模式

第一天:建立型模式--工廠方法模式

零、建立型模式

開篇先簡單說一下建立型模式,它關注物件的建立過程,將類的例項化過程進行了抽象,能夠將軟體模組中物件的建立和物件的使用分離。使得相同的建立過程可以多次複用,且修改二者中的任一個對另一個幾乎不造成任何影響。
建立型模式有五種:簡單工廠模式工廠方法模式抽象工廠模式建造者模式原型模式單例模式。這裡面我們只講常用的工廠方法模式、抽象工廠模式和原型模式。

一、工廠方法

  • 什麼是工廠方法:
    它是一個方法,對不同的輸入引數返回不同的物件。在工廠方法模式中,我們執行單個函式,傳入一個引數,並不要求知道任何關於物件如何實現以及來自哪裡的細節

二、身邊的例子

  • 早點攤買粥
    我只需要告訴早點攤的老闆要購買的粥的名字(比如皮蛋瘦肉粥),老闆就會給我所購買的粥,具體這碗粥是怎麼做出來的,以及是來自其他早點攤或者老闆自己做的,這些我都不需要知道。
  • Django 框架
    Django 是做Python Web開發常用的框架之一,其中表單欄位的建立就使用到了工廠方法模式。forms模組支援不同型別的建立和定製。

三、什麼情況下使用

  1. 需要將物件的使用和建立解耦的時候;
  2. 需要提高應用的效能和記憶體使用率的時候;
  3. 建立物件的程式碼分佈在多個不同的地方,且不僅僅在一個方法中,導致無法跟蹤這些物件的時候。

四、應用案例

下面我們使用程式碼演示以下工廠方法的使用,該例子將利用工廠方法解析xml和json檔案

#使用python 自帶的xml和json解析方法
import xml.etree.ElementTree as etree
import
json # Json 解析類 class JSONConnector: def __init__(self, filepath): self.data = dict() with open(filepath, mode='r', encoding='utf-8') as f: self.data = json.load(f) @property def parsed_data(self): return self.data # Xml 解析類 class XMLConnector: def
__init__(self, filepath):
self.tree = etree.parse(filepath) @property def parsed_data(self): return self.tree # 定義解析工廠方法 def connection_factory(filepath): # 根據字尾名判斷傳入的檔案型別 if filepath.endswith('json'): # 例項化Json解析類 connector = JSONConnector elif filepath.endswith('xml'): # 例項化Xml解析類 connector = XMLConnector else: # 如果不是兩種格式,則丟擲錯誤 raise ValueError('Cannot connect to {} '.format(filepath)) return connector(filepath) # 包裝工廠方法,增加異常攔截處理 def connect_to(filepath): factory = None try: factory = connection_factory(filepath) except ValueError as ve: print(ve) return factory def main(): sqlite_factory = connect_to('data/person.sp3') xml_factory = connect_to('data/contact_information.xml') xml_data = xml_factory.parsed_data persons = xml_data.findall(".//{}".format('person')) print('found: {} persons '.format(len(persons))) print('----------------------------------------------------') # 輸出xml中的內容 for ps in persons: print('姓名:{}'.format(ps.find('name').text)) print('年齡:{}'.format(ps.find('age').text)) for a in ps.find('addresses'): print('{}地址:{}'.format(a.attrib['type'], a.text)) for p in ps.find('phoneNumbers'): print('{}電話:{}'.format(p.attrib['type'], p.text)) print('----------------------------------------------------') json_factory = connect_to('data/donut.json') json_data = json_factory.parsed_data print('found:{} donuts '.format(len(json_data))) # 輸出json內容 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']] print('----------------------------------------------------') if __name__ == '__main__': main()

在這段程式碼中表格,我們定義了兩個類,一個是解析JSON檔案的類,一個是解析XML檔案的類,這兩個類中都有一個共同的方法parsed_data,這個方法用來返回解析出來的資料。我們又定義了一個工廠方法connection_factory,通過判斷檔案的副檔名類例項化對應的解析類。main方法中,我們在呼叫的時候,只需向該方法傳入檔案的儲存路徑,這個方法便能返回一個我們需要的物件,然後處理這個物件,使物件內容在控制檯輸出。