(轉自精通Python設計模式)Python設計模式之建立型模式——1.原廠模式

來源:互聯網
上載者:User

標籤:訪問   思想   流行   ext   ase   .com   enc   .text   author   

  在工廠設計模式中,用戶端可以請求一個對象,而無需知道這個對象來自哪裡;也就是,使用哪個類類產生這個對象。工廠背後的思想是簡化對象的建立。與用戶端自己基於類執行個體化直接建立對象相比,基於一個中心化函數來實現,更易於追蹤建立了哪些對象。通過將建立對象的代碼和使用對象的代碼解耦,工廠能夠降低應用維護的複雜度。

  工廠通常有兩種形式:一種是Factory 方法,它是一個方法(或是一個函數),對不同的輸入參數返回不同的對象;第二種是抽象工廠,它是一組建立一系列相關事物對象的Factory 方法。

  1. Factory 方法

  在Factory 方法模式中,我們執行單個函數,傳入一個參數(提供資訊表明我們想要什麼),但並不要求知道任何關於對象如何?以及對象來自哪裡的細節。

  1.1 案例

  以下例子將使用Factory 方法來解析兩種流行的人類可讀檔案格式:XML和JSON。我們使用Python髮型版本內建的兩個庫(xml.etree.ElementTree和json)來處理XML和JSON,如下所示:

import xml.etree.ElementTree as etreeimport json

  下面是Factory 方法實現(factory_method.py)的完整代碼。

#!/usr/bin/env python# -*- coding: utf-8 -*-# @Date    : 2018/7/13 15:34# @Author  : Yaheng Wang ([email protected])# @Link    : http://www.wy2160640.github.io# @Version : 1.0import xml.etree.ElementTree as etreeimport jsonimport ioclass JSONConnector:    def __init__(self, filepath):        self.data = {}        with io.open(filepath, mode=‘r‘, encoding=‘utf-8‘) as f:            self.data = json.load(f)    @property    def parsed_data(self):        return self.dataclass XMLConnector:    def __init__(self, filepath):        self.tree = etree.parse(filepath)    @property    def parsed_data(self):        return self.treedef connection_factory(filepath):    if filepath.endswith(‘json‘):        connector = JSONConnector    elif filepath.endswith(‘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 factorydef main():    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))        for p in liar.find(‘phoneNumbers‘):            print(‘phone number ({})‘.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)))    for donut in json_data:        print(‘name: {}‘.format(donut[‘name‘]))        print(‘price: ${}‘.format(donut[‘ppu‘]))        for t in donut[‘topping‘]:            print(‘topping: {} {}‘.format(t[‘id‘], t[‘type‘]))if __name__ == ‘__main__‘:    main()

  2. 抽象工廠

  抽象工廠設計模式是抽象方法的一種泛化。概括來說,一個抽象工廠是(邏輯上的)一組Factory 方法,其中的每個Factory 方法負責產生不同種類的對象。

  2.1案例

  抽象工廠有一個優點,在使用Factory 方法時從使用者視角通常是看不到的,那就是抽象工廠能夠通過改變啟用的Factory 方法動態地(運行時)改變使用者行為。一個經典的例子是能夠讓使用者在使用應用時改變應用的觀感,而不需要終止應用然後重新啟動。

  想象一下,我們正在創造一個遊戲,或者想在應用中包含一個迷你遊戲讓使用者娛樂娛樂。我們希望至少包含兩個遊戲,一個面向孩子,一個面向成人。在運行時,基於使用者輸入,決定改建立哪個遊戲並運行。遊戲建立部分由一個抽象工廠維護。

  抽象工廠實現的完整代碼(abstract_factory.py)如下所示:

#!/usr/bin/env python# -*- coding: utf-8 -*-# @Date    : 2018/7/14 15:13# @Author  : Yaheng Wang ([email protected])# @Link    : http://www.wy2160640.github.io# @Version : 1.0class Frog:    def __init__(self, name):        self.name = name    def __str__(self):        return self.name    def interact_with(self, obstacle):        print(‘{} the Frog encounters {} and {}!‘.format(self, obstacle, obstacle.action()))class Bug:    def __str__(self):        return ‘a bug‘    def action(self):        return ‘eats it‘class FrogWorld:    def __init__(self, name):        print(self)        self.player_name = name    def __str__(self):        return ‘\n\n\t------ Frog World ------‘    def make_character(self):        return Frog(self.player_name)    def make_obstacle(self):        return Bug()class Wizard:    def __init__(self, name):        self.name = name    def __str__(self):        return self.name    def interact_with(self, obstacle):        print(‘{} the Wizard battles against {} and {}!‘.format(self, obstacle, obstacle.action()))class Ork:    def __str__(self):        return ‘an evil ork‘    def action(self):        return ‘kills it‘class WizardWorld:    def __init__(self, name):        print(self)        self.player_name = name    def __str__(self):        return ‘\n\n\t------ Wizard World ------‘    def make_character(self):        return Wizard(self.player_name)    def make_obstacle(self):        return Ork()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 validate_age(name):    try:        age = raw_input(‘Welcome {}. How old are you?\n‘.format(name))        age = int(age)    except ValueError as err:        print("Age {} is invalid, please try again...".format(age))        return (False, age)    return (True, age)def main():    name = raw_input("Hello. What‘s your name?\n")    valid_input = False    while not valid_input:        valid_input, age = validate_age(name)    game = FrogWorld if age < 18 else WizardWorld    enviroment = GameEnvironment(game(name))    enviroment.play()if __name__ == ‘__main__‘:    main()

  3.小結

  兩種模式都可以用於以下幾種情境:(a)想要追蹤對象的建立時,(b)想要將對象的建立與使用解耦時,(c)想要最佳化應用的效能和資源佔用時。

  工廠設計方法模式的實現是一個不屬於任何類的單一函數,負責單一種類對象(一個形狀、一個連接點或者其他對象)的建立。作為樣本,我們實現了一個Factory 方法,提供了訪問XML和JSON檔案的能力。

  抽象工廠設計模式的實現是同屬於單個類的許多個Factory 方法用於建立一系列種類的相關對象(一輛車的組件、一個遊戲的環境,或者其他對象)。作為抽象工廠實現的樣本,我們完成了一個迷你遊戲,示範了如何在單個類中使用多個相關工廠。

(轉自精通Python設計模式)Python設計模式之建立型模式——1.原廠模式

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.