• Python设计模式(2):创建型


    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

  • 相关阅读:
    Linux常用命令 rm命令详解
    Python 面向对象(一)入门篇
    Python习题集(十六)
    Python 面向对象(三)公共变量,受保护变量,私有变量
    洛谷P1309 瑞士轮(归并排序)
    185. [USACO Oct08] 挖水井
    洛谷 P1078 文化之旅(CODEVS 1316)
    CODEVS 1074 食物链 2001年NOI全国竞赛(洛谷 P2024)
    186. [USACO Oct08] 牧场旅行
    157. [USACO Nov07] 奶牛跨栏
  • 原文地址:https://www.cnblogs.com/mac1993/p/9300866.html
Copyright © 2020-2023  润新知