设计模式:对软件设计中普遍存在(反复出现)的各种问题,所提出的解决方案。每一个设计模式系统地命名,解释和评价了面向对象系统中一个重要的和重复出现的设计
# 1.导入抽象基类,让子类必须要实现该方法,
# 只是抽象方法,并不实现功能,只能继承,不能被实例化
from abc import ABCMeta, abstractmethod
# 2.定义接口类
# Payment 是一个抽象类,定义了一个pay的抽象方法
# 通过抽象方法,可以规范其子类在用此方法的接口规范
class Payment(metaclass=ABCMeta):
@abstractmethod
# 定义接口抽象方法
def pay(self, money):
pass
# 3.定义子类Alipay来继承接口抽象类
class Alipay(Payment):
# 子类继承父类方法,接口保持一致
def pay(self, money):
print("alipay=%d" % money)
# 4.定义子类Wechatpay来继承接口抽象类
class WechatPay(Payment):
def pay(self, money):
print("wechatpay=%d" % money)
# 5.实例化子类对象
alipay_test = Alipay()
wechat_test = WechatPay()
# 6.调用子类的方法
alipay_test.pay(200)
wechat_test.pay(100)
alipay=200
wechatpay=100
from abc import ABCMeta, abstractmethod
# 抽象接口,负责所有的支付接口的样式
class Payment(metaclass=ABCMeta):
@abstractmethod
def pay(self, money):
pass
# 阿里支付,继承payment
class Alipay(Payment):
def __init__(self, use_huabei=False):
self.use_huabei = use_huabei
def pay(self, money):
if self.use_huabei:
print("花呗支付%d元."% money)
else:
print("支付宝支付%d元." % money)
class WechatPay(Payment):
def pay(self, money):
print("微信支付%d元." % money)
# 简单工厂模式
class PaymentFactory:
def create_payment(self, method):
if method == 'alipay':
return Alipay()
elif method == 'wechat':
return WechatPay()
elif method == 'huabei':
return Alipay(use_huabei=True)
else:
raise TypeError("No such class named %s" % method)
pf = PaymentFactory()
p = pf.create_payment('huabei')
p.pay(1000)
# 输出
#花呗支付1000元.
内容:
定义一个用于创建对象的接口(工厂接口),让子类决定实例化哪一个产品类
(1)抽象工厂角色(creator)
(2)具体工厂角色(concrete creator)
(3)抽象产品角色(product)
(4)具体产品角色(concrete product)
优点:
(1)每个具体产品都对应一个具体工厂类,不需要修改工厂代码
(2)隐藏了对象创建的实现细节
缺点:
(1)每增加一个具体产品类,就必须增加一个相应的具体工厂类
代码
from abc import ABCMeta, abstractmethod
# 抽象接口(支付);负责所有的支付接口的样式
class Payment(metaclass=ABCMeta):
@abstractmethod
def pay(self, money):
pass
# 阿里支付,继承payment
class Alipay(Payment):
def __init__(self, use_huabei=False):
self.use_huabei = use_huabei
def pay(self, money):
if self.use_huabei:
print("花呗支付%d元." % money)
else:
print("支付宝支付%d元." % money)
# 微信支付,继承payment
class WechatPay(Payment):
def pay(self, money):
print("微信支付%d元." % money)
# 银联支付,继承payment
class BankPay(Payment):
def pay(self, money):
print("银联支付%d元." % money)
# 抽象接口(支付工厂);负责实例化类
class PaymentFactory(metaclass=ABCMeta):
@abstractmethod
def create_payment(self):
pass
# 阿里支付工厂类,继承自 PaymentFactory
class AlipayFactory(PaymentFactory):
def create_payment(self):
return Alipay()
# 微信支付工厂类,继承自 PaymentFactory
class WechatPayFactory(PaymentFactory):
def create_payment(self):
return WechatPay()
# 花呗支付工厂类,继承自 PaymentFactory
class HuabeiFactory(PaymentFactory):
def create_payment(self):
return Alipay(use_huabei=True)
# 银联支付工厂类,继承自 PaymentFactory
class BankPayFactory(PaymentFactory):
def create_payment(self):
return BankPay()
# HuabeiFactory -> Alipay(use_huabei=True) -> pay
hua_factory = HuabeiFactory()
hua_pay = hua_factory.create_payment()
hua_pay.pay(200)
bank_facotry = BankPayFactory()
bank_pay = bank_facotry.create_payment()
bank_pay.pay(300)
ali_factory = AlipayFactory()
ali_pay = ali_factory.create_payment()
ali_pay.pay(400)
we_factory = WechatPayFactory()
we_pay = we_factory.create_payment()
we_pay.pay(500)
花呗支付200元.
银联支付300元.
支付宝支付400元.
微信支付500元.
# -*- coding: utf-8 -*-
# @Project: zc
# @Author: zc
# @File name: abstract_factory
# @Create time: 2022/1/16 11:55
# 1.导入相关数据库
from abc import abstractmethod, ABCMeta
# 2. 手机壳抽象类
class PhoneShell(metaclass=ABCMeta):
@abstractmethod
def show_shell(self):
pass
# 3. CPU抽象类
class CPU(metaclass=ABCMeta):
@abstractmethod
def show_cpu(self):
pass
# 4.系统抽象类
class OS(metaclass=ABCMeta):
@abstractmethod
def show_os(self):
pass
# 5. 工厂抽象类
class PhoneFactory(metaclass=ABCMeta):
@abstractmethod
def make_shell(self):
pass
@abstractmethod
def make_cpu(self):
pass
@abstractmethod
def make_os(self):
pass
# 6.具体类;小手机壳
class SmallShell(PhoneShell):
def show_shell(self):
print("普通手机小手机壳")
# 7.具体类:大手机壳
class BigShell(PhoneShell):
def show_shell(self):
print("普通手机大手机壳")
# 8.具体类:苹果手机壳
class AppleShell(PhoneShell):
def show_shell(self):
print("苹果手机壳")
# 9.具体类: 晓龙CPU
class SnapDragonCPU(CPU):
def show_cpu(self):
print("晓龙CPU")
# 10.具体类:联发科CPU
class MediaTekCPU(CPU):
def show_cpu(self):
print("联发科CPU")
# 11.具体类:苹果CPU
class AppleCPU(CPU):
def show_cpu(self):
print("苹果CPU")
# 12.具体类:安卓系统
class Android(OS):
def show_os(self):
print("Android系统")
# 13. 具体类:苹果系统
class IOS(OS):
def show_os(self):
print("IOS系统")
# 14. 具体类:小米工厂
class MiFactory(PhoneFactory):
def __init__(self):
print("*" * 20)
print("mi_start")
print("xiaomifactory")
def make_shell(self):
return BigShell()
def make_cpu(self):
return SnapDragonCPU()
def make_os(self):
return Android()
# 具体类:华为工厂
class HuaweiFactory(PhoneFactory):
def __init__(self):
print("*" * 20)
print("huawei_start")
print("huaweifactory")
def make_shell(self):
return SmallShell()
def make_cpu(self):
return MediaTekCPU()
def make_os(self):
return Android()
# 具体类:苹果工厂
class IPhoneFactory(PhoneFactory):
def __init__(self):
print("*" * 20)
print("Apple_start")
print("Apple_factory")
def make_cpu(self):
return AppleCPU()
def make_os(self):
return IOS()
def make_shell(self):
return AppleShell()
# 手机类,收集工厂手机信息,返回相关结果
class Phone:
def __init__(self, cpu, os, shell):
self.cpu = cpu
self.os = os
self.shell = shell
def show_info(self):
print("手机信息:")
self.cpu.show_cpu()
self.os.show_os()
self.shell.show_shell()
print("*" * 20)
print('\n')
def make_phone(factory):
cpu = factory.make_cpu()
os = factory.make_os()
shell = factory.make_shell()
return Phone(cpu, os, shell)
xiaomi_phone = make_phone(MiFactory())
xiaomi_phone.show_info()
huawei_phone = make_phone(HuaweiFactory())
huawei_phone.show_info()
apple_phone = make_phone(IPhoneFactory())
apple_phone.show_info()
********************
mi_start
xiaomifactory
手机信息:
晓龙CPU
Android系统
普通手机大手机壳
********************
********************
huawei_start
huaweifactory
手机信息:
联发科CPU
Android系统
普通手机小手机壳
********************
********************
Apple_start
Apple_factory
手机信息:
苹果CPU
IOS系统
苹果手机壳
********************
# -*- coding: utf-8 -*-
# @Project: zc
# @Author: zc
# @File name: constructor_mode_test
# @Create time: 2022/1/16 16:06
from abc import abstractmethod, ABCMeta
class Player:
def __init__(self, face=None, body=None, arm=None, leg=None):
self.face = face
self.body = body
self.arm = arm
self.leg = leg
def __str__(self):
return "%s,%s,%s,%s" % (self.face, self.body, self.arm, self.leg)
# 抽象建造者(Builder)
class PlayerBuilder(metaclass=ABCMeta):
@abstractmethod
def build_face(self):
pass
@abstractmethod
def build_body(self):
pass
@abstractmethod
def build_arm(self):
pass
@abstractmethod
def build_leg(self):
pass
# 具体建造者(concrete builder)
class SexGirlBuilder(PlayerBuilder):
def __init__(self):
self.player = Player()
def build_face(self):
self.player.face = "sex_face"
def build_body(self):
self.player.body = "sex_body"
def build_arm(self):
self.player.arm = "sex_arm"
def build_leg(self):
self.player.leg = "sex_leg"
# 具体建造者(concrete builder)
class MonsterBuilder(PlayerBuilder):
def __init__(self):
self.player = Player()
def build_face(self):
self.player.face = "monster_face"
def build_body(self):
self.player.body = "monster_body"
def build_arm(self):
self.player.arm = "monster_arm"
def build_leg(self):
self.player.leg = "monster_leg"
# 指挥者(Director)
class PlayerDirector:
def build_player(self, builder):
builder.build_body()
builder.build_face()
builder.build_arm()
builder.build_leg()
return builder.player
# client
sex_builder = SexGirlBuilder()
director = PlayerDirector()
director_sex = director.build_player(sex_builder)
print(director_sex)
monster_builder = MonsterBuilder()
director_monster = director.build_player(monster_builder)
print(director_monster)
sex_face,sex_body,sex_arm,sex_leg
monster_face,monster_body,monster_arm,monster_leg
# 创建一个基类-单例类
class SingleTon:
def __new__(cls, *args, **kwargs):
# 在创建的时候查看是否有实例
# 如果没有实例,创建一个实例
# 如果有实例,则返回以前的实例
if not hasattr(cls, "_instance"):
cls._instance = super(SingleTon, cls).__new__(cls)
return cls._instance
# 子类继承单例类
class MyClass(SingleTon):
def __init__(self, word):
self.word = word
# 创建实例a,b
a = MyClass(100)
b = MyClass(200)
print(f'a.word={a.word}')
print(f'b.word={b.word}')
# 因为是单例模式,所以a的值会被b的值取代掉,这样就只有一个实例了
print(f'id(a)==id(b) is {id(a) == id(b)}')
a.word=200
b.word=200
id(a)==id(b) is True
from abc import abstractmethod, ABCMeta
class Payment(metaclass=ABCMeta):
@abstractmethod
def pay(self, money):
pass
class Alipay(Payment):
def pay(self, money):
print("alipay is %d" % money)
class Wechat(Payment):
def pay(self, money):
print("wechat is %d" % money)
class Bankpay:
def cost(self, money):
print("the cost is %d" % money)
class Applepay:
def cost(self, money):
print("the cost is %d" % money)
# 对象适配器
class PaymentAdaptor(Payment):
def __init__(self, payment):
self.payment = payment
def pay(self, money):
self.payment.cost(money)
p = PaymentAdaptor(Applepay())
p.pay(100)
from abc import ABCMeta, abstractmethod
class Shape(metaclass=ABCMeta):
def __init__(self, color):
self.color = color
@abstractmethod
def draw(self):
pass
class Color(metaclass=ABCMeta):
@abstractmethod
def paint(self):
pass
class Rectangle(Shape):
name = "长方形"
def draw(self):
self.color.paint(self)
class Circle(Shape):
name = "圆形"
def draw(self):
self.color.paint(self)
class Line(Shape):
name = "直线"
def draw(self):
self.color.paint(self)
class Red(Color):
def paint(self, shape):
print("红色的%s" % shape.name)
class Green(Color):
def paint(self, shape):
print("蓝色的%s" % shape.name)
class Yellow(Color):
def paint(self, shape):
print("黄色的%s" % shape.name)
shape_1 = Rectangle(Red())
shape_1.draw()
shape_2 = Circle(Green())
shape_2.draw()
shape_3 = Line(Yellow())
shape_3.draw()
红色的长方形
蓝色的圆形
黄色的直线
from abc import ABCMeta, abstractmethod
# 抽象组件
class Graphic(metaclass=ABCMeta):
@abstractmethod
def draw(self):
pass
# 叶子组件
class Point(Graphic):
def __init__(self, x, y):
self.x = x
self.y = y
def __str__(self):
return "点(%s , %s)" % (self.x, self.y)
def draw(self):
print(str(self))
# 叶子组件
class Line(Graphic):
def __init__(self, p1, p2):
self.p1 = p1
self.p2 = p2
def __str__(self):
return "line[%s,%s]" % (self.p1, self.p2)
def draw(self):
print(str(self))
# 复合组件
class Picture(Graphic):
def __init__(self, iterable):
self.children = []
for g in iterable:
self.add(g)
def add(self, graphic):
self.children.append(graphic)
def draw(self):
print("----------复合图形------")
for g in self.children:
g.draw()
print("----------复合图形------")
p1 = Point(2, 3)
line_1 = Line(Point(0, 0), Point(6, 6))
line_2 = Line(Point(2, 2), Point(8, 8))
pic_1 = Picture([p1, line_1, line_2])
pic_2 = Picture([p1, line_1, line_2])
pc_1 = Picture([pic_1, pic_2])
pc_1.draw()
----------复合图形------
----------复合图形------
点(2 , 3)
line[点(0 , 0),点(6 , 6)]
line[点(2 , 2),点(8 , 8)]
----------复合图形------
----------复合图形------
点(2 , 3)
line[点(0 , 0),点(6 , 6)]
line[点(2 , 2),点(8 , 8)]
----------复合图形------
----------复合图形------
#子类CPU
class CPU:
def run(self):
print("CPU is run")
def stop(self):
print("CPU is stop")
# 子类disk
class Disk:
def run(self):
print("Disk is run")
def stop(self):
print("Disk is stop")
# 子类memory
class Memory:
def run(self):
print("Memory is run")
def stop(self):
print("Memory is stop")
# 外观模式的外观就是computer类
class Computer:
def __init__(self):
self.cpu = CPU()
self.disk = Disk()
self.memory = Memory()
def run(self):
print("computer is run")
self.cpu.run()
self.disk.run()
self.memory.run()
print("computer is run\n")
def stop(self):
print("computer is stop")
self.cpu.stop()
self.disk.stop()
self.memory.stop()
print("computer is stop\n")
computer1 = Computer()
computer1.run()
computer1.stop()
computer is run
CPU is run
Disk is run
Memory is run
computer is run
computer is stop
CPU is stop
Disk is stop
Memory is stop
computer is stop
# 导入相关数据库
from abc import abstractmethod, ABCMeta
# 目标:为了让代理的和真实的类对外具有相同的接口
# 抽象对象 subject定义接口
class Subject(metaclass=ABCMeta):
@abstractmethod
def get_content(self):
pass
@abstractmethod
def set_content(self, content):
pass
# 真实对象,继承自Subject
class RealSubject(Subject):
def __init__(self, filename):
self.filename = filename
f = open(self.filename, 'r', encoding='utf-8')
self.content = f.read()
f.close()
def get_content(self):
print("real_subject")
return self.content
def set_content(self, content):
f = open(self.filename, 'a', encoding='utf-8')
f.write(content)
f.close()
# 虚代理,为了解决在用户不执行get_content的时候,就不需要读取文件
# 1. 虚拟代理继承原来真实代理的方法
# 2. 在构造vitualsubject的时候不占用空间来存(self.content)
# 3. 只有用户在调用get_content的时候才读取self.content的信息
class VitualSubject(Subject):
def __init__(self, filename):
self.filename = filename
# self.subj = None 就可以保证默认不调用
self.subj = None
def get_content(self):
if not self.subj:
self.subj = RealSubject(self.filename)
return self.subj.get_content()
def set_content(self, content):
if not self.subj:
self.subj = RealSubject(self.filename)
return self.subj.set_content(content)
# 保护代理
# 如果我们只想要客户有一个读的权限get_content,不希望有写的权限set_content,
# 那么我们就需要拥戴保护代理模式
class ProtectedProxy(Subject):
def __init__(self, filename):
self.subj = RealSubject(filename)
# 如果想让客户用get_content,那么就直接调用原始的类的方法
def get_content(self):
return self.subj.get_content()
# 如果不想让客户用set_content,那么就抛出权限报错
def set_content(self, content):
raise PermissionError("无写入权限")
vitual_sub = VitualSubject("test.txt")
print(f'vitual_sub.get_content()={vitual_sub.get_content()}')
vitual_sub.set_content("vitual-content-add")
print(f'vitual_sub.get_content()={vitual_sub.get_content()}')
protected_sub = ProtectedProxy("test.txt")
print(f'protected_sub.get_content()={protected_sub.get_content()}')
print(f'protected_sub.set_content()={protected_sub.set_content("asdfaf")}')
real_subject
vitual_sub.get_content()=i love you pythonvitual-content-add
real_subject
vitual_sub.get_content()=i love you pythonvitual-content-add
real_subject
protected_sub.get_content()=i love you pythonvitual-content-addvitual-content-add
Traceback (most recent call last):
File "D:/zc/proxy_patten_test.py", line 146, in <module>
print(f'protected_sub.set_content()={protected_sub.set_content("asdfaf")}')
File "D:/zc/proxy_patten_test.py", line 136, in set_content
raise PermissionError("无写入权限")
PermissionError: 无写入权限
# 注:当我们调用protected_sub.set_content()的时候,我们就会报错,抛出无写入权限异常
责任链模式属于行为型模式
# 责任链模式通过类的相互传递进行责任链式发展
# 1.导入相关数据库
from abc import abstractmethod, ABCMeta
# 2. 定义通用接口
class Handle(metaclass=ABCMeta):
@abstractmethod
def handle(self, day):
pass
# 3.定义第 一 级别类
class General_Handle(Handle):
def handle(self, day):
if day <= 10:
print("General_Handle is ok for %d" % day)
else:
print(" you are ok for leave")
# 4.定义第 二 级别类
class Manager_Handle(Handle):
def __init__(self):
self.next = General_Handle()
def handle(self, day):
if day <= 5:
print("Manager_Handle is ok for %d" % day)
else:
self.next.handle(day)
# 5.定义第 三 级别类
class Department_Handle(Handle):
def __init__(self):
self.next = Manager_Handle()
def handle(self, day):
if day <= 1:
print("Department_Handle is ok for %d" % day)
else:
self.next.handle(day)
day_1 = 1
day_5 = 5
day_10 = 10
day_15 = 15
new_handle = Department_Handle()
new_handle.handle(day_1)
new_handle.handle(day_5)
new_handle.handle(day_10)
new_handle.handle(day_15)
Department_Handle is ok for 1
Manager_Handle is ok for 5
General_Handle is ok for 10
you are ok for leave
# -*- coding: utf-8 -*-
# @Project: zc
# @Author: zc
# @File name: observe-pattern
# @Create time: 2022/1/22 21:01
# 1.导入相关数据库
from abc import abstractmethod, ABCMeta, ABC
# 2.定义抽象的订阅者接口
class obeserve(metaclass=ABCMeta):
@abstractmethod
def update(self, notice): # notice参数应该是Notice类的对象
pass
# 3.定义抽象的发布者接口
class Notice:
def __init__(self):
self.observe = []
def attach(self, obs):
self.observe.append(obs)
def detach(self, obs):
self.observe.remove(obs)
def notify(self):
for obs in self.observe:
obs.update(self)
# 4.定义子类,具体的发布者
class Conpany_Notice(Notice):
def __init__(self, conpany_info=None):
super().__init__()
self.__conpany_info = conpany_info
# 负责返回私有属性
@property
def conpany_info(self):
return self.__conpany_info
# 重点!!!!
# 负责写私有属性值,
# 一旦在更改属性,就自动更新订阅者的信息
@conpany_info.setter
def conpany_info(self, info):
self.__conpany_info = info
self.notify()
class Staff_Observe(obeserve, ABC):
def __init__(self):
self.conpany_info = None
def update(self, notice):
self.conpany_info = notice.conpany_info
con_info_1 = "[第一条公告]"
con_info_2 = "[第二条公告]"
con_info_3 = "[第三条公告]"
My_Notice = Conpany_Notice()
staff_1 = Staff_Observe()
staff_2 = Staff_Observe()
My_Notice.attach(staff_1)
My_Notice.attach(staff_2)
print("*" * 30)
print("初始化时的公告")
print(f'staff_1.conpany_info={staff_1.conpany_info}')
print(f'staff_2.conpany_info={staff_2.conpany_info}')
print("*" * 30)
print("\n")
My_Notice.conpany_info = con_info_1
print("*" * 30)
print("第一次更改公告")
print(f'staff_1.conpany_info={staff_1.conpany_info}')
print(f'staff_2.conpany_info={staff_2.conpany_info}')
print("\n")
print("*" * 30)
print("第二次更改公告")
My_Notice.conpany_info = con_info_2
print(f'staff_1.conpany_info={staff_1.conpany_info}')
print(f'staff_2.conpany_info={staff_2.conpany_info}')
print("*" * 30)
print("第三次更改公告,取消staff_2关注")
My_Notice.detach(staff_1)
My_Notice.conpany_info = con_info_3
print(f'staff_1.conpany_info={staff_1.conpany_info}')
print(f'staff_2.conpany_info={staff_2.conpany_info}')
print("*" * 30)
******************************
初始化时的公告
staff_1.conpany_info=None
staff_2.conpany_info=None
******************************
******************************
第一次更改公告
staff_1.conpany_info=[第一条公告]
staff_2.conpany_info=[第一条公告]
******************************
第二次更改公告
staff_1.conpany_info=[第二条公告]
staff_2.conpany_info=[第二条公告]
******************************
第三次更改公告,取消staff_2关注
staff_1.conpany_info=[第二条公告]
staff_2.conpany_info=[第三条公告]
******************************
# -*- coding: utf-8 -*-
# @Project: zc
# @Author: zc
# @File name: strategy_patten
# @Create time: 2022/1/22 22:19
from abc import abstractmethod, ABCMeta
class Stratery(metaclass=ABCMeta):
@abstractmethod
def execute(self, data):
pass
class FastStrategy(Stratery):
def execute(self, data):
print("fast_strategy is for %s " % data)
class LowStrategy(Stratery):
def execute(self, data):
print("low_strategy is for %s " % data)
class Contex:
def __init__(self, strategy, data):
self.strategy = strategy
self.data = data
def set_strategy(self, my_strategy):
self.strategy = my_strategy
def do_strategy(self):
self.strategy.execute(self.data)
my_fast_strategy = FastStrategy()
my_low_strategy = LowStrategy()
my_data = "[....mydata...]"
my_contex = Contex(my_fast_strategy, my_data)
my_contex.do_strategy()
my_contex.set_strategy(my_low_strategy)
my_contex.do_strategy()
fast_strategy is for [....mydata...]
low_strategy is for [....mydata...]
# -*- coding: utf-8 -*-
# @Project: zc
# @Author: zc
# @File name: template-pattern
# @Create time: 2022/1/23 12:22
# 1.导入相关数据库
from abc import abstractmethod, ABCMeta
from time import sleep
# 2. 定义抽象类接口
class Window(metaclass=ABCMeta):
@abstractmethod
def start(self):
pass
@abstractmethod
def stop(self):
pass
@abstractmethod
def repaint(self):
pass
# 具体方法就是模板方法框架
def run(self):
self.start()
while True:
try:
self.repaint()
sleep(1)
except KeyboardInterrupt:
break
self.stop()
# 3. 定义子类,具体化父类的原子操作
class MyWindow(Window):
def __init__(self, msg=None):
self.msg = msg
# 定义原子操作
def start(self):
print("mywindow is start")
# 定义原子操作
def stop(self):
print("mywindow is stop")
# 定义原子操作
def repaint(self):
print("mywindow is %s" % self.msg)
MyWindow("new_message").run()
mywindow is start
mywindow is new_message
mywindow is new_message
mywindow is new_message
mywindow is new_message
mywindow is new_message
mywindow is new_message
mywindow is stop
from abc import ABCMeta, abstractmethod
# 定义通用接口state
class State(metaclass=ABCMeta):
@abstractmethod
def handle(self):
pass
# 定义具体类A继承自接口
class ConcreteStateA(State):
def handle(self):
print(f"ConcreteStateA")
# 定义具体类B继承自接口
class ConcreteStateB(State):
def handle(self):
print(f"ConcreteStateB")
# 定义上下文类来关联和管理具体类
class Context(State):
def __init__(self):
self.state = None
def get_state(self):
return self.state
def set_state(self, state):
self.state = state
def handle(self):
if self.state is None:
print("None")
else:
self.state.handle()
context = Context()
stateA = ConcreteStateA()
stateB = ConcreteStateB()
context.handle()
context.set_state(stateA)
context.handle()
context.set_state(stateB)
context.handle()
输出:
None
ConcreteStateA
ConcreteStateB
from abc import ABCMeta, abstractmethod
class State(metaclass=ABCMeta):
@abstractmethod
def doThis(self):
pass
class StartState(State):
def doThis(self):
print("TV Switching ON ...")
class StopState(State):
def doThis(self):
print("TV Switching OFF...")
class TVContext(State):
def __init__(self):
self.state = None
def get_state(self):
return self.state
def set_state(self, state):
self.state = state
def doThis(self):
return self.state.doThis()
context = TVContext()
print(context.get_state())
start = StartState()
stop = StopState()
context.set_state(start)
context.doThis()
context.set_state(stop)
context.doThis()
输出:
None
TV Switching ON ...
TV Switching OFF...
class ComputerState(object):
name = "state"
allowed = []
def swicth(self, state):
if state.name in self.allowed:
print('Current:', self, '=> switched to new state', state.name)
self.__class__ = state
else:
print('Current:', self, ' => switching to', state.name, 'not possible.')
def __str__(self):
return self.name
class Off(ComputerState):
name = "off"
allowed = ['on']
class On(ComputerState):
name = "on"
allowed = ['off', 'suspend', 'hibernate']
class Suspend(ComputerState):
name = "suspend"
allowed = ['on']
class Hibernate(ComputerState):
name = "hibernate"
allowed = ['on']
class Computer(object):
def __init__(self, model='HP'):
self.model = model
self.state = Off()
def change(self, state):
self.state.swicth(state)
if __name__ == "__main__":
comp = Computer()
comp.change(On)
comp.change(Off)
comp.change(On)
comp.change(Suspend)
comp.change(Hibernate)
comp.change(On)
comp.change(Off)
输出:
Current: off => switched to new state on
Current: on => switched to new state off
Current: off => switched to new state on
Current: on => switched to new state suspend
Current: suspend => switching to hibernate not possible.
Current: suspend => switched to new state on
Current: on => switched to new state off