设计模式+创建型详解

一、设计模式简介

  1、什么是设计模式

    1.1、设计模式是经过总结、优化的,对我们经常会碰到的一些编程问题的可重用解决方案;

    1.2、一个设计模式并不像一个类或一个库那样能够直接作用于我们的代码。

    1.3、设计模式更为高级,它是一种必须在特定情形下实现的一种方法模板。

    1.4、设计模式不会绑定具体的编程语言

    1.5、一个好的设计模式应该能够用大部分编程语言实现(如果做不到全部的话,具体取决于语言特性)

    1.6、设计模式也是一把双刃剑,如果设计模式被用在不恰当的情形下将会造成灾难,进而带来无穷的麻烦。然而如果设计模式在正确的时间被用在正确地地方,它将是你的救星。

  2、设计模式的分类

    1、创建模式,提供实例化的方法,为适合的状况提供相应的对象创建方法。

    2、结构化模式,通常用来处理实体之间的关系,使得这些实体能够更好地协同工作。

    3、行为模式,用于在不同的实体建进行通信,为实体之间的通信提供更容易,更灵活的通信方法。

创建模式:
 
1. Factory Method(工厂方法)

2. Abstract Factory(抽象工厂)

3. Builder(建造者)

4. Prototype(原型)

5. Singleton(单例)
创建模式
结构化模式

6. Adapter Class/Object(适配器)

7. Bridge(桥接)

8. Composite(组合)

9. Decorator(装饰)

10. Facade(外观)

11. Flyweight(享元)

12. Proxy(代理)
结构化模式
行为模式

13. Interpreter(解释器)

14. Template Method(模板方法)

15. Chain of Responsibility(责任链)

16. Command(命令)

17. Iterator(迭代器)

18. Mediator(中介者)

19. Memento(备忘录)

20. Observer(观察者)

21. State(状态)

22. Strategy(策略)

23. Visitor(访问者)
行为模式

 

二、创建型

 1、Factory Method(工厂方法)

    定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method 使一个类的实例化延迟到其子类。

  适用性:

    1、当一个类不知道它所必须创建的对象的类的时候。

    2、当一个类希望由它的子类来指定它所创建的对象的时候。

    3、当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。

#!/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]()

if __name__ == '__main__':

    # 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))

###运行结果###
#dog 小狗
#parrot parrot
#cat 小猫
#bear bear
Factory Method

  

  2、Abstract Factory(抽象工厂)

  

  

 提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。 

  适用性:

    1、一个系统要独立于它的产品的创建、组合和表示时。

    2、一个系统要由多个产品系列中的一个来配置时。

    3、当你要强调一系列相关的产品对象的设计以便进行联合使用时。

    4、当你提供一个产品类库,而只想显示它们的接口而不是实现时。

#!/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)



###运行结果###
#This is a lovely Cat
#It says meow
#It eats cat food
#====================
#This is a lovely Cat
#It says meow
#It eats cat food
#====================
#This is a lovely Dog
#It says woof
#It eats dog food
#====================
Abstract Factory

  3、Builder(建造者模式) 

   

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

  适用性

    1、当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。

    2、当构造过程必须允许被构造的对象有不同的表示时。

#!/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)


###结果###
#Floor: One | Size: Big
#Floor: More than One | Size: Small
Builder

  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



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

def main():
    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()


###结果###
#I am A
#1 2 3
Prototype

  5、Singleton(单例模式)

 保证一个类仅有一个实例,并提供一个访问它的全局访问点。

  适用性

    1、当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时。

    2、当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时。

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


class Singleton(object):
    ''''' A python style singleton '''

    def __new__(cls, *args, **kw):
        if not hasattr(cls, '_instance'):
            org = super(Singleton, cls)
            cls._instance = org.__new__(cls )


        return cls._instance

class SingleSpam(Singleton):
    def __init__(self, s):
     self.s = s

    def __str__(self):
        return self.s


if __name__ == '__main__':
    s1 = SingleSpam('spam')
    print (id(s1), s1)
    s2 = SingleSpam('spa')
    print (id(s2), s2)
    print (id(s1), s1)



###结果###
#4356151000 spam
#4356151000 spa
#4356151000 spa
singleton
原文地址:https://www.cnblogs.com/ppzhang/p/14433646.html