【Abstract Thought】【Design Patterns】python实现所有个设计模式【上】

前言

山本无忧,因雪白头。水本无愁,因风起皱——《我欲封天》

设计模式不是必须的,不需要强迫自己使用设计模式。如果系统复杂了不知道怎么处理,可以看看设计模式中哪个可以帮帮。


         \;\\\;\\\;

简单的设计模式

1抽象工厂

产品类有一颗树,工厂也有一颗树,最高层的工厂直接产生最高层的产品就行。

调用的时候直接调用最高层的产品函数,只是创建的是new第二层、第三层的产品。

concrete具体的,discreet谨慎的

from __future__ import annotations    #这行必须放开头
from abc import ABC, abstractmethod






#第一层的工厂
class Factory(ABC):
    @abstractmethod
    def create_a(self) -> ProductA:
        pass
    @abstractmethod
    def create_b(self) -> ProductB:
        pass


#第二层的工厂
class ConcreteFactory1(Factory):
    def create_a(self) -> ProductA:
        return ConcreteProductA1()   #创建第二层的产品
    def create_b(self) -> ProductB:
        return ConcreteProductB1()   #创建第二层的产品

#第二层的工厂
class ConcreteFactory2(Factory):
    def create_a(self) -> ProductA:
        return ConcreteProductA2()    #创建第二层的产品
    def create_b(self) -> ProductB:
        return ConcreteProductB2()     #创建第二层的产品










#第一层的产品
class ProductA(ABC):
    @abstractmethod
    def run(self) -> str:
        pass

#第二层的产品
class ConcreteProductA1(ProductA):
    def run(self) -> str:
        return "ConcreteProductA1:run()"

#第二层的产品
class ConcreteProductA2(ProductA):
    def run(self) -> str:
        return "ConcreteProductA2:run()"

#第一层的产品
class ProductB(ABC):
    @abstractmethod
    def exec(self) -> None:
        pass
    @abstractmethod
    def another_exec(self, collaborator: ProductA) -> None:        #collaborator注解,用来避免错误
        pass

#第二层的产品
class ConcreteProductB1(ProductB):
    def exec(self) -> str:
        return "ConcreteProductB1:exec()"
    def another_exec(self, collaborator: ProductA) -> str:
        result = collaborator.run()
        print(result)
        return f"ConcreteProductB1:another_exec()"

#第二层的产品
class ConcreteProductB2(ProductB):
    def exec(self) -> str:
        return "ConcreteProductB2:exec()"
    def another_exec(self, collaborator: ProductA) -> str:
        result = collaborator.run()
        print(result)
        return f"ConcreteProductB2:another_exec()"







#客户代码
def client_code(factory: Factory) -> None:
    product_a = factory.create_a()
    product_b = factory.create_b()

    #执行产品B的函数,其中又会调用产品A的函数
    print(f"{product_b.exec()}")
    print(f"{product_b.another_exec(product_a)}", end="")



def main():
    #创建工厂1并执行
    client_code(ConcreteFactory1())
    print("\n")
    # 创建工厂1并执行
    client_code(ConcreteFactory2())

if __name__ == "__main__":
    main()




在这里插入图片描述

         \;\\\;\\\;

2工厂方法

结构更简单,适合单一类型产品

只在第二层、第三层才create,而抽象工厂第一层就create了

from __future__ import annotations
from abc import ABC, abstractmethod



#第一层工厂
class Factory(ABC):
    @abstractmethod
    def create(self):
        pass
    def exec(self) -> str:
        product = self.create()
        result = f"{product.run()}"
        return result

#第二层工厂
class ConcreteFactory1(Factory):
    def create(self) -> Product:
        return ConcreteProduct1()    #创建第二层产品

#第二层工厂
class ConcreteFactory2(Factory):
    def create(self) -> Product:
        return ConcreteProduct2()    #创建第二层产品





#第一层产品
class Product(ABC):
    @abstractmethod
    def run(self) -> str:
        pass

#第二层产品
class ConcreteProduct1(Product):
    def run(self) -> str:
        return "ConcreteProduct1:run()"

#第二层产品
class ConcreteProduct2(Product):
    def run(self) -> str:
        return "ConcreteProduct2:run()"



#客户代码
def client_code(f: Factory) -> None:
    a = f.create()    #第二层的工厂才能create
    a.run()
    print(f.exec())


def main():
    client_code(ConcreteFactory1())
    print("\n")
    client_code(ConcreteFactory2())


if __name__ == "__main__":
    main()

在这里插入图片描述

         \;\\\;\\\;

3建造者

1,产品可以分为不同部分;

  • 抽象工厂是一个产品一个类,建造者是多个产品一个类

2,构建与显示分开;

from __future__ import annotations
from abc import ABC, abstractmethod
from typing import Any


#第一层建造者
class Builder(ABC):
    @property
    @abstractmethod
    def product(self) -> None:
        pass
    @abstractmethod
    def produce_part_a(self) -> None:
        pass
    @abstractmethod
    def produce_part_b(self) -> None:
        pass
    @abstractmethod
    def produce_part_c(self) -> None:
        pass


#第二层建造者
class ConcreteBuilder1(Builder):
    def __init__(self) -> None:
        self.reset()
    def reset(self) -> None:
        self._product = Product1()
    @property        #让函数可以像属性一样被访问
    def product(self) -> Product1:
        old_p = self._product   #保存旧值
        self.reset()            #生成一个新值
        return old_p            #返回旧值

    #建造各部分,就是把产品添加到产品的列表中
    def produce_part_a(self) -> None:
        self._product.add("PartA1")
    def produce_part_b(self) -> None:
        self._product.add("PartB1")
    def produce_part_c(self) -> None:
        self._product.add("PartC1")



#第一层产品
class Product1():
    def __init__(self) -> None:
        self.parts = []
    def add(self, part: Any) -> None:
        self.parts.append(part)
    def show(self) -> None:
        print(f"Product parts: {', '.join(self.parts)}", end="")



#管理者
class Manager:
    def __init__(self) -> None:
        self._builder = None
    @property            #获取属性builder
    def builder(self) -> Builder:
        return self._builder
    @builder.setter      #设置属性builder。有了获取和设置,可以直接使用builder当属性(封装了一下)
    def builder(self, builder: Builder) -> None:
        self._builder = builder
        
    def build_minimal_viable_product(self) -> None:
        self.builder.produce_part_a()
    def build_full_featured_product(self) -> None:
        self.builder.produce_part_a()
        self.builder.produce_part_b()
        self.builder.produce_part_c()




def Main():
    m = Manager()
    builder = ConcreteBuilder1()
    m.builder = builder

    print("Standard basic product: ")
    m.build_minimal_viable_product()    #只建造基础款产品
    builder.product.show()
    print("\n")

    print("Standard full featured product: ")
    m.build_full_featured_product()     #建造完整版产品
    builder.product.show()
    print("\n")

    print("Custom product: ")
    builder.produce_part_a()
    builder.produce_part_b()
    builder.product.show()

if __name__ == "__main__":
    Main()

在这里插入图片描述

         \;\\\;\\\;

4原形

原形是每一个实体,当中都有一个parent指向上一个,所以原形就是一个个连在一起和链表一样。

可以用在拷贝已有实例,

import copy

# 自引用实体类
class Entity:
    def __init__(self):
        self.parent = None
    def set_parent(self, parent):    #连接上一级
        self.parent = parent

# 组件类
class Component:
    def __init__(self, number, items, ref):
        self.items = items       #一个包含多种类型对象的列表
        self.number = number
        self.ref = ref           #引用的实体

    def __copy__(self):
        # 浅拷贝
        items = copy.copy(self.items)
        ref = copy.copy(self.ref)
        new = self.__class__(items, self.number, ref)
        new.__dict__.update(self.__dict__)
        return new

    def __deepcopy__(self, memo=None):
        # 深拷贝
        if memo is None:
            memo = {}
        items = copy.deepcopy(self.items, memo)
        ref = copy.deepcopy(self.ref, memo)
        new = self.__class__(items, self.number, ref)
        new.__dict__ = copy.deepcopy(self.__dict__, memo)
        return new


def main():
    # 创建一个包含多种类型对象的列表
    items = [1, {1, 2, 3}, [1, 2, 3]]

    # 创建一个自引用实体
    ref = Entity()

    # 创建一个组件实例
    component = Component(23, items, ref)

    # 设置自引用实体的父对象
    ref.set_parent(component)




    # 浅拷贝组件
    shallow_copied = copy.copy(component)

    # 修改浅拷贝组件的列表
    shallow_copied.items.append("another object")

    # 检查原始组件的列表是否受到影响
    if component.items[-1] == "another object":
        print("修改浅拷贝组件的列表,原始组件的列表也受到影响。")
    else:
        print("修改浅拷贝组件的列表,原始组件的列表不受影响。")

    # 修改原始组件的列表中的集合
    component.items[1].add(4)
    if 4 in shallow_copied.items[1]:
        print("修改原始组件的集合,浅拷贝组件的集合也受到影响。")
    else:
        print("修改原始组件的集合,浅拷贝组件的集合不受影响。")





    # 深拷贝组件
    deep_copied = copy.deepcopy(component)

    # 修改深拷贝组件的列表
    deep_copied.items.append("one more object")

    if component.items[-1] == "one more object":
        print("修改深拷贝组件的列表,原始组件的列表也受到影响。")
    else:
        print("修改深拷贝组件的列表,原始组件的列表不受影响。")

    # 修改原始组件的列表中的集合
    component.items[1].add(10)
    if 10 in deep_copied.items[1]:
        print("修改原始组件的集合,深拷贝组件的集合也受到影响。")
    else:
        print("修改原始组件的集合,深拷贝组件的集合不受影响。")

    # 检查深拷贝对象的自引用实体的父对象
    print(f"id(deep_copied.ref.parent): {id(deep_copied.ref.parent)}")
    print(f"id(deep_copied.ref.parent.ref.parent): {id(deep_copied.ref.parent.ref.parent)}")
    print("这表明深拷贝对象包含相同的引用,不会重复克隆。")

if __name__ == "__main__":
    main()

在这里插入图片描述

         \;\\\;\\\;

5单例

确保该类只有一个实例


#单例的meta类
class SingletonMeta(type):
    _instances = {}
    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            instance = super().__call__(*args, **kwargs)
            cls._instances[cls] = instance
        return cls._instances[cls]

#设置meta类
class Singleton(metaclass=SingletonMeta):
    def some_business_logic(self):
        print('do something.')



def Main():
    s1 = Singleton()
    s2 = Singleton()
    if id(s1) == id(s2):
        print("Singleton works, both variables contain the same instance.")
    else:
        print("Singleton failed, variables contain different instances.")

if __name__ == "__main__":
    Main()

在这里插入图片描述

         \;\\\;\\\;

6适配器

接口转换,把specific_request()转换成request()
表面上使用目标的request(),实际上使用被适配者的specific_request()

# 目标类,定义客户端期望的接口
class Target:
    def request(self) -> str:
        return "Target:request"


# 被适配者类,具有不兼容的接口
class Adaptee:
    def specific_request(self) -> str:
        return "Adaptee:specific_request"


# 适配器类,将被适配者接口转换为目标接口
class Adapter(Target, Adaptee):
    def request(self) -> str:      #使用的是Target接口,内部实际上用的被适配者的接口
        return f"Adapter:request -> {self.specific_request()[::-1]}"


# 客户端代码
def client_code(t: Target) -> None:
    print(t.request())



def main():
    #目标这么写
    print("Client: I can work just fine with the Target objects:")
    t = Target()
    client_code(t)
    print()

    #被失陪者这么写
    a = Adaptee()
    print("Client: The Adaptee class has a weird interface. See, I don't understand it:")
    print(f"Adaptee: {a.specific_request()}")
    print()

    #调用适配器,实际上内部还是调用被适配者的函数
    print("Client: But I can work with it via the Adapter:")
    adapter = Adapter()
    client_code(adapter)


if __name__ == "__main__":
    main()

在这里插入图片描述

         \;\\\;\\\;

7桥接

桥接模式将人员和实现给分离开

适配器只是一个类对类的封装

from __future__ import annotations
from abc import ABC, abstractmethod


#第一层人
class People:
    def __init__(self, implementation: Implementation) -> None:
        self.implementation = implementation
    def say(self) -> str:
        return f"People:say -> {self.implementation.run()}"

#第二层人
class NPC(People):
    def say(self) -> str:
        return f"NPC:say -> {self.implementation.run()}"

#第一层实现
class Implementation(ABC):
    @abstractmethod
    def run(self) -> str:
        pass

#第二层实现
class ConcreteA(Implementation):
    def run(self) -> str:
        return "ConcretenA: Here's the result on the platform A."

#第二层实现
class ConcreteB(Implementation):
    def run(self) -> str:
        return "ConcreteB: Here's the result on the platform B."



#客户代码
def client_code(p: People) -> None:
    print(p.say(), end="")



def Main():
    w = ConcreteA()     #创建第二层实现
    p = People(w)       #传给第一层人来调用
    client_code(p)
    print("\n")

    w = ConcreteB()     #创建第二层实现
    p = NPC(w)          #传给第二层人来调用
    client_code(p)


if __name__ == "__main__":
    Main()

在这里插入图片描述

         \;\\\;\\\;

8组合

都说不要objective面向对象,要面向组合Composition。但是这里的组合模式不一样,指的是同一棵树中类元素的组合,也就是将类实例添加到容器中。

from __future__ import annotations
from abc import ABC, abstractmethod
from typing import List


#第一层组件
class Component(ABC):
    @property
    def parent(self) -> Component:
        return self._parent
    @parent.setter
    def parent(self, parent: Component):
        self._parent = parent
    def add(self, component: Component) -> None:
        pass
    def remove(self, component: Component) -> None:
        pass
    def is_composite(self) -> bool:
        return False
    @abstractmethod
    def operation(self) -> str:
        pass


#第二层组件
class Leaf(Component):
    def operation(self) -> str:
        return "Leaf"


#第二层组件
class Composite(Component):
    def __init__(self) -> None:
        self._children: List[Component] = []
    def add(self, c: Component) -> None:
        self._children.append(c)
        c.parent = self
    def remove(self, c: Component) -> None:
        self._children.remove(c)
        c.parent = None
    def is_composite(self) -> bool:
        return True
    def operation(self) -> str:
        results = []
        for child in self._children:
            results.append(child.operation())
        return f"Branch({'+'.join(results)})"





#客户代码
def client_code(c: Component) -> None:
    print(f"RESULT: {c.operation()}", end="")

#客户代码
def client_code2(c1: Component, c2: Component) -> None:
    if c1.is_composite():
        c1.add(c2)    #多加一个叶子
    print(f"RESULT: {c1.operation()}", end="")



def Main():
    simple = Leaf()
    print("Client: I've got a simple component:")
    client_code(simple)
    print("\n")

    #创建根节点
    tree = Composite()

    #分支下面加两个叶子
    branch1 = Composite()
    branch1.add(Leaf())
    branch1.add(Leaf())

    #另一个分支下面加一个叶子
    branch2 = Composite()
    branch2.add(Leaf())

    #两个分支都作为根结点的叶子
    tree.add(branch1)
    tree.add(branch2)

    print("Client: Now I've got a composite tree:")
    client_code(tree)
    print("\n")

    print("Client: I don't need to check the components classes even when managing the tree:")
    client_code2(tree, simple)
if __name__ == "__main__":
    Main()

在这里插入图片描述

         \;\\\;\\\;

9装饰器

就是在执行exec()函数前,添加一层或多层其他函数的执行


#第一层组件
class Component():
    def exec(self) -> str:
        pass

#第二层组件
class ConcreteComponent(Component):
    def exec(self) -> str:
        return "ConcreteComponent"


#第一层装饰器 / 第二层组件
class Decorator(Component):
    _component: Component = None
    def __init__(self, c: Component) -> None:
        self._component = c
    @property    #能外部获取component属性
    def component(self) -> Component:
        return self._component

    def exec(self) -> str:
        return self._component.exec()


#第二层装饰器 / 第三层组件
class ConcreteA(Decorator):
    def exec(self) -> str:
        return f"ConcreteA -> {self.component.exec()}"

#第二层装饰器 / 第三层组件
class ConcreteB(Decorator):
    def exec(self) -> str:
        return f"ConcreteB -> {self.component.exec()}"


#客户代码
def client_code(c: Component) -> None:
    print(f"RESULT: {c.exec()}", end="")


def Main():
    simple = ConcreteComponent()
    print("Client: I've got a simple component:")
    client_code(simple)    #没装饰直接使用
    print("\n")

    decorator1 = ConcreteA(simple)          #前面用装饰类先执行一下
    decorator2 = ConcreteB(decorator1)      #前面用装饰类先执行一下
    print("Client: Now I've got a decorated component:")
    client_code(decorator2)    #嵌套装饰了两层后调用


if __name__ == "__main__":
    Main()

在这里插入图片描述
         \;\\\;\\\;
感觉不如python的装饰器,不用写成复杂的类也能装饰,如下。

并不一定要每个设计模式都懂,也不是一定要用设计模式。用的时候类多了,自然就形成复杂的调用关系了。

import time


#这个装饰器起到计时的作用
def time_it(func):
    #包裹住
    def wrapper(*args, **kwargs):
        start_time = time.time()
        
        #执行被装饰的函数
        result = func(*args, **kwargs)
        
        end_time = time.time()
        print(f"Function {func.__name__} took {end_time - start_time:.6f} seconds to execute")
        return result
    return wrapper

@time_it
def compute_sum(n):
    return sum(range(n))



def Main():
    compute_sum(1000000)


if __name__ == "__main__":
    Main()

在这里插入图片描述

         \;\\\;\\\;

10门面

为了隐藏子系统,所以用一个外观类(门面类)封装一下

from __future__ import annotations



#门面
class Facade:
    def __init__(self, subsystem1: Subsystem1, subsystem2: Subsystem2) -> None:
        self._subsystem1 = subsystem1 or Subsystem1()
        self._subsystem2 = subsystem2 or Subsystem2()
    def operation(self) -> str:
        results = []
        results.append("Facade initializes subsystems:")
        results.append(self._subsystem1.operation1())
        results.append(self._subsystem2.operation1())
        results.append("Facade orders subsystems to perform the action:")
        results.append(self._subsystem1.operation_n())
        results.append(self._subsystem2.operation_z())
        return "\n".join(results)



class Subsystem1:
    def operation1(self) -> str:
        return "Subsystem1: Ready!"
    def operation_n(self) -> str:
        return "Subsystem1: Go!"


class Subsystem2:
    def operation1(self) -> str:
        return "Subsystem2: Get ready!"
    def operation_z(self) -> str:
        return "Subsystem2: Fire!"

def client_code(facade: Facade) -> None:
    print(facade.operation(), end="")


def Main():
    subsystem1 = Subsystem1()
    subsystem2 = Subsystem2()
    facade = Facade(subsystem1, subsystem2)
    client_code(facade)


if __name__ == "__main__":
    Main()

在这里插入图片描述

         \;\\\;\\\;

11代理

。。。和装饰器一样。。。绷不住了

from abc import ABC, abstractmethod



#第一层池子
class Pool(ABC):
    @abstractmethod
    def request(self) -> None:
        pass

#第二层池子
class ConcretePool(Pool):
    def request(self) -> None:
        print("ConcretePool:request")


class Proxy(Pool):
    def __init__(self, rp: ConcretePool) -> None:
        self._real_Pool = rp

    def request(self) -> None:
        if self.check_access():
            self._real_Pool.request()
            self.log_access()

    def check_access(self) -> bool:
        print("Proxy:check_access")
        return True
    def log_access(self) -> None:
        print("Proxy:log_access", end="")



def client_code(p: Pool) -> None:
    p.request()


def Main():
    print("Client: Executing the client code with a real Pool:")
    real_Pool = ConcretePool()
    client_code(real_Pool)
    print("")

    print("Client: Executing the same client code with a proxy:")
    proxy = Proxy(real_Pool)
    client_code(proxy)

if __name__ == "__main__":
    Main()

在这里插入图片描述

         \;\\\;\\\;

12共享

维护一个字典,value是共享类,不同的key对应不同的实例,甚至是同一个实例,这样就节约了空间,达到了共享!

import json
from typing import Dict, List

# 共享类
class Flyweight:
    def __init__(self, shared_state: List[str]) -> None:
        self._shared_state = shared_state   #初始化的时候传进来一个

    def exec(self, unique_state: List[str]) -> None:
        s = json.dumps(self._shared_state)
        u = json.dumps(unique_state)    #执行的时候又传进来一个
        print(f"Flyweight:exec -> \n\t{s}\n\t{u}", end="")




# 工厂类
class Factory:
    #通过字符串key去查找共享类
    _flyweights: Dict[str, Flyweight] = {}

    def __init__(self, initial_flyweights: List[List[str]]) -> None:
        for state in initial_flyweights:
            self._flyweights[self.get_key(state)] = Flyweight(state)    #添加元素

    #每个key都是由多个字符串用下划线连起来组成的
    def get_key(self, state: List[str]) -> str:
        return "_".join(sorted(state))

    def get_flyweight(self, shared_state: List[str]) -> Flyweight:
        key = self.get_key(shared_state)
        if key not in self._flyweights:  #如果没有这个key
            print("Factory:get_flyweight ->  Can't find a flyweight, creating new one.")
            self._flyweights[key] = Flyweight(shared_state)
        else:
            print("Factory:get_flyweight ->  Reusing existing flyweight.")
        return self._flyweights[key]

    def show(self) -> None:
        count = len(self._flyweights)
        print(f"Factory: I have {count} flyweights:")
        print("\n".join(self._flyweights.keys()), end="")





# 一个新业务
def add_car_to_police_database(
        factory: Factory,    #工厂
        plates: str,         #传入工厂的形参
        owner: str,          #传入工厂的形参
        brand: str,          #传入工厂的形参
        model: str,          #传入工厂的形参
        color: str           #传入工厂的形参
) -> None:
   # print("\nClient: Adding a car to database.")
    flyweight = factory.get_flyweight([brand, model, color])
    flyweight.exec([plates, owner])





def main():
    factory = Factory([
        ["Chevrolet", "Camaro2018", "pink"],
        ["Mercedes Benz", "C300", "black"],
        ["Mercedes Benz", "C500", "red"],
        ["BMW", "M5", "red"],
        ["BMW", "X6", "white"],
    ])
    factory.show()
    print("\n")
    
    #增加一条信息
    add_car_to_police_database(factory, "CL234IR", "James Doe", "BMW", "M5", "red")
    print("\n")
    # 增加一条信息
    add_car_to_police_database(factory, "CL234IR", "James Doe", "BMW", "X1", "red")

    print("\n")

    factory.show()

if __name__ == "__main__":
    main()

在这里插入图片描述

         \;\\\;\\\;

复杂的设计模式

下篇继续

         \;\\\;\\\;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

念心科道尊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值