16_Python设计模式
阅读原文时间:2023年07月09日阅读:4

1.设计模式概述

1.设计模式代表了一种最佳的实践,是被开发人员长期总结,用来解决某一类问题的思路方法,这些方法保证了代码的效率也易于理解

2.设计模式类型:根据23种设计模式可以分为三大类
        创建型模式(Creational Patterns):

            简单工厂模式,工厂模式,抽象工厂模式,原型模式,建造者模式,单例模式

            这些设计模式提供了一种在创建对象的同时隐藏创建逻辑的方式,而不是使用 new 运算符直接实例化对象

            这使得程序在判断针对某个给定实例需要创建哪些对象时更加灵活

        结构型模式(Structural Patterns):

            装饰器模式,适配器模式,门面模式,组合模式,享元模式,桥梁模式,代理模式

            这些设计模式关注类和对象的组合,继承的概念被用来组合接口和定义组合对象获得新功能的方式

        行为型模式(Behavioral Patterns):

            策略模式,责任链模式,命令模式,中介者模式,模板模式,迭代器模式,

            访问者模式,观察者模式,解释器模式,备忘录模式,状态模式

            这些设计模式特别关注对象之间的通信

3.设计模式的六大原则

        1.开闭原则(Open Close Principle)

            这个原则的意思是: 对扩展开放,对修改关闭,在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果

            即: 是为了使程序的扩展性好,易于维护和升级,想要达到这样的效果,我们需要使用接口和抽象类

        2.里氏代换原则(Liskov Substitution Principle)

            里氏代换原则是面向对象设计的基本原则之一,里氏代换原则中说任何基类可以出现的地方,子类一定可以出现

            LSP 是继承复用的基石,只有当派生类可以替换掉基类,且软件单位的功能不受到影响时,基类才能真正被复用

            而派生类也能够在基类的基础上增加新的行为,里氏代换原则是对开闭原则的补充

            实现开闭原则的关键步骤就是抽象化,而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范

        3.依赖倒转原则(Dependence Inversion Principle)

            这个原则是开闭原则的基础,具体内容: 针对接口编程,依赖于抽象而不依赖于具体

        4.接口隔离原则(Interface Segregation Principle)

            这个原则的意思是: 使用多个隔离的接口,比使用单个接口要好

            另外一个意思是: 降低类之间的耦合度,其实设计模式就是从大型软件架构出发,便于升级和维护的软件设计思想它强调降低依赖,降低耦合

        5.迪米特法则,又称最少知道原则(Demeter Principle)

            最少知道原则是指: 一个实体应当尽量少地与其他实体之间发生相互作用,使得系统功能模块相对独立

        6.合成复用原则(Composite Reuse Principle)

            合成复用原则是指: 尽量使用合成/聚合的方式,而不是使用继承

4.Python设计模式参考自如下链接

        https://yq.aliyun.com/topic/122

        https://www.cnblogs.com/alex3714/articles/5760582.html

2.创建型模式

1.简单工厂模式(Simple Factory Pattern)

1.概述: 省去了将工厂实例化的过程,用一个简单的工厂类,来统一的提供给用户调用,根据用户提供的信息返回创建的实例

2.简单工厂模式流程图: https://www.processon.com/view/link/5f155e85e401fd2e0defe767

3.示例1:图形绘制

class Shape:
"""抽象形状类"""

def draw(self):  
    raise NotImplementedError

class Circle(Shape):
"""圆形类"""

def draw(self):  
    print("画圆形")

class Rectangle(Shape):
"""四边形类"""

def draw(self):  
    print("画四边形")

class ShapeFactory:
"""简单工厂类"""

@classmethod  
def create(cls, shape):  
    if shape == 'Circle':  
        return Circle()  
    elif shape == 'Rectangle':  
        return Rectangle()  
    else:  
        return None

if __name__ == '__main__':
# 创建一个简单工厂实例
fac = ShapeFactory()
# 使用工厂实例创建Circle对象
obj = fac.create('Circle')
# 调用对象中的draw方法
obj.draw() # 画圆形

4.示例2: 快餐点餐系统

class Burger:
"""抽象汉堡类"""
name = ""
price = 0.0

def getPrice(self):  
    return self.price

def setPrice(self, price):  
    self.price = price

def getName(self):  
    return self.name

class cheeseBurger(Burger):
"""起司汉堡类"""

def \_\_init\_\_(self):  
    self.name = "cheese burger"  
    self.price = 10.0

class spicyChickenBurger(Burger):
"""辣鸡肉汉堡类"""

def \_\_init\_\_(self):  
    self.name = "spicy chicken burger"  
    self.price = 15.0

class Snack:
"""抽象小吃基类"""
name = ""
price = 0.0
type = "SNACK"

def getPrice(self):  
    return self.price

def setPrice(self, price):  
    self.price = price

def getName(self):  
    return self.name

class chips(Snack):
"""零碎类"""

def \_\_init\_\_(self):  
    self.name = "chips"  
    self.price = 6.0

class chickenWings(Snack):
"""鸡翅类"""

def \_\_init\_\_(self):  
    self.name = "chicken wings"  
    self.price = 12.0

class Beverage:
"""抽象饮料类"""
name = ""
price = 0.0
type = "BEVERAGE"

def getPrice(self):  
    return self.price

def setPrice(self, price):  
    self.price = price

def getName(self):  
    return self.name

class coke(Beverage):
"""可乐类"""

def \_\_init\_\_(self):  
    self.name = "coke"  
    self.price = 4.0

class milk(Beverage):
"""牛奶类"""

def \_\_init\_\_(self):  
    self.name = "milk"  
    self.price = 5.0

class simpleFoodFactory():
"""抽象简单工厂类"""

@classmethod  
def createFood(cls, foodClass):  
    print("Simple factory produce a instance.")  
    foodIns = foodClass()  
    return foodIns

class burgerFactory(simpleFoodFactory):
"""汉堡工厂类"""

def \_\_init\_\_(self):  
    self.type = "BURGER"

class snackFactory(simpleFoodFactory):
"""小吃工厂类"""

def \_\_init\_\_(self):  
    self.type = "SNACK"

class beverageFactory(simpleFoodFactory):
"""饮料工厂类"""

def \_\_init\_\_(self):  
    self.type = "BEVERAGE"

if __name__ == "__main__":
# 工厂实例化
# burger_factory = burgerFactory()
# snack_factorry = snackFactory()
# beverage_factory = beverageFactory()
# 实例调用
# cheese_burger = burger_factory.createFood(cheeseBurger)
# print(cheese_burger.getName(), cheese_burger.getPrice())
# chicken_wings = snack_factorry.createFood(chickenWings)
# print(chicken_wings.getName(), chicken_wings.getPrice())
# coke_drink = beverage_factory.createFood(coke)
# print(coke_drink.getName(), coke_drink.getPrice())

# 省去了将工厂实例化的过程  
spicy\_chicken\_burger = simpleFoodFactory.createFood(spicyChickenBurger)  
print(spicy\_chicken\_burger.getName(), spicy\_chicken\_burger.getPrice())  

"""执行结果
Simple factory produce a instance.
spicy chicken burger 15.0
"""

2.工厂模式(Factory Pattern)

1.概述: 定义一个用于创建对象的接口,让子类决定实例化哪个类,工厂方法使一个类的实例化延迟到其子类,工厂在使用前必须实例化

2.工厂模式流程图: https://www.processon.com/view/link/5f1533aa07912906d9ae82d0

3.示例1:图形绘制

# 形状基类,所有形状子类继承于该类
class Shape:
"""抽象形状类"""

def getShape(self):  
    return self.shape\_name

def draw(self):  
    raise NotImplementedError

class Circle(Shape):
"""圆形类"""

def \_\_init\_\_(self):  
    self.shape\_name = "Circle"

def draw(self):  
    print("画圆形")

class Rectangle(Shape):
"""四边形类"""

def \_\_init\_\_(self):  
    self.shape\_name = "Retangle"

def draw(self):  
    print("画四边形")

形状工厂的基类,所有形状工厂继承于该类

class ShapeFactory:
"""抽象形状工厂类"""

def create(self):  
    """把要创建的工厂对象装配进来"""  
    raise NotImplementedError

class CircleFactory(ShapeFactory):
"""圆形工厂类"""

def create(self):  
    return Circle()

class RectangleFactory(ShapeFactory):
"""四边形工厂类"""

def create(self):  
    return Rectangle()

创建一个圆形工厂实例

cf = CircleFactory()

使用圆形工厂产生圆形对象

obj = cf.create()

调用圆形对象的shape_name

print(obj.getShape()) # Circle

调用圆形对象的draw方法

obj.draw() # 画圆形

创建一个四边形工厂实例

rf = RectangleFactory()
obj2 = rf.create()
print(obj2.getShape()) # Retangle
obj2.draw() # 画四边形

4.示例2: 快餐点餐系统

class Burger:
"""抽象汉堡类"""
name = ""
price = 0.0

def getPrice(self):  
    return self.price

def setPrice(self, price):  
    self.price = price

def getName(self):  
    return self.name

class cheeseBurger(Burger):
"""起司汉堡类"""

def \_\_init\_\_(self):  
    self.name = "cheese burger"  
    self.price = 10.0

class spicyChickenBurger(Burger):
"""辣鸡肉汉堡类"""

def \_\_init\_\_(self):  
    self.name = "spicy chicken burger"  
    self.price = 15.0

class Snack:
"""抽象小吃类"""
name = ""
price = 0.0
type = "SNACK"

def getPrice(self):  
    return self.price

def setPrice(self, price):  
    self.price = price

def getName(self):  
    return self.name

class chips(Snack):
"""零碎类"""

def \_\_init\_\_(self):  
    self.name = "chips"  
    self.price = 6.0

class chickenWings(Snack):
"""鸡翅类"""

def \_\_init\_\_(self):  
    self.name = "chicken wings"  
    self.price = 12.0

class Beverage:
"""抽象饮料基类"""
name = ""
price = 0.0
type = "BEVERAGE"

def getPrice(self):  
    return self.price

def setPrice(self, price):  
    self.price = price

def getName(self):  
    return self.name

class coke(Beverage):
"""可乐类"""

def \_\_init\_\_(self):  
    self.name = "coke"  
    self.price = 4.0

class milk(Beverage):
"""牛奶类"""

def \_\_init\_\_(self):  
    self.name = "milk"  
    self.price = 5.0

class foodFactory:
"""抽象工厂基类"""
type = ""

def createFood(self, foodClass):  
    print(self.type, " factory produce a instance.")  
    foodIns = foodClass()  
    return foodIns

class burgerFactory(foodFactory):
"""汉堡工厂类"""

def \_\_init\_\_(self):  
    self.type = "BURGER"

class snackFactory(foodFactory):
"""小吃工厂类"""

def \_\_init\_\_(self):  
    self.type = "SNACK"

class beverageFactory(foodFactory):
"""饮料工厂类"""

def \_\_init\_\_(self):  
    self.type = "BEVERAGE"

if __name__ == "__main__":
# 工厂实例化
burger_factory = burgerFactory()
snack_factorry = snackFactory()
beverage_factory = beverageFactory()
# 实例调用
cheese_burger = burger_factory.createFood(cheeseBurger)
print(cheese_burger.getName(), cheese_burger.getPrice())
chicken_wings = snack_factorry.createFood(chickenWings)
print(chicken_wings.getName(), chicken_wings.getPrice())
coke_drink = beverage_factory.createFood(coke)
print(coke_drink.getName(), coke_drink.getPrice())
"""执行结果
BURGER factory produce a instance.
cheese burger 10.0
SNACK factory produce a instance.
chicken wings 12.0
BEVERAGE factory produce a instance.
coke 4.0
"""

3.抽象工厂模式(Abstract Factory Pattern)

1.概述: 一个配置类是对具体工厂的一层抽象,完成与各类产品的基类关联

2.抽象工厂模式流程图: https://www.processon.com/view/link/5f1552386376895d7fbab22a

3.示例: 组装电脑

class AbstractFactory:
"""抽象工厂类(配置类)"""
computer_name = ''

def createCpu(self):  
    pass

def createMainboard(self):  
    pass

class IntelFactory(AbstractFactory):
"""Intel配置类(CPU和主板都使用Intel的配置)"""
computer_name = 'Intel I7-series computer '

def createCpu(self):  
    return IntelCpu('I7-6500')

def createMainboard(self):  
    return IntelMainBoard('Intel-6000')

class AmdFactory(AbstractFactory):
"""Amd配置类(CPU和主板都使用Amd的配置)"""
computer_name = 'Amd 4 computer '

def createCpu(self):  
    return AmdCpu('amd444')

def createMainboard(self):  
    return AmdMainBoard('AMD-4000')

class AbstractCpu:
"""抽象CPU类"""
series_name = ''
instructions = ''
arch = ''

class IntelCpu(AbstractCpu):
"""Intel的CPU类"""

def \_\_init\_\_(self, series):  
    self.series\_name = series

class AmdCpu(AbstractCpu):
"""Amd的CPU类"""

def \_\_init\_\_(self, series):  
    self.series\_name = series

class AbstractMainboard:
"""抽象主板类"""
series_name = ''

class IntelMainBoard(AbstractMainboard):
"""Intel主板类"""

def \_\_init\_\_(self, series):  
    self.series\_name = series

class AmdMainBoard(AbstractMainboard):
"""Amd主板类"""

def \_\_init\_\_(self, series):  
    self.series\_name = series

class ComputerEngineer:
"""抽象配置工程师类"""

# 使用配置工厂类来创建电脑  
def makeComputer(self, computer\_obj):  
    self.prepareHardwares(computer\_obj)

# 准备硬件  
def prepareHardwares(self, computer\_obj):  
    # 创建配置清单中的CPU  
    self.cpu = computer\_obj.createCpu()  
    # 创建配置清单中的主板  
    self.mainboard = computer\_obj.createMainboard()  
    info = """  
    ------- computer \[%s\] info:  
    cpu: %s  
    mainboard: %s  
    -------- End --------  
    """ % (computer\_obj.computer\_name, self.cpu.series\_name, self.mainboard.series\_name)  
    print(info)

if __name__ == "__main__":
# 实例化一个配置工程师实例
engineer = ComputerEngineer()

# 实例化Intel配置对象  
computer\_factory = IntelFactory()  
# 按Intel配置配一台电脑  
engineer.makeComputer(computer\_factory)

# 实例化AMD配置对象  
computer\_factory2 = AmdFactory()  
# 按AMD配置配一台电脑  
engineer.makeComputer(computer\_factory2)  

"""执行结果
------- computer [Intel I7-series computer ] info:
cpu: I7-6500
mainboard: Intel-6000
-------- End --------

------- computer \[Amd 4 computer \] info:  
cpu: amd444  
mainboard: AMD-4000  
-------- End --------  

"""

4.原型模式(Prototype Pattern)

1.概述: 用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象,即浅拷贝和深拷贝的运用

2.原型模式流程图: https://www.processon.com/view/link/5f15bb795653bb7fd2449bf2

3.示例: 图层

from copy import copy
from copy import deepcopy

class simpleLayer:
"""图层类"""

background = \[0, 0, 0, 0\]  
content = "blank"

def getContent(self):  
    return self.content

def getBackgroud(self):  
    return self.background

def paint(self, painting):  
    self.content = painting

def setParent(self, p):  
    self.background\[3\] = p

def fillBackground(self, back):  
    self.background = back

def clone(self):  
    return copy(self)

def deep\_clone(self):  
    return deepcopy(self)

if __name__ == "__main__":
dog_layer = simpleLayer()
dog_layer.paint("Dog")
dog_layer.fillBackground([0, 0, 255, 0])
print("Background:", dog_layer.getBackgroud())
print("Painting:", dog_layer.getContent())
another_dog_layer = dog_layer.clone() # 浅拷贝
print("Background:", another_dog_layer.getBackgroud())
print("Painting:", another_dog_layer.getContent())
"""执行结果
Background: [0, 0, 255, 0]
Painting: Dog
Background: [0, 0, 255, 0]
Painting: Dog
"""

5.建造者模式(Builder Pattern)

1.概述: 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示,其作用就是将构建和表示分离,以达到解耦的作用

2.建造者模式流程图: https://www.processon.com/view/link/5f1561366376895d7fbb000d

3.示例1: 创造人类

class Person:
"""抽象产品类(最终产出的东西)"""

def \_\_init\_\_(self):  
    self.head = ""  
    self.body = ""  
    self.arm = ""  
    self.leg = ""

def getPersonInfo(self):  
    print("Head:" + self.head + "\\n" + "Body:" + self.body + "\\n"  
          + "Arm:" + self.arm + "\\n" + "Leg:" + self.leg)

class PersonBuilder:
"""抽象建造者类"""

def BuildHead(self):  
    pass

def BuildBody(self):  
    pass

def BuildArm(self):  
    pass

def BuildLeg(self):  
    pass

class PersonFatBuilder(PersonBuilder):
"""胖子建造者子类"""
type = '胖子'

def \_\_init\_\_(self):  
    self.person = Person()

def BuildHead(self):  
    self.person.head = "构建%s的头" % self.type

def BuildBody(self):  
    self.person.body = "构建%s的身体" % self.type

def BuildArm(self):  
    self.person.arm = "构建%s的手" % self.type

def BuildLeg(self):  
    self.person.leg = "构建%s的腿" % self.type

def getPerson(self):  
    return self.person

class PersonThinBuilder(PersonBuilder):
"""瘦子建造者子类"""
type = '瘦子'

def \_\_init\_\_(self):  
    self.person = Person()

def BuildHead(self):  
    self.person.head = "构建%s的头" % self.type

def BuildBody(self):  
    self.person.body = "构建%s的身体" % self.type

def BuildArm(self):  
    self.person.arm = "构建%s的手" % self.type

def BuildLeg(self):  
    self.person.leg = "构建%s的腿" % self.type

def getPerson(self):  
    return self.person

class PersonDirector:
"""使用建造者的类(指挥官)"""

def \_\_init\_\_(self, pb):  
    self.pb = pb

# 调用建造者里的各部位方法来创建一个人  
def CreatePereson(self):  
    self.pb.BuildHead()  
    self.pb.BuildBody()  
    self.pb.BuildArm()  
    self.pb.BuildLeg()  
    return self.pb.getPerson()

def clientUI():
# 瘦子建造者实例
pb = PersonThinBuilder()
# 指挥官类(使用瘦子创建者)
pd = PersonDirector(pb)
# 创建一个瘦子
created_thin_person = pd.CreatePereson()
created_thin_person.getPersonInfo()

# 胖子建造者实例  
pb = PersonFatBuilder()  
# 指挥官类(使用胖子创建者)  
pd = PersonDirector(pb)  
# 创建一个胖子  
created\_fat\_person = pd.CreatePereson()  
created\_fat\_person.getPersonInfo()

if __name__ == '__main__':
clientUI()
"""执行结果
Head:构建瘦子的头
Body:构建瘦子的身体
Arm:构建瘦子的手
Leg:构建瘦子的腿
Head:构建胖子的头
Body:构建胖子的身体
Arm:构建胖子的手
Leg:构建胖子的腿
"""

4.示例2: 快餐点餐系统

class Burger:
"""抽象汉堡类"""
name = ""
price = 0.0

def getPrice(self):  
    return self.price

def setPrice(self, price):  
    self.price = price

def getName(self):  
    return self.name

class cheeseBurger(Burger):
"""起司汉堡类"""

def \_\_init\_\_(self):  
    self.name = "cheese burger"  
    self.price = 10.0

class spicyChickenBurger(Burger):
"""辣鸡汉堡类"""

def \_\_init\_\_(self):  
    self.name = "spicy chicken burger"  
    self.price = 15.0

class Snack:
"""抽象小吃类"""
name = ""
price = 0.0
type = "SNACK"

def getPrice(self):  
    return self.price

def setPrice(self, price):  
    self.price = price

def getName(self):  
    return self.name

class chips(Snack):
"""零碎类"""

def \_\_init\_\_(self):  
    self.name = "chips"  
    self.price = 6.0

class chickenWings(Snack):
"""鸡翅类"""

def \_\_init\_\_(self):  
    self.name = "chicken wings"  
    self.price = 12.0

class Beverage:
"""抽象饮料类"""
name = ""
price = 0.0
type = "BEVERAGE"

def getPrice(self):  
    return self.price

def setPrice(self, price):  
    self.price = price

def getName(self):  
    return self.name

class coke(Beverage):
"""可乐类"""

def \_\_init\_\_(self):  
    self.name = "coke"  
    self.price = 4.0

class milk(Beverage):
"""牛奶类"""

def \_\_init\_\_(self):  
    self.name = "milk"  
    self.price = 5.0

class order:
"""订单类"""
burger = ""
snack = ""
beverage = ""

def \_\_init\_\_(self, orderBuilder):  
    # orderBuilder就是建造者模式中所谓的建造者  
    self.burger = orderBuilder.bBurger  
    self.snack = orderBuilder.bSnack  
    self.beverage = orderBuilder.bBeverage

def show(self):  
    print("Burger:%s" % self.burger.getName())  
    print("Snack:%s" % self.snack.getName())  
    print("Beverage:%s" % self.beverage.getName())

class orderBuilder:
"""建造者类"""
bBurger = ""
bSnack = ""
bBeverage = ""

def addBurger(self, xBurger):  
    self.bBurger = xBurger

def addSnack(self, xSnack):  
    self.bSnack = xSnack

def addBeverage(self, xBeverage):  
    self.bBeverage = xBeverage

def build(self):  
    return order(self)

if __name__ == "__main__":
# 实现订单生成
order_builder = orderBuilder()
order_builder.addBurger(spicyChickenBurger())
order_builder.addSnack(chips())
order_builder.addBeverage(milk())
order_1 = order_builder.build()
order_1.show()
"""执行结果
Burger:spicy chicken burger
Snack:chips
Beverage:milk
"""

6.单例模式(Singleton Pattern)

1.概述: 保证一个类仅有一个实例可以节省比较多的内存空间,并提供一个访问它的全局访问点可以更好地进行数据同步控制,避免多重占用

2.实现单例-自定义类方法实现

class Foo:
instance = None

def \_\_init\_\_(self):  
    pass

@classmethod  
def get\_instance(cls):  
    if cls.instance:  
        return cls.instance  
    else:  
        cls.instance = cls()  
        return cls.instance

def process(self):  
    print("process")

if __name__ == '__main__':
obj1 = Foo.get_instance()
obj2 = Foo.get_instance()
print(id(obj1), id(obj2)) # 4411389776 4411389776

3.实现单例-类的构造方法 __new__ 实现

import threading
import time

这里使用方法__new__来实现单例模式

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

总线

class Bus(Singleton):
lock = threading.RLock()

def sendData(self, data):  
    self.lock.acquire()  
    time.sleep(3)  
    print("Sending Signal Data...", data)  
    self.lock.release()

线程对象,为更加说明单例的含义,这里将Bus对象实例化写在了run里

class VisitEntity(threading.Thread):
my_bus = ""
name = ""

def getName(self):  
    return self.name

def setName(self, name):  
    self.name = name

def run(self):  
    self.my\_bus = Bus()  
    self.my\_bus.sendData(self.name)

if __name__ == "__main__":
for i in range(3):
print("Entity %d begin to run…" % i)
my_entity = VisitEntity()
my_entity.setName("Entity_" + str(i))
my_entity.start()
"""执行结果
Entity 0 begin to run…
Entity 1 begin to run…
Entity 2 begin to run…
Sending Signal Data… Entity_0
Sending Signal Data… Entity_1
Sending Signal Data… Entity_2
"""

4.实现单例-基于模块导入机制实现

# 1.原理剖析: 模块只被导入一次,当我们在导入一个模块时,python会编译生成一个pyc文件,这个文件会在模块的第一次导入时生成
# 当pyc存在的时候,例如第二次导入模块,则不会在运行模块中的代码,而是直接使用内存中的pyc,利用这一特性,可以构建单例模型

2.在mysingleton模块中,定义了MySingleton类,并获取了一个实例对象

class MySingleton:
def foo(self):
print("foo…")

my_singleton = MySingleton()

3.在另一个模块中,对mysingleton模块进行导入

第一次导入my_singleton

from mysingleton import my_singleton

第二次导入my_singleton

from mysingleton import my_singleton as my_singleton_2

print(id(my_singleton)) #
print(id(my_singleton_2)) #

5.实现单例-装饰器实现

# 实现构建单例对象的装饰器
def singleton(cls, *args, **kwargs):
# 一个用于存放单例对象的字典,以类为key,单例对象为value
instances = {}

def get\_instance(\*args, \*\*kwargs):  
    # 如果这个类没有创建过对象,则创建对象,作为value存放在字典中  
    if cls not in instances:  
        instances\[cls\] = cls(\*args, \*\*kwargs)  
    return instances\[cls\]

return get\_instance

@singleton
class Test:
def __init__(self, name):
self.name = name

def get\_name(self):  
    return self.name

if __name__ == '__main__':
t1 = Test("leo1")
t2 = Test("leo2")

print(t1.get\_name())  # leo1  
print(t2.get\_name())  # leo1  
print(id(t1) == id(t2))  # True

3.结构型模式

1.装饰器模式(Decorator Pattern)

1.概述: 动态地给一个对象添加一些额外的职责,在增加功能方面,装饰器模式比生成子类更为灵活

2.示例: 快餐点餐系统

class Beverage:
"""抽象饮料类"""
name = ""
price = 0.0
type = "BEVERAGE"

def getPrice(self):  
    return self.price

def setPrice(self, price):  
    self.price = price

def getName(self):  
    return self.name

class coke(Beverage):
"""可乐类"""

def \_\_init\_\_(self):  
    self.name = "coke"  
    self.price = 4.0

class milk(Beverage):
"""牛奶类"""

def \_\_init\_\_(self):  
    self.name = "milk"  
    self.price = 5.0

class drinkDecorator:
"""抽象装饰器类"""

def getName(self):  
    pass

def getPrice(self):  
    pass

class iceDecorator(drinkDecorator):
"""加冰装饰器类"""

def \_\_init\_\_(self, beverage):  
    self.beverage = beverage

def getName(self):  
    return self.beverage.getName() + " +ice"

def getPrice(self):  
    return self.beverage.getPrice() + 0.3

class sugarDecorator(drinkDecorator):
"""加糖装饰器类"""

def \_\_init\_\_(self, beverage):  
    self.beverage = beverage

def getName(self):  
    return self.beverage.getName() + " +sugar"

def getPrice(self):  
    return self.beverage.getPrice() + 0.5

if __name__ == "__main__":
coke_cola = coke()
print("Name:%s" % coke_cola.getName())
print("Price:%s" % coke_cola.getPrice())

# 可乐加冰  
ice\_coke = iceDecorator(coke\_cola)  
print("Name:%s" % ice\_coke.getName())  
print("Price:%s" % ice\_coke.getPrice())

# 可乐加糖  
sugar\_coke = sugarDecorator(coke\_cola)  
print("Name:%s" % sugar\_coke.getName())  
print("Price:%s" % sugar\_coke.getPrice())  
"""执行结果  
    Name:coke  
    Price:4.0  
    Name:coke +ice  
    Price:4.3  
    Name:coke +sugar  
    Price:4.5  
"""

2.适配器模式(Adapter Pattern)

1.概述: 将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以一起工作

2.应用场景: 希望复用一些现存的类,但是接口又与复用环境要求不一致

3.适配器模式流程图: https://www.processon.com/view/link/5f16e1bae0b34d54dac066d2

2.示例1: 球场球员兼容

def printInfo(info):
print(info)

class Player:
"""抽象球员基类"""
name = ''

def \_\_init\_\_(self, name):  
    self.name = name

def Attack(self, name):  
    pass

def Defense(self):  
    pass

class Forwards(Player):
"""前锋类"""

def \_\_init\_\_(self, name):  
    Player.\_\_init\_\_(self, name)

def Attack(self):  
    printInfo("前锋%s 进攻" % self.name)

def Defense(self, name):  
    printInfo("前锋%s 防守" % self.name)

class Center(Player):
"""中锋类"""

def \_\_init\_\_(self, name):  
    Player.\_\_init\_\_(self, name)

def Attack(self):  
    printInfo("中锋%s 进攻" % self.name)

def Defense(self):  
    printInfo("中锋%s 防守" % self.name)

class Guards(Player):
"""后卫类"""

def \_\_init\_\_(self, name):  
    Player.\_\_init\_\_(self, name)

def Attack(self):  
    printInfo("后卫%s 进攻" % self.name)

def Defense(self):  
    printInfo("后卫%s 防守" % self.name)

class ForeignCenter(Player):
"""待适配类(外籍中锋)"""
name = ''

def \_\_init\_\_(self, name):  
    Player.\_\_init\_\_(self, name)

# 不同的成员方法,需要适配成Attack方法  
def ForeignAttack(self):  
    printInfo("外籍中锋%s 进攻" % self.name)

# 不同的成员方法,需要适配成Defense方法  
def ForeignDefense(self):  
    printInfo("外籍中锋%s 防守" % self.name)

class Translator(Player):
"""翻译类(适配类)"""
foreignCenter = None

# 将需要适配的类对象作为属性  
def \_\_init\_\_(self, name):  
    self.foreignCenter = ForeignCenter(name)

# 将需要适配的类成员方法翻译成适配后的成员方法  
def Attack(self):  
    self.foreignCenter.ForeignAttack()

def Defense(self):  
    self.foreignCenter.ForeignDefense()

def clientUI():
b = Forwards('巴蒂尔')
m = Guards('姚明')
# 直接使用适配类
ym = Translator('麦克格雷迪')

b.Attack()  
m.Defense()  
ym.Attack()  
ym.Defense()  
return

if __name__ == '__main__':
clientUI()
"""执行结果
前锋巴蒂尔 进攻
后卫姚明 防守
外籍中锋麦克格雷迪 进攻
外籍中锋麦克格雷迪 防守
"""

3.示例2: 外包人员系统兼容

class ACpnStaff:
"""抽象A公司工作人员类"""
name = ""
id = ""
phone = ""

def \_\_init\_\_(self, id):  
    self.id = id

def getName(self):  
    print("A protocol getName method...id:%s" % self.id)  
    return self.name

def setName(self, name):  
    print("A protocol setName method...id:%s" % self.id)  
    self.name = name

def getPhone(self):  
    print("A protocol getPhone method...id:%s" % self.id)  
    return self.phone

def setPhone(self, phone):  
    print("A protocol setPhone method...id:%s" % self.id)  
    self.phone = phone

class BCpnStaff:
"""抽象B公司工作人员类"""
name = ""
id = ""
telephone = ""

def \_\_init\_\_(self, id):  
    self.id = id

def get\_name(self):  
    print("B protocol get\_name method...id:%s" % self.id)  
    return self.name

def set\_name(self, name):  
    print("B protocol set\_name method...id:%s" % self.id)  
    self.name = name

def get\_telephone(self):  
    print("B protocol get\_telephone method...id:%s" % self.id)  
    return self.telephone

def set\_telephone(self, telephone):  
    print("B protocol get\_name method...id:%s" % self.id)  
    self.telephone = telephone

class CpnStaffAdapter:
"""适配器类: 实现将B公司人员接口封装,而对外接口形式与A公司人员接口一致"""
b_cpn = ""

def \_\_init\_\_(self, id):  
    self.b\_cpn = BCpnStaff(id)

def getName(self):  
    return self.b\_cpn.get\_name()

def getPhone(self):  
    return self.b\_cpn.get\_telephone()

def setName(self, name):  
    self.b\_cpn.set\_name(name)

def setPhone(self, phone):  
    self.b\_cpn.set\_telephone(phone)

if __name__ == "__main__":
acpn_staff = ACpnStaff("")
acpn_staff.setName("X-A")
acpn_staff.setPhone("")
print("A Staff Name:%s" % acpn_staff.getName())
print("A Staff Phone:%s" % acpn_staff.getPhone())
bcpn_staff = CpnStaffAdapter("")
bcpn_staff.setName("Y-B")
bcpn_staff.setPhone("")
print("B Staff Name:%s" % bcpn_staff.getName())
print("B Staff Phone:%s" % bcpn_staff.getPhone())
"""执行结果
A protocol setName method…id:123
A protocol setPhone method…id:123
A protocol getName method…id:123
A Staff Name:X-A
A protocol getPhone method…id:123
A Staff Phone:10012345678
B protocol set_name method…id:456
B protocol get_name method…id:456
B protocol get_name method…id:456
B Staff Name:Y-B
B protocol get_telephone method…id:456
B Staff Phone:99987654321
"""

3.门面模式(Facade Pattern)

1.概述: 要求一个子系统的外部与其内部的通信必须通过一个统一的对象进行,门面模式提供一个高层次的接口,使得子系统更易于使用

2.示例1: 股票交易

def printInfo(info):
print(info)

class Stock:
"""股票交易所类"""
name = '股票1'

def buy(self):  
    printInfo('买 ' + self.name)

def sell(self):  
    printInfo('卖 ' + self.name)

class ETF:
"""基金交易所类"""
name = '指数型基金'

def buy(self):  
    printInfo('买 ' + self.name)

def sell(self):  
    printInfo('卖 ' + self.name)

class Future:
"""期货交易所类"""
name = '期货'

def buy(self):  
    printInfo('买 ' + self.name)

def sell(self):  
    printInfo('卖 ' + self.name)

class NationDebt:
"""国债交易所类"""
name = '国债'

def buy(self):  
    printInfo('买 ' + self.name)

def sell(self):  
    printInfo('卖 ' + self.name)

class Option:
"""权证叫死类"""
name = '权证'

def buy(self):  
    printInfo('买 ' + self.name)

def sell(self):  
    printInfo('卖 ' + self.name)

class Fund:
"""基金类"""

def \_\_init\_\_(self):  
    self.stock = Stock()  
    self.etf = ETF()  
    self.future = Future()  
    self.debt = NationDebt()  
    self.option = Option()

def buyFund(self):  
    self.stock.buy()  
    self.etf.buy()  
    self.debt.buy()  
    self.future.buy()  
    self.option.buy()

def sellFund(self):  
    self.stock.sell()  
    self.etf.sell()  
    self.future.sell()  
    self.debt.sell()  
    self.option.sell()

def clientUI():
myFund = Fund()
myFund.buyFund()
myFund.sellFund()
return

if __name__ == '__main__':
clientUI()
"""执行结果
买 股票1
买 指数型基金
买 国债
买 期货
买 权证
卖 股票1
卖 指数型基金
卖 期货
卖 国债
卖 权证
"""

3.示例2 火警报警器

class AlarmSensor:
"""报警器类"""

def run(self):  
    print("Alarm Ring...")

class WaterSprinker:
"""喷水器类"""

def run(self):  
    print("Spray Water...")

class EmergencyDialer:
"""拨号器类"""

def run(self):  
    print("Dial 119...")

class EmergencyFacade:
"""门面类:统一对象,提供接口"""

def \_\_init\_\_(self):  
    self.alarm\_sensor = AlarmSensor()  
    self.water\_sprinker = WaterSprinker()  
    self.emergency\_dialer = EmergencyDialer()

def runAll(self):  
    self.alarm\_sensor.run()  
    self.water\_sprinker.run()  
    self.emergency\_dialer.run()

if __name__ == "__main__":
emergency_facade = EmergencyFacade()
emergency_facade.runAll()
"""执行结果
Alarm Ring…
Spray Water…
Dial 119…
"""

4.组合模式(Composite Pattern)

1.概述: 将对象组合成树形结构以表示部分和整体的层次结构,使得用户对单个对象和组合对象的使用具有一致性

2.示例1: 店面组织结构

class Store:
"""抽象店面类"""

# 添加店面  
def add(self, store):  
    pass

# 删除店面  
def remove(self, store):  
    pass

def pay\_by\_card(self):  
    pass

class BranchStore(Store):
"""分店类"""

def \_\_init\_\_(self, name):  
    self.name = name  
    self.my\_store\_list = \[\]

def pay\_by\_card(self):  
    print("店面\[%s\]的积分已累加进该会员卡" % self.name)  
    for s in self.my\_store\_list:  
        s.pay\_by\_card()

# 添加店面  
def add(self, store):  
    self.my\_store\_list.append(store)

# 删除店面  
def remove(self, store):  
    self.my\_store\_list.remove(store)

class JoinStore(Store):
"""加盟店"""

def \_\_init\_\_(self, name):  
    self.name = name

def pay\_by\_card(self):  
    print("店面\[%s\]的积分已累加进该会员卡" % self.name)

def add(self, store):  
    print("无添加子店权限")

def remove(self, store):  
    print("无删除子店权限")

if __name__ == "__main__":
store = BranchStore("朝阳总店")
branch = BranchStore("海滨分店")
join_branch = JoinStore("昌平加盟1店")
join_branch2 = JoinStore("昌平加盟2店")

branch.add(join\_branch)  
branch.add(join\_branch2)

store.add(branch)

store.pay\_by\_card()  
print(store.my\_store\_list)  

"""执行结果
店面[朝阳总店]的积分已累加进该会员卡
店面[海滨分店]的积分已累加进该会员卡
店面[昌平加盟1店]的积分已累加进该会员卡
店面[昌平加盟2店]的积分已累加进该会员卡
[<__main__.BranchStore object at 0x10be2aad0>]
"""

3.示例2: 公司结构组织

class Company:
"""抽象公司类"""
name = ''

def \_\_init\_\_(self, name):  
    self.name = name

def add(self, company):  
    pass

def remove(self, company):  
    pass

def display(self, depth):  
    pass

def listDuty(self):  
    pass

class ConcreteCompany(Company):
"""总公司类"""
childrenCompany = None

def \_\_init\_\_(self, name):  
    Company.\_\_init\_\_(self, name)  
    self.childrenCompany = \[\]

def add(self, company):  
    self.childrenCompany.append(company)

def remove(self, company):  
    self.childrenCompany.remove(company)

def display(self, depth):  
    print('-' \* depth + self.name)  
    for component in self.childrenCompany:  
        component.display(depth + 1)

def listDuty(self):  
    for component in self.childrenCompany:  
        component.listDuty()

class HRDepartment(Company):
"""人事部门类"""

def \_\_init\_\_(self, name):  
    Company.\_\_init\_\_(self, name)

def display(self, depth):  
    print('-' \* depth + self.name)

def listDuty(self):  # 履行职责  
    print('%s\\t Enrolling & Transfering management.' % self.name)

class FinanceDepartment(Company):
"""财务部门类"""

def \_\_init\_\_(self, name):  
    Company.\_\_init\_\_(self, name)

def display(self, depth):  
    print("-" \* depth + self.name)

def listDuty(self):  # 履行职责  
    print('%s\\tFinance Management.' % self.name)

class RdDepartment(Company):
"""研发部门类"""

def \_\_init\_\_(self, name):  
    Company.\_\_init\_\_(self, name)

def display(self, depth):  
    print("-" \* depth + self.name)

def listDuty(self):  
    print("%s\\tResearch & Development." % self.name)

if __name__ == "__main__":
# 总公司下设东边的分公司一个,东边的分公司下设东北公司和东南公司,显示公司层级,并罗列这些的公司中各部门的职责
root = ConcreteCompany('HeadQuarter')
root.add(HRDepartment('HQ HR'))
root.add(FinanceDepartment('HQ Finance'))
root.add(RdDepartment("HQ R&D"))

comp = ConcreteCompany('East Branch')  
comp.add(HRDepartment('East.Br HR'))  
comp.add(FinanceDepartment('East.Br Finance'))  
comp.add(RdDepartment("East.Br R&D"))  
root.add(comp)

comp1 = ConcreteCompany('Northast Branch')  
comp1.add(HRDepartment('Northeast.Br HR'))  
comp1.add(FinanceDepartment('Northeast.Br Finance'))  
comp1.add(RdDepartment("Northeast.Br R&D"))  
comp.add(comp1)

comp2 = ConcreteCompany('Southeast Branch')  
comp2.add(HRDepartment('Southeast.Br HR'))  
comp2.add(FinanceDepartment('Southeast.Br Finance'))  
comp2.add(RdDepartment("Southeast.Br R&D"))  
comp.add(comp2)

root.display(1)

root.listDuty()  

"""执行结果
-HeadQuarter
--HQ HR
--HQ Finance
--HQ R&D
--East Branch
---East.Br HR
---East.Br Finance
---East.Br R&D
---Northast Branch
----Northeast.Br HR
----Northeast.Br Finance
----Northeast.Br R&D
---Southeast Branch
----Southeast.Br HR
----Southeast.Br Finance
----Southeast.Br R&D
HQ HR Enrolling & Transfering management.
HQ Finance Finance Management.
HQ R&D Research & Development.
East.Br HR Enrolling & Transfering management.
East.Br Finance Finance Management.
East.Br R&D Research & Development.
Northeast.Br HR Enrolling & Transfering management.
Northeast.Br Finance Finance Management.
Northeast.Br R&D Research & Development.
Southeast.Br HR Enrolling & Transfering management.
Southeast.Br Finance Finance Management.
Southeast.Br R&D Research & Development.
"""

5.享元模式(Flyweight Pattern)

1.概述: 使用共享对象支持大量细粒度对象,大量细粒度的对象的支持共享,可能会涉及这些对象的两类信息: 内部状态信息和外部状态信息
            即使用一个字典保存所有对象,在产生对象时,将其类+参数作为键,键相同的对象,只会产生一份,有点像单例

            键不同则会产生新的对象,相当于相同属性的对象,直接共享使用,节省存储空间

2.示例1: 精卵工厂

class FlyweightBase:
"""抽象基地类"""
_instances = dict()

def \_\_init\_\_(self, \*args, \*\*kwargs):  
    # 继承的子类必须初始化  
    raise NotImplementedError

def \_\_new\_\_(cls, \*args, \*\*kwargs):  
    # 类+参数作为键,如果已经存在,则返回存在的值(对象),如果不存在,则产生一个新实例并返回  
    return cls.\_instances.setdefault(  
        (cls, args, tuple(kwargs.items())),  
        super(FlyweightBase, cls).\_\_new\_\_(cls)  
    )

def test\_data(self):  
    pass

class Spam(FlyweightBase):
"""精子类"""

def \_\_init\_\_(self, a, b):  
    self.a = a  
    self.b = b

def test\_data(self):  
    print("精子准备好了", self.a, self.b)

class Egg(FlyweightBase):
"""卵类"""

def \_\_init\_\_(self, x, y):  
    self.x = x  
    self.y = y

def test\_data(self):  
    print("卵子准备好了", self.x, self.y)

由于spam1和spam2都是产生自Spam类,而且参数都是1, 'abc',所以键是一样的,spam1事先被创建并存于_instance中,spam2就不会被创建了

spam1 = Spam(1, 'abc')
spam2 = Spam(1, 'abc')

spam3的参数不一样,所以被创建实例,保存在_instance中

spam3 = Spam(3, 'DEF')

egg1的类是Egg,所以也被创建实例,保存在_instance中

egg1 = Egg(1, 'abc')

spam1和spam2是同一个实例

print(id(spam1), id(spam2))
spam2.test_data()
egg1.test_data()

print(egg1._instances)
print(egg1._instances.keys())
"""执行结果
4445952976 4445952976
精子准备好了 1 abc
卵子准备好了 1 abc
{(, (1, 'abc'), ()): <__main__.Spam object at 0x108ffdbd0>,
(, (3, 'DEF'), ()): <__main__.Spam object at 0x108ffdc50>,
(, (1, 'abc'), ()): <__main__.Egg object at 0x108ffdc90>}
dict_keys([(, (1, 'abc'), ()), (,
(3, 'DEF'), ()), (, (1, 'abc'), ())])
"""

3.示例2: 网上咖啡选购平台

class Coffee:
"""咖啡类"""
name = ''
price = 0

def \_\_init\_\_(self, name):  
    self.name = name  
    # 在实际业务中,咖啡价格应该是由配置表进行配置,或者调用接口获取等方式得到  
    # 此处为说明享元模式,将咖啡价格定为名称长度,只是一种简化  
    self.price = len(name)

def show(self):  
    print("Coffee Name:%s Price:%s" % (self.name, self.price))

class Customer:
"""顾客类"""
coffee_factory = ""
name = ""

def \_\_init\_\_(self, name, coffee\_factory):  
    self.name = name  
    self.coffee\_factory = coffee\_factory

def order(self, coffee\_name):  
    print("%s ordered a cup of coffee:%s" % (self.name, coffee\_name))  
    return self.coffee\_factory.getCoffee(coffee\_name)

class CoffeeFactory:
"""咖啡工厂类"""
coffee_dict = {}

def getCoffee(self, name):  
    if self.coffee\_dict.\_\_contains\_\_(name) == False:  # 判断键是否存在于字典中  
        self.coffee\_dict\[name\] = Coffee(name)  
    return self.coffee\_dict\[name\]

def getCoffeeCount(self):  
    return len(self.coffee\_dict)

if __name__ == "__main__":
coffee_factory = CoffeeFactory()
customer_1 = Customer("A Client", coffee_factory)
customer_2 = Customer("B Client", coffee_factory)
customer_3 = Customer("C Client", coffee_factory)
c1_capp = customer_1.order("cappuccino")
c1_capp.show()
c2_mocha = customer_2.order("mocha")
c2_mocha.show()
c3_capp = customer_3.order("cappuccino")
c3_capp.show()
print("Num of Coffee Instance:%s" % coffee_factory.getCoffeeCount())
"""执行结果
A Client ordered a cup of coffee:cappuccino
Coffee Name:cappuccino Price:10
B Client ordered a cup of coffee:mocha
Coffee Name:mocha Price:5
C Client ordered a cup of coffee:cappuccino
Coffee Name:cappuccino Price:10
Num of Coffee Instance:2
"""

6.桥梁模式(Bridge Pattern)

1.概述: 将抽象与实现解耦(此处的抽象和实现,并非抽象类和实现类的那种关系,而是一种角色的关系),可以使其独立变化

2.示例1: 车辆行驶

class AbstractRoad:
"""公路基类"""
car = None

class AbstractCar:
"""车辆基类"""

def run(self):  
    pass

class Street(AbstractRoad):
"""市区街道类"""

def run(self):  
    self.car.run()  
    print("在市区街道上行驶")

class SpeedWay(AbstractRoad):
"""高速公路类"""

def run(self):  
    self.car.run()  
    print("在高速公路上行驶")

class Car(AbstractCar):
"""小汽车类"""

def run(self):  
    print("小汽车在")

class Bus(AbstractCar):
"""公共汽车类"""

def run(self):  
    print("公共汽车在")

if __name__ == "__main__":
# 小汽车在高速上行驶
road1 = SpeedWay()
road1.car = Car()
road1.run()
# 公交车在高速上行驶
road2 = SpeedWay()
road2.car = Bus()
road2.run()
"""执行结果
小汽车在
在高速公路上行驶
公共汽车在
在高速公路上行驶
"""

3.示例2: 画笔与形状

class Shape:
"""抽象形状类"""
name = ""
param = ""

def \_\_init\_\_(self, \*param):  
    pass

def getName(self):  
    return self.name

def getParam(self):  
    return self.name, self.param

class Pen:
"""抽象画笔类"""
shape = ""
type = ""

def \_\_init\_\_(self, shape):  
    self.shape = shape

def draw(self):  
    pass

class Rectangle(Shape):
"""矩形类"""

def \_\_init\_\_(self, long, width):  
    self.name = "Rectangle"  
    self.param = "Long:%s Width:%s" % (long, width)  
    print("Create a rectangle:%s" % self.param)

class Circle(Shape):
"""圆形类"""

def \_\_init\_\_(self, radius):  
    self.name = "Circle"  
    self.param = "Radius:%s" % radius  
    print("Create a circle:%s" % self.param)

class NormalPen(Pen):
"""普通画笔类"""

def \_\_init\_\_(self, shape):  
    Pen.\_\_init\_\_(self, shape)  
    self.type = "Normal Line"

def draw(self):  
    print("DRAWING %s:%s----PARAMS:%s" % (self.type, self.shape.getName(), self.shape.getParam()))

class BrushPen(Pen):
"""画刷类"""

def \_\_init\_\_(self, shape):  
    Pen.\_\_init\_\_(self, shape)  
    self.type = "Brush Line"

def draw(self):  
    print("DRAWING %s:%s----PARAMS:%s" % (self.type, self.shape.getName(), self.shape.getParam()))

if __name__ == "__main__":
normal_pen = NormalPen(Rectangle("20cm", "10cm"))
brush_pen = BrushPen(Circle("15cm"))
normal_pen.draw()
brush_pen.draw()
"""执行结果
Create a rectangle:Long:20cm Width:10cm
Create a circle:Radius:15cm
DRAWING Normal Line:Rectangle----PARAMS:('Rectangle', 'Long:20cm Width:10cm')
DRAWING Brush Line:Circle----PARAMS:('Circle', 'Radius:15cm')
"""

7.代理模式(Proxy Pattern)

1.概述: 为某对象提供一个代理,以控制对其的访问和控制,在使用过程中应尽量对抽象主题类进行代理,不要对加过修饰和方法的子类代理

2.示例1: 寄件代理

class sender_base:
"""寄件者基类"""

def \_\_init\_\_(self):  
    pass

def send\_something(self, something):  
    pass

class send_class(sender_base):
"""寄件者子类"""

def \_\_init\_\_(self, receiver):  
    self.receiver = receiver

def send\_something(self, something):  
    print("SEND " + something + ' TO ' + self.receiver.name)

class agent_class(sender_base):
"""代理类"""

# 告诉代理接受者是谁  
def \_\_init\_\_(self, receiver):  
    self.send\_obj = send\_class(receiver)

# 代理直接调用发送者的send\_something方法发送东西给接受者  
def send\_something(self, something):  
    self.send\_obj.send\_something(something)

class receive_class:
"""接受者类"""

def \_\_init\_\_(self, someone):  
    self.name = someone

if '__main__' == __name__:
receiver = receive_class('Leo')
agent = agent_class(receiver)
agent.send_something('Cake')

print(receiver.\_\_class\_\_)  
print(agent.\_\_class\_\_)  

"""执行结果
SEND Cake TO Leo


"""

3.示例2: 网络服务器配置白名单

# 该服务器接受如下格式数据,addr代表地址,content代表接收的信息内容
info_struct = dict()
info_struct["addr"] = 10000
info_struct["content"] = ""

class Server:
"""网络服务器类"""
content = ""

def recv(self, info):  
    pass

def send(self, info):  
    pass

def show(self):  
    pass

class infoServer(Server):
"""收发功能类"""

def recv(self, info):  
    self.content = info  
    return "recv OK!"

def send(self, info):  
    pass

def show(self):  
    print("SHOW:%s" % self.content)

class serverProxy:
"""代理基类"""
pass

class infoServerProxy(serverProxy):
"""Server的直接接口代理类"""
server = ""

def \_\_init\_\_(self, server):  
    self.server = server

def recv(self, info):  
    return self.server.recv(info)

def show(self):  
    self.server.show()

class whiteInfoServerProxy(infoServerProxy):
"""实现服务器的白名单访问类"""
white_list = []

def recv(self, info):  
    try:  
        assert type(info) == dict  
    except:  
        return "info structure is not correct"  
    addr = info.get("addr", 0)  
    if not addr in self.white\_list:  
        return "Your address is not in the white list."  
    else:  
        content = info.get("content", "")  
        return self.server.recv(content)

def addWhite(self, addr):  
    self.white\_list.append(addr)

def rmvWhite(self, addr):  
    self.white\_list.remove(addr)

def clearWhite(self):  
    self.white\_list = \[\]

if __name__ == "__main__":
info_struct = dict()
info_struct["addr"] = 10010
info_struct["content"] = "Hello World!"
info_server = infoServer()
info_server_proxy = whiteInfoServerProxy(info_server)
print(info_server_proxy.recv(info_struct))
info_server_proxy.show()
info_server_proxy.addWhite(10010)
print(info_server_proxy.recv(info_struct))
info_server_proxy.show()
"""执行结果
Your address is not in the white list.
SHOW:
recv OK!
SHOW:Hello World!
"""

4.行为型模式

1.策略模式(Strategy Pattern)

1.概述: 定义一组算法,将每个算法都封装起来,并使他们之间可互换,算法策略比较经常地需要被替换时,可以使用策略模式

2.示例1: 出行方式选择

class TravelStrategy:
"""出行策略类"""

def travelAlgorithm(self):  
    pass

class AirplaneStrategy(TravelStrategy):
"""飞机策略类"""

def travelAlgorithm(self):  
    print("坐飞机出行....")

class TrainStrategy(TravelStrategy):
"""高铁策略类"""

def travelAlgorithm(self):  
    print("坐高铁出行....")

class CarStrategy(TravelStrategy):
"""自驾策略类"""

def travelAlgorithm(self):  
    print("自驾出行....")

class BicycleStrategy(TravelStrategy):
"""骑车策略类"""

def travelAlgorithm(self):  
    print("骑车出行....")

class TravelInterface:
"""旅行类"""

def \_\_init\_\_(self, travel\_strategy):  
    self.travel\_strategy = travel\_strategy

def set\_strategy(self, travel\_strategy):  
    self.travel\_strategy = travel\_strategy

def travel(self):  
    return self.travel\_strategy.travelAlgorithm()

坐飞机

travel = TravelInterface(AirplaneStrategy())

travel.travel()

改开车

travel.set_strategy(TrainStrategy())
travel.travel()
"""执行结果
坐飞机出行….
坐高铁出行….
"""

3.示例2: 客户消息通知

class customer:
"""客户类"""
customer_name = ""
snd_way = ""
info = ""
phone = ""
email = ""

def setPhone(self, phone):  
    self.phone = phone

def setEmail(self, mail):  
    self.email = mail

def getPhone(self):  
    return self.phone

def getEmail(self):  
    return self.email

def setInfo(self, info):  
    self.info = info

def setName(self, name):  
    self.customer\_name = name

def setBrdWay(self, snd\_way):  
    self.snd\_way = snd\_way

def sndMsg(self):  
    self.snd\_way.send(self.info)

class msgSender:
"""抽象通知方式类"""
dst_code = ""

def setCode(self, code):  
    self.dst\_code = code

def send(self, info):  
    pass

class emailSender(msgSender):
"""邮件通知类"""

def send(self, info):  
    print("EMAIL\_ADDRESS:%s EMAIL:%s" % (self.dst\_code, info))

class textSender(msgSender):
"""短信通知类"""

def send(self, info):  
    print("TEXT\_CODE:%s EMAIL:%s" % (self.dst\_code, info))

if __name__ == "__main__":
customer_x = customer()
customer_x.setName("CUSTOMER_X")
customer_x.setPhone("")
customer_x.setEmail("customer_x@xmail.com")
customer_x.setInfo("Welcome to our new party!")
text_sender = textSender()
text_sender.setCode(customer_x.getPhone())
customer_x.setBrdWay(text_sender)
customer_x.sndMsg()
mail_sender = emailSender()
mail_sender.setCode(customer_x.getEmail())
customer_x.setBrdWay(mail_sender)
customer_x.sndMsg()
"""执行结果
TEXT_CODE:10023456789 EMAIL:Welcome to our new party!
EMAIL_ADDRESS:customer_x@xmail.com EMAIL:Welcome to our new party!
"""

2.责任链模式(Chain of Responsibility Pattern)

1.概述: 使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系

2.示例1: 统一处理接口

# 处理器基类,其中包含下一个处理器
class BaseHandler:
"""处理基类"""

def successor(self, successor):  
    # 与下一个责任者关联  
    self.\_successor = successor

处理器1

class RequestHandlerL1(BaseHandler):
"""第一级请求处理者"""
name = "TeamLeader"

def handle(self, request):  
    if request < 500:  
        print("审批者\[%s\],请求金额\[%s\],审批结果\[审批通过\]" % (self.name, request))  
    else:  
        print("\\033\[31;1m\[%s\]无权审批,交给下一个审批者\\033\[0m" % self.name)  
        self.\_successor.handle(request)

处理器2

class RequestHandlerL2(BaseHandler):
"""第二级请求处理者"""
name = "DeptManager"

def handle(self, request):  
    if request < 5000:  
        print("审批者\[%s\],请求金额\[%s\],审批结果\[审批通过\]" % (self.name, request))  
    else:  
        print("\\033\[31;1m\[%s\]无权审批,交给下一个审批者\\033\[0m" % self.name)  
        self.\_successor.handle(request)

处理器3

class RequestHandlerL3(BaseHandler):
"""第三级请求处理者"""
name = "CEO"

def handle(self, request):  
    if request < 10000:  
        print("审批者\[%s\],请求金额\[%s\],审批结果\[审批通过\]" % (self.name, request))  
    else:  
        print("\\033\[31;1m\[%s\]要太多钱了,不批\\033\[0m" % self.name)  
        # self.\_successor.handle(request)

统一的接口

class RequestAPI:
"""统一的接口类"""

# 创建处理器1,2,3的实例  
h1 = RequestHandlerL1()  
h2 = RequestHandlerL2()  
h3 = RequestHandlerL3()

# 责任链: 处理器1--处理器2--处理器3  
h1.successor(h2)  
h2.successor(h3)

def \_\_init\_\_(self, name, amount):  
    self.name = name  
    self.amount = amount

# 统一处理API  
def handle(self):  
    """统一请求接口"""  
    # 在满足条件的情况下(>5000),会依次执行h1,h2,h3的handle  
    self.h1.handle(self.amount)

if __name__ == "__main__":
r1 = RequestAPI("echo", 30000)
r1.handle()
print(r1.__dict__)
"""执行结果
[TeamLeader]无权审批,交给下一个审批者
[DeptManager]无权审批,交给下一个审批者
[CEO]要太多钱了,不批
{'name': 'echo', 'amount': 30000}
"""

3.示例2: 请假系统

class manager:
"""抽象经理类"""
successor = None
name = ''

def \_\_init\_\_(self, name):  
    self.name = name

def setSuccessor(self, successor):  
    self.successor = successor

def handleRequest(self, request):  
    pass

class lineManager(manager):
"""直属经理类"""

def handleRequest(self, request):  
    if request.requestType == 'DaysOff' and request.number <= 3:  
        print('%s:%s Num:%d Accepted OVER' % (self.name, request.requestContent, request.number))  
    else:  
        print('%s:%s Num:%d Accepted CONTINUE' % (self.name, request.requestContent, request.number))  
        if self.successor != None:  
            self.successor.handleRequest(request)

class departmentManager(manager):
"""部门经理类"""

def handleRequest(self, request):  
    if request.requestType == 'DaysOff' and request.number <= 7:  
        print('%s:%s Num:%d Accepted OVER' % (self.name, request.requestContent, request.number))  
    else:  
        print('%s:%s Num:%d Accepted CONTINUE' % (self.name, request.requestContent, request.number))  
        if self.successor != None:  
            self.successor.handleRequest(request)

class generalManager(manager):
"""总经理类"""

def handleRequest(self, request):  
    if request.requestType == 'DaysOff':  
        print('%s:%s Num:%d Accepted OVER' % (self.name, request.requestContent, request.number))

class request:
"""假期请求类"""
requestType = ''
requestContent = ''
number = 0

if __name__ == "__main__":
line_manager = lineManager('LINE MANAGER')
department_manager = departmentManager('DEPARTMENT MANAGER')
general_manager = generalManager('GENERAL MANAGER')

line\_manager.setSuccessor(department\_manager)  
department\_manager.setSuccessor(general\_manager)

req = request()  
req.requestType = 'DaysOff'  
req.requestContent = 'Ask 1 day off'  
req.number = 1  
line\_manager.handleRequest(req)

req.requestType = 'DaysOff'  
req.requestContent = 'Ask 5 days off'  
req.number = 5  
line\_manager.handleRequest(req)

req.requestType = 'DaysOff'  
req.requestContent = 'Ask 10 days off'  
req.number = 10  
line\_manager.handleRequest(req)  

"""执行结果
LINE MANAGER:Ask 1 day off Num:1 Accepted OVER
LINE MANAGER:Ask 5 days off Num:5 Accepted CONTINUE
DEPARTMENT MANAGER:Ask 5 days off Num:5 Accepted OVER
LINE MANAGER:Ask 10 days off Num:10 Accepted CONTINUE
DEPARTMENT MANAGER:Ask 10 days off Num:10 Accepted CONTINUE
GENERAL MANAGER:Ask 10 days off Num:10 Accepted OVER
"""

3.命令模式(Command Pattern)

1.概述: 将一个请求封装成一个对象,从而可以使用不同的请求将客户端参数化,对请求排队或者记录请求日志可提供命令的撤销,恢复功能

2.示例: 饭店点餐系统

class backSys:
"""抽象后台系统类"""

def cook(self, dish):  
    pass

class mainFoodSys(backSys):
"""主食子系统类"""

def cook(self, dish):  
    print("MAINFOOD:Cook %s" % dish)

class coolDishSys(backSys):
"""凉菜子系统类"""

def cook(self, dish):  
    print("COOLDISH:Cook %s" % dish)

class hotDishSys(backSys):
"""热菜子系统类"""

def cook(self, dish):  
    print("HOTDISH:Cook %s" % dish)

class waiterSys:
"""前台系统类"""

menu\_map = dict()  
commandList = \[\]

def setOrder(self, command):  
    print("WAITER:Add dish")  
    self.commandList.append(command)

def cancelOrder(self, command):  
    print("WAITER:Cancel order...")  
    self.commandList.remove(command)

def notify(self):  
    print("WAITER:Nofify...")  
    for command in self.commandList:  
        command.execute()

命令类构建: 前台系统中的notify接口直接调用命令中的execute接口执行命令

class Command:
"""抽象命令类"""

receiver = None

def \_\_init\_\_(self, receiver):  
    self.receiver = receiver

def execute(self):  
    pass

class foodCommand(Command):
"""食物命令类"""
dish = ""

def \_\_init\_\_(self, receiver, dish):  
    self.receiver = receiver  
    self.dish = dish

def execute(self):  
    self.receiver.cook(self.dish)

class mainFoodCommand(foodCommand):
"""主食命令类"""
pass

class coolDishCommand(foodCommand):
"""凉菜命令类"""
pass

class hotDishCommand(foodCommand):
"""热菜命令类"""
pass

class menuAll:
"""菜单类"""
menu_map = dict()

def loadMenu(self):  # 加载菜单,这里直接写死  
    self.menu\_map\["hot"\] = \["Yu-Shiang Shredded Pork", "Sauteed Tofu, Home Style", "Sauteed Snow Peas"\]  
    self.menu\_map\["cool"\] = \["Cucumber", "Preserved egg"\]  
    self.menu\_map\["main"\] = \["Rice", "Pie"\]

def isHot(self, dish):  
    if dish in self.menu\_map\["hot"\]:  
        return True  
    return False

def isCool(self, dish):  
    if dish in self.menu\_map\["cool"\]:  
        return True  
    return False

def isMain(self, dish):  
    if dish in self.menu\_map\["main"\]:  
        return True  
    return False

if __name__ == "__main__":
dish_list = ["Yu-Shiang Shredded Pork", "Sauteed Tofu, Home Style", "Cucumber", "Rice"] # 顾客点的菜
waiter_sys = waiterSys()
main_food_sys = mainFoodSys()
cool_dish_sys = coolDishSys()
hot_dish_sys = hotDishSys()
menu = menuAll()
menu.loadMenu()
for dish in dish_list:
if menu.isCool(dish):
cmd = coolDishCommand(cool_dish_sys, dish)
elif menu.isHot(dish):
cmd = hotDishCommand(hot_dish_sys, dish)
elif menu.isMain(dish):
cmd = mainFoodCommand(main_food_sys, dish)
else:
continue
waiter_sys.setOrder(cmd)
waiter_sys.notify()
"""执行结果
WAITER:Add dish
WAITER:Add dish
WAITER:Add dish
WAITER:Add dish
WAITER:Nofify…
HOTDISH:Cook Yu-Shiang Shredded Pork
HOTDISH:Cook Sauteed Tofu, Home Style
COOLDISH:Cook Cucumber
MAINFOOD:Cook Rice
"""

4.中介者模式(Mediator Pattern)

1.概述: 用一个中介对象封装一系列的对象交互,中介者使各对象不需要显式地互相作用,从而使其耦合松散

2.示例: 仓储管理系统

class colleague:
"""抽象同事类"""
mediator = None

def \_\_init\_\_(self, mediator):  
    self.mediator = mediator

class purchaseColleague(colleague):
"""采购同事类"""

def buyStuff(self, num):  
    print("PURCHASE:Bought %s" % num)  
    self.mediator.execute("buy", num)

def getNotice(self, content):  
    print("PURCHASE:Get Notice--%s" % content)

class warehouseColleague(colleague):
"""仓库同事类"""
total = 0
threshold = 100

def setThreshold(self, threshold):  
    self.threshold = threshold

def isEnough(self):  
    if self.total < self.threshold:  
        print("WAREHOUSE:Warning...Stock is low... ")  
        self.mediator.execute("warning", self.total)  
        return False  
    else:  
        return True

def inc(self, num):  
    self.total += num  
    print("WAREHOUSE:Increase %s" % num)  
    self.mediator.execute("increase", num)  
    self.isEnough()

def dec(self, num):  
    if num > self.total:  
        print("WAREHOUSE:Error...Stock is not enough")  
    else:  
        self.total -= num  
        print("WAREHOUSE:Decrease %s" % num)  
        self.mediator.execute("decrease", num)  
    self.isEnough()

class salesColleague(colleague):
"""销售同事类"""

def sellStuff(self, num):  
    print("SALES:Sell %s" % num)  
    self.mediator.execute("sell", num)

def getNotice(self, content):  
    print("SALES:Get Notice--%s" % content)

class abstractMediator:
"""中介者基类"""
purchase = ""
sales = ""
warehouse = ""

def setPurchase(self, purchase):  
    self.purchase = purchase

def setWarehouse(self, warehouse):  
    self.warehouse = warehouse

def setSales(self, sales):  
    self.sales = sales

def execute(self, content, num):  
    pass

KA直接协调各个同事的工作

class stockMediator(abstractMediator):
"""KA中介者类"""

def execute(self, content, num):  
    print("MEDIATOR:Get Info--%s" % content)  
    if content == "buy":  
        self.warehouse.inc(num)  
        self.sales.getNotice("Bought %s" % num)  
    elif content == "increase":  
        self.sales.getNotice("Inc %s" % num)  
        self.purchase.getNotice("Inc %s" % num)  
    elif content == "decrease":  
        self.sales.getNotice("Dec %s" % num)  
        self.purchase.getNotice("Dec %s" % num)  
    elif content == "warning":  
        self.sales.getNotice("Stock is low.%s Left." % num)  
        self.purchase.getNotice("Stock is low. Please Buy More!!! %s Left" % num)  
    elif content == "sell":  
        self.warehouse.dec(num)  
        self.purchase.getNotice("Sold %s" % num)  
    else:  
        pass

if __name__ == "__main__":
mobile_mediator = stockMediator() # 先配置
mobile_purchase = purchaseColleague(mobile_mediator)
mobile_warehouse = warehouseColleague(mobile_mediator)
mobile_sales = salesColleague(mobile_mediator)
mobile_mediator.setPurchase(mobile_purchase)
mobile_mediator.setWarehouse(mobile_warehouse)
mobile_mediator.setSales(mobile_sales)

mobile\_warehouse.setThreshold(200)  # 设置仓储阈值为200  
mobile\_purchase.buyStuff(300)  # 先采购300  
mobile\_sales.sellStuff(120)  # 再卖出120  

"""执行结果
PURCHASE:Bought 300
MEDIATOR:Get Info--buy
WAREHOUSE:Increase 300
MEDIATOR:Get Info--increase
SALES:Get Notice--Inc 300
PURCHASE:Get Notice--Inc 300
SALES:Get Notice--Bought 300
SALES:Sell 120
MEDIATOR:Get Info--sell
WAREHOUSE:Decrease 120
MEDIATOR:Get Info--decrease
SALES:Get Notice--Dec 120
PURCHASE:Get Notice--Dec 120
WAREHOUSE:Warning…Stock is low…
MEDIATOR:Get Info--warning
SALES:Get Notice--Stock is low.180 Left.
PURCHASE:Get Notice--Stock is low. Please Buy More!!! 180 Left
PURCHASE:Get Notice--Sold 120
"""

5.模板模式(Template Pattern)

1.概述: 定义一个操作中的算法的框架,而将一些步骤延迟到子类中,使得子类可以不改变算法的结构即可重新定义该算法的某些特定的步骤

2.示例1: 注册登录

# 注册基类,定义所有注册都需要的步骤
class Register:
"""用户注册接口类"""

def register(self):  
    pass

def login(self):  
    pass

def auth(self):  
    self.register()  
    self.login()

QQ登录的具体实现

class RegisterByQQ(Register):
"""qq注册类"""

def register(self):  
    print("---用qq注册-----")

def login(self):  
    print('----用qq登录-----')

WeiChat登录的具体实现

class RegisterByWeiChat(Register):
"""微信注册类"""

def register(self):  
    print("---用微信注册-----")

def login(self):  
    print('----用微信登录-----')

if __name__ == "__main__":
register1 = RegisterByQQ()
register1.login()

register2 = RegisterByWeiChat()  
register2.login()  

"""执行结果
----用qq登录-----
----用微信登录-----
"""

3.示例2: 股票查询客户端

class StockQueryDevice:
"""股票查询类"""

stock\_code = ""  
stock\_price = 0.0

def login(self, usr, pwd):  
    pass

def setCode(self, code):  
    self.stock\_code = code

def queryPrice(self):  
    pass

def showPrice(self):  
    pass

# 实现封装登录,设置代码,查询,展示的步骤  
def operateQuery(self, usr, pwd, code):  
    self.login(usr, pwd)  
    self.setCode(code)  
    self.queryPrice()  
    self.showPrice()  
    return True

# 登录  
def login(self, usr, pwd):  
    pass

# 设置股票代码  
def setCode(self, code):  
    self.stock\_code = code

# 查询  
def queryPrice(self):  
    pass

# 展示  
def showPrice(self):  
    pass

class WebAStockQueryDevice(StockQueryDevice):
"""WebA查询类"""

def login(self, usr, pwd):  
    if usr == "myStockA" and pwd == "myPwdA":  
        print("Web A:Login OK... user:%s pwd:%s" % (usr, pwd))  
        return True  
    else:  
        print("Web A:Login ERROR... user:%s pwd:%s" % (usr, pwd))  
        return False

def queryPrice(self):  
    print("Web A Querying...code:%s " % self.stock\_code)  
    self.stock\_price = 20.00

def showPrice(self):  
    print("Web A Stock Price...code:%s price:%s" % (self.stock\_code, self.stock\_price))

class WebBStockQueryDevice(StockQueryDevice):
"""WebB查询类"""

def login(self, usr, pwd):  
    if usr == "myStockB" and pwd == "myPwdB":  
        print("Web B:Login OK... user:%s pwd:%s" % (usr, pwd))  
        return True  
    else:  
        print("Web B:Login ERROR... user:%s pwd:%s" % (usr, pwd))  
        return False

def queryPrice(self):  
    print("Web B Querying...code:%s " % self.stock\_code)  
    self.stock\_price = 30.00

def showPrice(self):  
    print("Web B Stock Price...code:%s price:%s" % (self.stock\_code, self.stock\_price))

def operateQuery(self, usr, pwd, code):
"""登录判断"""
if not self.login(usr, pwd):
return False
self.setCode(code)
self.queryPrice()
self.showPrice()
return True

if __name__ == "__main__":
# 在网站A上查询股票
web_a_query_dev = WebAStockQueryDevice()
web_a_query_dev.operateQuery("myStockA", "myPwdA", "")
"""执行结果
Web A:Login OK… user:myStockA pwd:myPwdA
Web A Querying…code:12345
Web A Stock Price…code:12345 price:20.0
"""

6.迭代器模式(Iterator Pattern)

1.概述: 它提供一种方法,访问一个容器对象中各个元素,而又不需要暴露对象的内部细节

2.示例1: 可迭代对象

if __name__ == "__main__":
lst = ["hello Alice", "hello Bob", "hello Eve"]
lst_iter = iter(lst)
print(lst_iter)
print(next(lst_iter))
print(next(lst_iter))
print(lst_iter.__next__())
print(lst_iter.__next__())
"""执行结果

hello Alice
hello Bob
hello Eve
Traceback (most recent call last):
File "/Users/tangxuecheng/Desktop/python3/demo/demo1.py", line 8, in
print(lst_iter.__next__())
StopIteration
"""

3.示例2: 自定义迭代器类

class MyIter:
"""自定义迭代器类"""

def \_\_init\_\_(self, n):  
    self.index = 0  
    self.n = n

def \_\_iter\_\_(self):  
    # return MyIter(self.n)  # 次写法可以让迭代器重复迭代  
    return self  # 此写法迭代器只能迭代一次

def \_\_next\_\_(self):  
    if self.index < self.n:  
        value = self.index \*\* 2  
        self.index += 1  
        return value  
    else:  
        raise StopIteration()

if __name__ == "__main__":
x_square = MyIter(10)
for x in x_square:
print(x, end=" ")
"""执行结果
0 1 4 9 16 25 36 49 64 81
"""

7.访问者模式(Visitor Pattern)

1.概述: 封装一些作用于某种数据结构中的各元素的操作,它可以在不改变数据结构的前提下定义于作用于这些元素的新操作

2.示例: 药房业务系统

class Medicine:
"""药品基类"""
name = ""
price = 0.0

def \_\_init\_\_(self, name, price):  
    self.name = name  
    self.price = price

def getName(self):  
    return self.name

def setName(self, name):  
    self.name = name

def getPrice(self):  
    return self.price

def setPrice(self, price):  
    self.price = price

def accept(self, visitor):  
    pass

class Antibiotic(Medicine):
"""抗生素类"""

def accept(self, visitor):  
    visitor.visit(self)

class Coldrex(Medicine):
"""感冒药类"""

def accept(self, visitor):  
    visitor.visit(self)

class Visitor:
"""工作人员基类"""
name = ""

def setName(self, name):  
    self.name = name

def visit(self, medicine):  
    pass

class Charger(Visitor):
"""划价员类"""

def visit(self, medicine):  
    print("CHARGE: %s lists the Medicine %s. Price:%s " % (self.name, medicine.getName(), medicine.getPrice()))

class Pharmacy(Visitor):
"""药房管理员类"""

def visit(self, medicine):  
    print("PHARMACY:%s offers the Medicine %s. Price:%s" % (self.name, medicine.getName(), medicine.getPrice()))

class ObjectStructure:
pass

class Prescription(ObjectStructure):
"""药方类"""
medicines = []

def addMedicine(self, medicine):  
    self.medicines.append(medicine)

def rmvMedicine(self, medicine):  
    self.medicines.append(medicine)

def visit(self, visitor):  
    for medc in self.medicines:  
        medc.accept(visitor)

if __name__ == "__main__":
yinqiao_pill = Coldrex("Yinqiao Pill", 2.0)
penicillin = Antibiotic("Penicillin", 3.0)
doctor_prsrp = Prescription()
doctor_prsrp.addMedicine(yinqiao_pill)
doctor_prsrp.addMedicine(penicillin)
charger = Charger()
charger.setName("Doctor Strange")
pharmacy = Pharmacy()
pharmacy.setName("Doctor Wei")
doctor_prsrp.visit(charger)
doctor_prsrp.visit(pharmacy)
"""执行结果
CHARGE: Doctor Strange lists the Medicine Yinqiao Pill. Price:2.0
CHARGE: Doctor Strange lists the Medicine Penicillin. Price:3.0
PHARMACY:Doctor Wei offers the Medicine Yinqiao Pill. Price:2.0
PHARMACY:Doctor Wei offers the Medicine Penicillin. Price:3.0
"""

8.观察者模式(Observer Pattern)

1.概述: 定义对象间一种一对多的依赖关系,使得当该对象状态改变时,所有依赖于它的对象都会得到通知,并被自动更新

2.示例1: 粉丝推广

class ObserverBase:
"""观察者基类,类似于大V账户"""

def \_\_init\_\_(self):  
    self.\_observerd\_list = \[\]  # 粉丝列表

def attach(self, observe\_subject):  
    """添加要观察的对象,添加粉丝"""  
    if observe\_subject not in self.\_observerd\_list:  
        self.\_observerd\_list.append(observe\_subject)  
        print("\[%s\]已经将\[%s\]加入观察队列..." % (self.name, observe\_subject))

def detach(self, observe\_subject):  
    """解除观察关系,删除粉丝"""  
    try:  
        self.\_observerd\_list.remove(observe\_subject)  
        print("不再观察\[%s\]" % observe\_subject)  
    except ValueError:  
        pass

def notify(self):  
    """通知所有被观察者,通知粉丝"""  
    # 粉丝.by\_notified(self)  
    for fun\_obj in self.\_observerd\_list:  
        fun\_obj.by\_notified(self)

class Observer(ObserverBase):
"""观察者类,实际的大V"""

def \_\_init\_\_(self, name):  
    super(Observer, self).\_\_init\_\_()  
    self.name = name  
    self.\_msg = ''

@property  
def msg(self):  
    """当前状况"""  
    return self.\_msg

@msg.setter  
def msg(self, content):  
    """当msg这个属性被设置的时候,执行的方法"""  
    self.\_msg = content  
    self.notify()

class FenViewer:
"""粉丝类"""

def \_\_init\_\_(self, name):  
    self.name = name

def by\_notified(self, big\_v\_object):  
    print("粉丝\[%s\]:收到\[%s\]消息\[%s\] " % (self.name, big\_v\_object.name, big\_v\_object.msg))

if __name__ == "__main__":
big_v_1 = Observer("大V_1")
big_v_2 = Observer("大V_2")

fen\_a = FenViewer("粉丝A")  
fen\_b = FenViewer("粉丝B")

big\_v\_1.attach(fen\_a)  
big\_v\_1.attach(fen\_b)

big\_v\_2.attach(fen\_b)

big\_v\_1.msg = "\\033\[32;1m官宣...\\033\[0m"  
big\_v\_2.msg = "\\033\[31;1m广告推荐~~~\\033\[0m"  

"""执行结果
[大V_1]已经将[<__main__.FenViewer object at 0x10ee6fc50>]加入观察队列…
[大V_1]已经将[<__main__.FenViewer object at 0x10ee6fc90>]加入观察队列…
[大V_2]已经将[<__main__.FenViewer object at 0x10ee6fc90>]加入观察队列…
粉丝[粉丝A]:收到[大V_1]消息[官宣…]
粉丝[粉丝B]:收到[大V_1]消息[官宣…]
粉丝[粉丝B]:收到[大V_2]消息[广告推荐~~~]
"""

3.示例2: 火警报警器

# 三个类提取共性,泛化出观察者类,并构造被观察者
class Observer:
"""抽象共性类"""

def update(self):  
    pass

class AlarmSensor(Observer):
"""报警器类"""

def update(self, action):  
    print("Alarm Got: %s" % action)  
    self.runAlarm()

def runAlarm(self):  
    print("Alarm Ring...")

class WaterSprinker(Observer):
"""喷水器类"""

def update(self, action):  
    print("Sprinker Got: %s" % action)  
    self.runSprinker()

def runSprinker(self):  
    print("Spray Water...")

class EmergencyDialer(Observer):
"""拨号器类"""

def update(self, action):  
    print("Dialer Got: %s" % action)  
    self.runDialer()

def runDialer(self):  
    print("Dial 119...")

class Observed:
"""观察者类"""
observers = []
action = ""

def addObserver(self, observer):  
    self.observers.append(observer)

def notifyAll(self):  
    for obs in self.observers:  
        obs.update(self.action)

class smokeSensor(Observed):
"""烟雾传感器类"""

def setAction(self, action):  
    self.action = action

def isFire(self):  
    return True

if __name__ == "__main__":
alarm = AlarmSensor()
sprinker = WaterSprinker()
dialer = EmergencyDialer()

smoke\_sensor = smokeSensor()  
smoke\_sensor.addObserver(alarm)  
smoke\_sensor.addObserver(sprinker)  
smoke\_sensor.addObserver(dialer)

if smoke\_sensor.isFire():  
    smoke\_sensor.setAction("On Fire!")  
    smoke\_sensor.notifyAll()  

"""执行结果
Alarm Got: On Fire!
Alarm Ring…
Sprinker Got: On Fire!
Spray Water…
Dialer Got: On Fire!
Dial 119…
"""

9.解释器模式(Interpreter Pattern)

1.概述: 给定一种语言,定义它的文法表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子

2.示例: 模拟吉他

class PlayContext():
"""乐谱类"""
play_text = None

class Expression():
"""解释器表达式类"""

def interpret(self, context):  
    """转译乐谱"""  
    if len(context.play\_text) == 0:  
        return  
    else:  
        play\_segs = context.play\_text.split(" ")  
        for play\_seg in play\_segs:  
            pos = 0  
            for ele in play\_seg:  
                if ele.isalpha():  
                    pos += 1  
                    continue  
                break  
            play\_chord = play\_seg\[0:pos\]  
            play\_value = play\_seg\[pos:\]  
            self.execute(play\_chord, play\_value)

def execute(self, play\_key, play\_value):  
    """演奏乐谱"""  
    pass

class NormGuitar(Expression):
"""吉他类"""

def execute(self, key, value):  
    """覆盖父类的演奏乐谱方法"""  
    print("Normal Guitar Playing--Chord:%s Play Tune:%s" % (key, value))

if __name__ == "__main__":
context = PlayContext()
context.play_text = "C53231323 Em43231323 F43231323 G63231323"
guitar = NormGuitar()
guitar.interpret(context)
"""执行结果
Normal Guitar Playing--Chord:C Play Tune:53231323
Normal Guitar Playing--Chord:Em Play Tune:43231323
Normal Guitar Playing--Chord:F Play Tune:43231323
Normal Guitar Playing--Chord:G Play Tune:63231323
"""

10.备忘录模式(Memento Pattern)

1.概述: 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以将该对象恢复到原来保存的状态

2.示例: 游戏进度保存

import random

实现保存进度

class Memento:
"""备忘录类"""
vitality = 0
attack = 0
defense = 0

def \_\_init\_\_(self, vitality, attack, defense):  
    self.vitality = vitality  
    self.attack = attack  
    self.defense = defense

定义基本的生命值,攻击值,防御值以及实现角色状态控制的方法

class GameCharacter:
"""整体控制类"""
vitality = 0
attack = 0
defense = 0

def displayState(self):  
    print('Current Values:')  
    print('Life:%d' % self.vitality)  
    print('Attack:%d' % self.attack)  
    print('Defence:%d' % self.defense)

def initState(self, vitality, attack, defense):  
    self.vitality = vitality  
    self.attack = attack  
    self.defense = defense

def saveState(self):  
    return Memento(self.vitality, self.attack, self.defense)

def recoverState(self, memento):  
    self.vitality = memento.vitality  
    self.attack = memento.attack  
    self.defense = memento.defense

实现具体的战斗接口

class FightCharactor(GameCharacter):
"""战斗类"""

def fight(self):  
    self.vitality -= random.randint(1, 10)

if __name__ == "__main__":
game_chrctr = FightCharactor()
game_chrctr.initState(100, 79, 60)
game_chrctr.displayState()
memento = game_chrctr.saveState()
game_chrctr.fight()
game_chrctr.displayState()
game_chrctr.recoverState(memento)
game_chrctr.displayState()
"""执行结果
Current Values:
Life:100
Attack:79
Defence:60
Current Values:
Life:94
Attack:79
Defence:60
Current Values:
Life:100
Attack:79
Defence:60
"""

11.状态模式(State Pattern)

1.概述: 当一个对象内在状态改变时允许其改变行为,这个对象看起来像改变了其类

2.示例: 电梯控制器

class LiftState:
"""抽象电梯状态基类"""

def open(self):  
    pass

def close(self):  
    pass

def run(self):  
    pass

def stop(self):  
    pass

class OpenState(LiftState):
"""开放状态类"""

def open(self):  
    print("OPEN:The door is opened...")  
    return self

def close(self):  
    print("OPEN:The door start to close...")  
    print("OPEN:The door is closed")  
    return StopState()

def run(self):  
    print("OPEN:Run Forbidden.")  
    return self

def stop(self):  
    print("OPEN:Stop Forbidden.")  
    return self

class RunState(LiftState):
"""运行状态类"""

def open(self):  
    print("RUN:Open Forbidden.")  
    return self

def close(self):  
    print("RUN:Close Forbidden.")  
    return self

def run(self):  
    print("RUN:The lift is running...")  
    return self

def stop(self):  
    print("RUN:The lift start to stop...")  
    print("RUN:The lift stopped...")  
    return StopState()

class StopState(LiftState):
"""停止状态类"""

def open(self):  
    print("STOP:The door is opening...")  
    print("STOP:The door is opened...")  
    return OpenState()

def close(self):  
    print("STOP:Close Forbidden")  
    return self

def run(self):  
    print("STOP:The lift start to run...")  
    return RunState()

def stop(self):  
    print("STOP:The lift is stopped.")  
    return self

class Context:
"""上下文调度状态记录类"""
lift_state = ""

def getState(self):  
    return self.lift\_state

def setState(self, lift\_state):  
    self.lift\_state = lift\_state

def open(self):  
    self.setState(self.lift\_state.open())

def close(self):  
    self.setState(self.lift\_state.close())

def run(self):  
    self.setState(self.lift\_state.run())

def stop(self):  
    self.setState(self.lift\_state.stop())

if __name__ == "__main__":
ctx = Context()
ctx.setState(StopState())
ctx.open()
ctx.run()
ctx.close()
ctx.run()
ctx.stop()
"""执行结果
STOP:The door is opening…
STOP:The door is opened…
OPEN:Run Forbidden.
OPEN:The door start to close…
OPEN:The door is closed
STOP:The lift start to run…
RUN:The lift start to stop…
RUN:The lift stopped…
"""