1. 程式人生 > >Python設計模式(2):創建型

Python設計模式(2):創建型

reg target ice cti lov term concrete The 延遲

1. Factory Method(工廠方法)

技術分享圖片

意圖:定義一個用於創建對象的接口,讓子類決定實例化哪一個類。Factory Method使一個類的實例化延遲到其子類。

適用性:

  • 當一個類不知道它所必須創建的對象的類的時候。
  • 當一個類希望由它的子類來指定它所創建的對象的時候。
  • 當類將創建對象的職責委托給多個幫助子類中的某一個,並且你希望將哪一個幫助子類是代理者這一信息局部化的時候。
#!/usr/bin/python
#coding:utf8
‘‘‘
Factory Method
‘‘‘

class ChinaGetter:
    """A simple localizer a la gettext"""
    def __init__(self):
        self.trans = dict(dog=u"小狗", cat=u"小貓")

    def get(self, msgid):
        """We‘ll punt if we don‘t have a translation"""
        try:
            return self.trans[msgid]
        except KeyError:
            return str(msgid)


class EnglishGetter:
    """Simply echoes the msg ids"""
    def get(self, msgid):
        return str(msgid)


def get_localizer(language="English"):
    """The factory method"""
    languages = dict(English=EnglishGetter, China=ChinaGetter)
    return languages[language]()

# Create our localizers
e, g = get_localizer("English"), get_localizer("China")
# Localize some text
for msgid in "dog parrot cat bear".split():
    print(e.get(msgid), g.get(msgid))

2. Abstract Factory(抽象工廠)

技術分享圖片

意圖:提供一個創建一系列相關或相互依賴對象的接口,而無需指定它們具體的類。

適用性:

  • 一個系統要獨立於它的產品的創建、組合和表示時。

  • 一個系統要由多個產品系列中的一個來配置時。

  • 當你要強調一系列相關的產品對象的設計以便進行聯合使用時。

  • 當你提供一個產品類庫,而只想顯示它們的接口而不是實現時。

#!/usr/bin/python
#coding:utf8
‘‘‘
Abstract Factory
‘‘‘

import random

class PetShop:
    """A pet shop"""

    def __init__(self, animal_factory=None):
        """pet_factory is our abstract factory.
        We can set it at will."""

        self.pet_factory = animal_factory

    def show_pet(self):
        """Creates and shows a pet using the
        abstract factory"""

        pet = self.pet_factory.get_pet()
        print("This is a lovely", str(pet))
        print("It says", pet.speak())
        print("It eats", self.pet_factory.get_food())


# Stuff that our factory makes

class Dog:
    def speak(self):
        return "woof"

    def __str__(self):
        return "Dog"


class Cat:
    def speak(self):
        return "meow"

    def __str__(self):
        return "Cat"


# Factory classes

class DogFactory:
    def get_pet(self):
        return Dog()

    def get_food(self):
        return "dog food"


class CatFactory:
    def get_pet(self):
        return Cat()

    def get_food(self):
        return "cat food"


# Create the proper family
def get_factory():
    """Let‘s be dynamic!"""
    return random.choice([DogFactory, CatFactory])()


# Show pets with various factories
if __name__ == "__main__":
    shop = PetShop()
    for i in range(3):
        shop.pet_factory = get_factory()
        shop.show_pet()
        print("=" * 20)

3. Builder(建造者)

技術分享圖片

意圖:將一個復雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。

適用性:

  • 當創建復雜對象的算法應該獨立於該對象的組成部分以及它們的裝配方式時。

  • 當構造過程必須允許被構造的對象有不同的表示時。

#!/usr/bin/python
#coding:utf8

"""
    Builder
"""

# Director
class Director(object):
    def __init__(self):
        self.builder = None

    def construct_building(self):
        self.builder.new_building()
        self.builder.build_floor()
        self.builder.build_size()

    def get_building(self):
        return self.builder.building


# Abstract Builder
class Builder(object):
    def __init__(self):
        self.building = None

    def new_building(self):
        self.building = Building()


# Concrete Builder
class BuilderHouse(Builder):
    def build_floor(self):
        self.building.floor = ‘One‘

    def build_size(self):
        self.building.size = ‘Big‘


class BuilderFlat(Builder):
    def build_floor(self):
        self.building.floor = ‘More than One‘

    def build_size(self):
        self.building.size = ‘Small‘


# Product
class Building(object):
    def __init__(self):
        self.floor = None
        self.size = None

    def __repr__(self):
        return ‘Floor: %s | Size: %s‘ % (self.floor, self.size)


# Client
if __name__ == "__main__":
    director = Director()
    director.builder = BuilderHouse()
    director.construct_building()
    building = director.get_building()
    print(building)
    director.builder = BuilderFlat()
    director.construct_building()
    building = director.get_building()
    print(building)

4. Prototype(原型)

技術分享圖片

意圖:用原型實例指定創建對象的種類,並且通過拷貝這些原型創建新的對象。

適用性:

  • 當要實例化的類是在運行時刻指定時,例如,通過動態裝載。
  • 為了避免創建一個與產品類層次平行的工廠類層次時。
  • 當一個類的實例只能有幾個不同狀態組合中的一種時。建立相應數目的原型並克隆它們可能比每次用合適的狀態手工實例化該類更方便一些。
#!/usr/bin/python
#coding:utf8
‘‘‘
Prototype
‘‘‘

import copy

class Prototype:
    def __init__(self):
        self._objects = {}

    def register_object(self, name, obj):
        """Register an object"""
        self._objects[name] = obj

    def unregister_object(self, name):
        """Unregister an object"""
        del self._objects[name]

    def clone(self, name, **attr):
        """Clone a registered object and update inner attributes dictionary"""
        obj = copy.deepcopy(self._objects.get(name))
        obj.__dict__.update(attr)
        return obj


def main():
    class A:
        def __str__(self):
            return "I am A"

    a = A()
    prototype = Prototype()
    prototype.register_object(‘a‘, a)
    b = prototype.clone(‘a‘, a=1, b=2, c=3)

    print(a)
    print(b.a, b.b, b.c)


if __name__ == ‘__main__‘:
    main()

參考文章

https://www.cnblogs.com/Liqiongyu/p/5916710.html

Python設計模式(2):創建型