16_Python设计模式
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
{(<class '__main__.Spam'>, (1, 'abc'), ()): <__main__.Spam object at 0x108ffdbd0>,
(<class '__main__.Spam'>, (3, 'DEF'), ()): <__main__.Spam object at 0x108ffdc50>,
(<class '__main__.Egg'>, (1, 'abc'), ()): <__main__.Egg object at 0x108ffdc90>}
dict_keys([(<class '__main__.Spam'>, (1, 'abc'), ()), (<class '__main__.Spam'>,
(3, 'DEF'), ()), (<class '__main__.Egg'>, (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
<class '__main__.receive_class'>
<class '__main__.agent_class'>
"""
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__())
"""执行结果
<list_iterator object at 0x10acd8890>
hello Alice
hello Bob
hello Eve
Traceback (most recent call last):
File "/Users/tangxuecheng/Desktop/python3/demo/demo1.py", line 8, in <module>
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...
"""
16_Python设计模式的更多相关文章
- MVVM设计模式和WPF中的实现(四)事件绑定
MVVM设计模式和在WPF中的实现(四) 事件绑定 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在WPF中 ...
- java EE设计模式简介
1.何为设计模式 设计模式提供了对常见应用设计问题的解决方案.在面向对象的编程中,设计模式通常在解决与对象创建和交互相关的问题,而非整体软件架构所面对的大规模问题,它们以样板代码的形式提供了通用的解决 ...
- 计算机程序的思维逻辑 (54) - 剖析Collections - 设计模式
上节我们提到,类Collections中大概有两类功能,第一类是对容器接口对象进行操作,第二类是返回一个容器接口对象,上节我们介绍了第一类,本节我们介绍第二类. 第二类方法大概可以分为两组: 接受其他 ...
- 《JavaScript设计模式 张》整理
最近在研读另外一本关于设计模式的书<JavaScript设计模式>,这本书中描述了更多的设计模式. 一.创建型设计模式 包括简单工厂.工厂方法.抽象工厂.建造者.原型和单例模式. 1)简单 ...
- 《JavaScript设计模式与开发实践》整理
最近在研读一本书<JavaScript设计模式与开发实践>,进阶用的. 一.高阶函数 高阶函数是指至少满足下列条件之一的函数. 1. 函数可以作为参数被传递. 2. 函数可以作为返回值输出 ...
- 设计模式之行为类模式大PK
行为类模式大PK 行为类模式包括责任链模式.命令模式.解释器模式.迭代器模式.中介者模式.备忘录模式.观察者模式.状态模式.策略 ...
- .NET设计模式访问者模式
一.访问者模式的定义: 表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作. 二.访问者模式的结构和角色: 1.Visitor 抽象访问者角色,为该 ...
- Java开发中的23种设计模式详解
[放弃了原文访问者模式的Demo,自己写了一个新使用场景的Demo,加上了自己的理解] [源码地址:https://github.com/leon66666/DesignPattern] 一.设计模式 ...
- java 设计模式
目录: 设计模式六大原则(1):单一职责原则 设计模式六大原则(2):里氏替换原则 设计模式六大原则(3):依赖倒置原则 设计模式六大原则(4):接口隔离原则 设计模式六大原则(5):迪米特法则 设计 ...
随机推荐
- Android Studio简单的登陆界面
在app->src->main->java里面找到MainActivity.java,将鼠标放到activity-main上按住Ctrl后单击跳转到activity-main.xml ...
- 【项目实战】sass使用基础篇(上)
Sass是一种CSS预处理语言.CSS预处理语言是一种新的专门的编程语言,编译后形成正常的css文件,为css增加一些编程特性,无需考虑浏览器的兼容性(完全兼容css3),让css更加简洁.适应性更强 ...
- 新司机的致胜法宝,使用ApexSql Log2018快速恢复数据库被删除的数据
作为开发人员,误操作数据delete.update.insert是最正常不过的了,比如: 删除忘记加where条件: 查询为了图方便按了F5,但是数据里面夹杂着delete语句. 不管是打着后发动机声 ...
- 计算vtable的大小
在ClassFileParser::parseClassFile()函数中会计算vtable和itable所需要的大小,因为vtable和itable是内嵌在Klass中的,parseClassFil ...
- C#LeetCode刷题-线段树
线段树篇 # 题名 刷题 通过率 难度 218 天际线问题 32.7% 困难 307 区域和检索 - 数组可修改 42.3% 中等 315 计算右侧小于当前元素的个数 31.9% 困难 4 ...
- JavaScript 通过prototype改变原型的两种方式
// -------------------- prototype 1 -------------------- function A(){} A.prototype.n = 1 let b = ne ...
- Vue 大量data及rules的data选项结构组织
如果Vue文件需要很多的data成员及表单验证,建议使用类似结构 export default{ data(){ const model = { username: 'suzhen', passwor ...
- github渗透测试工具库[转载]
前言 今天看到一个博客里有这个置顶的工具清单,但是发现这些都是很早以前就有文章发出来的,我爬下来后一直放在txt里吃土.这里一起放出来. 漏洞练习平台 WebGoat漏洞练习平台:https://gi ...
- 12 种使用 Vue 的最佳做法
随着 VueJS 的使用越来越广泛,出现了几种最佳实践并逐渐成为标准. 1.始终在 v-for 中使用 :key 在需要操纵数据时,将key属性与v-for指令一起使用可以让程序保持恒定且可预测. 这 ...
- day8 文件
添加中文 需要编码 f = open("123.txt",'w',encoding='utf-8') 字符串转化二进制编码 encode() 1.文件: 计算机 ...