第一天:建立型模式--工廠方法模式
阿新 • • 發佈:2019-01-24
零、建立型模式
開篇先簡單說一下建立型模式,它關注物件的建立過程,將類的例項化過程進行了抽象,能夠將軟體模組中物件的建立和物件的使用分離。使得相同的建立過程可以多次複用,且修改二者中的任一個對另一個幾乎不造成任何影響。
建立型模式有五種:簡單工廠模式、工廠方法模式、抽象工廠模式、建造者模式、原型模式、單例模式。這裡面我們只講常用的工廠方法模式、抽象工廠模式和原型模式。
一、工廠方法
- 什麼是工廠方法:
它是一個方法,對不同的輸入引數返回不同的物件。在工廠方法模式中,我們執行單個函式,傳入一個引數,並不要求知道任何關於物件如何實現以及來自哪裡的細節
二、身邊的例子
- 早點攤買粥
我只需要告訴早點攤的老闆要購買的粥的名字(比如皮蛋瘦肉粥),老闆就會給我所購買的粥,具體這碗粥是怎麼做出來的,以及是來自其他早點攤或者老闆自己做的,這些我都不需要知道。 - Django 框架
Django 是做Python Web開發常用的框架之一,其中表單欄位的建立就使用到了工廠方法模式。forms模組支援不同型別的建立和定製。
三、什麼情況下使用
- 需要將物件的使用和建立解耦的時候;
- 需要提高應用的效能和記憶體使用率的時候;
- 建立物件的程式碼分佈在多個不同的地方,且不僅僅在一個方法中,導致無法跟蹤這些物件的時候。
四、應用案例
下面我們使用程式碼演示以下工廠方法的使用,該例子將利用工廠方法解析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方法中,我們在呼叫的時候,只需向該方法傳入檔案的儲存路徑,這個方法便能返回一個我們需要的物件,然後處理這個物件,使物件內容在控制檯輸出。