Python三种设计模式

一、Python创建型设计模式

1、工厂模式(Factory):解决对象创建问题

2、构造模式(Builder):控制复杂对象的创建

3、原型模式(Prototype):通过原型的克隆创建新的实例

4、单例模式(Brog/Singleton):一个类只能创建同一个对象

5、对象池模式(Pool):预先分配同一类型的一组实例

6、惰性计算模式(Lazy Evaluaion):延迟计算(Python的property)

 

(1)工厂模式

          解决对象创建问题,解耦对象的创建和使用,包括工厂方法和抽象工厂

# 工厂方法的一个例子
class Dog:
    def speak(self):
        print("WangWang!")

class Cat:
    def speak(self):
        print("MiaoMiao!")

def animal(speak_type):
    if speak_type == 'Dog':
        return Dog()
    elif speak_type == 'Cat':
        return Cat()

(2)构造模式

       用来控制复杂对象的构造,创建和表示分离。比如买电脑,工厂模式直接给你电脑而构造模式则允许自己自定义电脑的配置,组装后给你

# 构造模式的一个例子
class Computer:
    def __init__(self, serial_number):
        self.serial = serial_number
        self.memory = None
        self.hdd = None
        self.gpu = None
    
    def __str__(self):
        info = ('Memory: {}GB'.format(self.memory),
                'Hard Disk: {}GB'.format(self.hdd),
                'Graphics Card: {}'.format(self.gpu))    
        return '\n'.join(info)

class ComputerBuilder:
    def __init__(self):
        self.computer = Computer('XXXXXXXX')
    
    def configure_memory(self, amount):
        self.computer.memory = amount

    def configure_hdd(self, amount):
        self.computer.hdd = amount

    def configure_gpu(self, gpu_model):
        self.computer.gpu = gpu_model

class HardwareEngineer:
    def __init__(self):
        self.builder = None
    
    def construct_computer(self, memory, hdd, gpu):
        self.builder = ComputerBuilder()
        [step for step in (self.builder.configure_memory(memory),
                           self.builder.configure_hdd(hdd),
                           self.builder.configure_gpu(gpu))]                

    @property
    def computer(self):
        return self.builder.computer

engineer = HardwareEngineer()
engineer.construct_computer(hdd=1024, memory=32, gpu='GeForce GTX 2080 Ti')
computer = engineer.computer
print(computer)

(3)原型模式

       通过克隆原型来创建新的实例,可以使用相同的原型,通过修改部分属性来创建新的示例,用途:对于一些创建实例开销比较高的地方可以使用原型模式

(4)单例模式

      一个类创建出来的对象是同一个,例如:Python模块就是单例的,多次导入只会导入一次。可以使用共享同一个实例来创建单例模式

# 单例模式
class Singleton:
    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, '_instance'):
            _instance = super().__new__(cls, *args, **kwargs)
            cls._instance = _instance
        return cls._instance

 

二、结构型设计模式

1、装饰器模式(Decorater):无需子类化扩展对象功能

2、代理模式(Proxy):把一个对象的操作代理到另一个对象

3、适配器模式(Adapter):通过一个间接层适配统一接口

4、外观模式(Facade):简化复杂对象的访问问题

5、享元模式(Flyweight):通过对象复用(池)改善资源利用,比如连接池

6、Model-View-Controller(MVC):解耦显示逻辑和业务逻辑

 

(1)代理模式

      把对象的操作代理到另一个对象,这里可以用到Stack/Queue,把操作代理到deque。

# 代理模式 —— Stack
from collections import deque

class Stack(object):
    
    def __init__(self):
        self._deque = deque()

    def push(self, value):
        return self._deque.append(value)

    def pop(self):
        return self._deque.pop()

    def empty(self):
        return len(self._deque) == 0

(2)适配器模式

        把不同的对象的接口适配到同一个接口,当需要不同的对象统一接口的时候可以使用适配器模式

class Dog(object):
    def __init__(self):
        self.name = "Dog"

    def bark(self):
        return "woof"

class Cat(object):
    def __init__(self):
        self.name = "Cat"

    def miao(self):
        return "miao"


class Adapter:
    def __init__(self, obj, **adapted_methods):
        self.obj = obj
        self.__dict__.update(adapted_methods)

    def __getattr__(self, attr):
        return getattr(self.obj, attr)

objects = []
dog = Dog()
objects.append(Adapter(dog, make_noise=dog.bark))
cat = Cat()
objects.append(Adapter(cat, make_noise=cat.bark))
for obj in objects:
    print("A {0} goes {1}".format(obj.name, obj.make_noise()))

三、行为型模式

1、迭代器模式(Iterator):通过统一的接口迭代对象

2、观察者模式(Observer):对象发生改变的时候,观察者执行相应的动作

3、策略模式(Strategy):针对不同规模输入使用不同的策略

 

(1)迭代器模式

       Python内置对迭代器模式的支持,可以用for遍历各种Iterable的数据类型,不可迭代对象需要用(__next__和__iter__)实现迭代器,可以迭代的对象只使用__iter__

# 迭代器模式 —— 可以迭代的Stack
from collections import deque

class Stack(object):
    
    def __init__(self):
        self._deque = deque()

    def push(self, value):
        return self._deque.append(value)

    def pop(self):
        return self._deque.pop()

    def empty(self):
        return len(self._deque) == 0
    
    def __iter__(self):
        res = []
        for i in self._deque:
            res.append(i)
        for i in reversed(res):
            yield i

 

(2)观察者模式

          发布订阅最为常见,发布订阅用于解耦逻辑,可以通过回调等方式实现,当条件发生时可以使用相应的回调函数

# 发布订阅模式

class Publisher:
    def __init__(self):
        self.observers = []

    def add(self, observer):
        if observer not in self.observers:
            self.observers.append(observer)
        else:
            print('Failed to add : {}'.format(observer))

    def remove(self, observer):
        try:
            self.observers.remove(observer)
        except:
            print('Failed to remove : {}'.format(observer))

    def notify(self):
        [o.notify_by(self) for o in self.observers]

class Formatter(Publisher):
    def __init__(self, name):
        super().__init__()
        self.name = name
        self._data = 0

    @property
    def data(self):
        return self._data

    @data.setter
    def data(self, new_value):
        self._data = int(new_value)
        self.notify()

class BinaryFormatter:
    
    def notify_by(self, publisher):
        print("{} : {} has now bin data = {}".format(
                            type(self).__name__,
                            publisher.name,
                            bin(publisher.data)))

(3)策略模式

        根据不同输入采用不同的策略,对外暴露统一的接口,内部采用不同的策略计算

# 策略模式
class Order:
    def __init__(self, price,discount_strategy=None):
        self.price = price
        self.discount_strategy = discount_strategy

    def price_after_discount(self):
        if self.discount_strategy:
            discount = self.discount_strategy(self)
        else:
            discount = 0
        return self.price - discount

    def __repr__(self):
        fmt = "<Price: {}, price after discount: {}>"
        return fmt.format(self.price, self.price_after_discount())

 

    原文作者:CircleYua
    原文地址: https://blog.csdn.net/kingyuan666/article/details/87990941
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞