1、 设计模式
2、接口
interface.py
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# Date: 2018/12/1
# class Payment:
# def pay(self, money):
# raise NotImplementedError
from abc import ABCMeta, abstractmethod
# 接口
# class Payment(metaclass=ABCMeta):
# # abstract class
# @abstractmethod
# def pay(self, money):
# pass
#
#
# class Alipay(Payment):
# def pay(self, money):
# print("支付宝支付%d元." % money)
#
#
# class WechatPay(Payment):
# def pay(self, money):
# print("微信支付%d元." % money)
#
#
#
# p = WechatPay()
# p.pay(100)
#
# class User:
# def show_name(self):
# pass
#
# class VIPUser(User):
# def show_name(self):
# pass
#
# def show_user(u):
# res = u.show_name()
class LandAnimal(metaclass=ABCMeta):
@abstractmethod
def walk(self):
pass
class WaterAnimal(metaclass=ABCMeta):
@abstractmethod
def swim(self):
pass
class SkyAnimal(metaclass=ABCMeta):
@abstractmethod
def fly(self):
pass
class Tiger(LandAnimal):
def walk(self):
print("老虎走路")
class Frog(LandAnimal, WaterAnimal):
pass
3、面向对象设计SOLID原则
4、设计模式分类
5、创建型模式
1)简单工厂模式
factory.py
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# Date: 2018/12/1
from abc import ABCMeta, abstractmethod
class Payment(metaclass=ABCMeta):
# abstract class
@abstractmethod
def pay(self, money):
pass
class Alipay(Payment):
def __init__(self, use_huabei=False):
self.use_huaei = use_huabei
def pay(self, money):
if self.use_huaei:
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 payment named %s" % method)
# client
pf = PaymentFactory()
p = pf.create_payment('huabei')
p.pay(100)
2)工厂方法模式
factory_method.py
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# Date: 2018/12/1
from abc import ABCMeta, abstractmethod
class Payment(metaclass=ABCMeta):
# abstract class
@abstractmethod
def pay(self, money):
pass
class Alipay(Payment):
def __init__(self, use_huabei=False):
self.use_huaei = use_huabei
def pay(self, money):
if self.use_huaei:
print("花呗支付%d元." % money)
else:
print("支付宝余额支付%d元." % money)
class WechatPay(Payment):
def pay(self, money):
print("微信支付%d元." % money)
class BankPay(Payment):
def pay(self, money):
print("银行卡支付%d元." % money)
class PaymentFactory(metaclass=ABCMeta):
@abstractmethod
def create_payment(self):
pass
class AlipayFactory(PaymentFactory):
def create_payment(self):
return Alipay()
class WechatPayFactory(PaymentFactory):
def create_payment(self):
return WechatPay()
class HuabeiFactory(PaymentFactory):
def create_payment(self):
return Alipay(use_huabei=True)
class BankPayFactory(PaymentFactory):
def create_payment(self):
return BankPay()
# client
pf = HuabeiFactory()
p = pf.create_payment()
p.pay(100)
3)抽象工厂模式
abstract_factory.py
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# Date: 2018/12/1
from abc import abstractmethod, ABCMeta
# ------抽象产品------
class PhoneShell(metaclass=ABCMeta):
@abstractmethod
def show_shell(self):
pass
class CPU(metaclass=ABCMeta):
@abstractmethod
def show_cpu(self):
pass
class OS(metaclass=ABCMeta):
@abstractmethod
def show_os(self):
pass
# ------抽象工厂------
class PhoneFactory(metaclass=ABCMeta):
@abstractmethod
def make_shell(self):
pass
@abstractmethod
def make_cpu(self):
pass
@abstractmethod
def make_os(self):
pass
# ------具体产品------
class SmallShell(PhoneShell):
def show_shell(self):
print("普通手机小手机壳")
class BigShell(PhoneShell):
def show_shell(self):
print("普通手机大手机壳")
class AppleShell(PhoneShell):
def show_shell(self):
print("苹果手机壳")
class SnapDragonCPU(CPU):
def show_cpu(self):
print("骁龙CPU")
class MediaTekCPU(CPU):
def show_cpu(self):
print("联发科CPU")
class AppleCPU(CPU):
def show_cpu(self):
print("苹果CPU")
class Android(OS):
def show_os(self):
print("Android系统")
class IOS(OS):
def show_os(self):
print("iOS系统")
# ------具体工厂------
class MiFactory(PhoneFactory):
def make_cpu(self):
return SnapDragonCPU()
def make_os(self):
return Android()
def make_shell(self):
return BigShell()
class HuaweiFactory(PhoneFactory):
def make_cpu(self):
return MediaTekCPU()
def make_os(self):
return Android()
def make_shell(self):
return SmallShell()
class IPhoneFactory(PhoneFactory):
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()
def make_phone(factory):
cpu = factory.make_cpu()
os = factory.make_os()
shell = factory.make_shell()
return Phone(cpu, os, shell)
p1 = make_phone(IPhoneFactory())
p1.show_info()
4)建造者模式
builder.py
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# Date: 2018/12/1
from abc import ABCMeta, abstractmethod
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)
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
class SexyGirlBuilder(PlayerBuilder):
def __init__(self):
self.player = Player()
def build_face(self):
self.player.face = "漂亮脸蛋"
def build_body(self):
self.player.body = "苗条"
def build_arm(self):
self.player.arm = "漂亮胳膊"
def build_leg(self):
self.player.leg = "大长腿"
class Monster(PlayerBuilder):
def __init__(self):
self.player = Player()
def build_face(self):
self.player.face = "怪兽脸"
def build_body(self):
self.player.body = "怪兽身材"
def build_arm(self):
self.player.arm = "长毛的胳膊"
def build_leg(self):
self.player.leg = "长毛的腿"
class PlayerDirector: # 控制组装顺序
def build_player(self, builder):
builder.build_body()
builder.build_face()
builder.build_arm()
builder.build_leg()
return builder.player
# client
builder = Monster()
director = PlayerDirector()
p = director.build_player(builder)
print(p)
5)单例模式
singleton.py
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# Date: 2018/12/1
from abc import abstractmethod, ABCMeta
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, a):
self.a = a
a = MyClass(10)
b = MyClass(20)
print(a.a)
print(b.a)
print(id(a), id(b))
6)创建型模式小结
6、结构型模式
1)适配器模式
adapter.py
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# Date: 2018/12/1
from abc import ABCMeta, abstractmethod
class Payment(metaclass=ABCMeta):
# abstract class
@abstractmethod
def pay(self, money):
pass
class Alipay(Payment):
def pay(self, money):
print("支付宝支付%d元." % money)
class WechatPay(Payment):
def pay(self, money):
print("微信支付%d元." % money)
class BankPay:
def cost(self, money):
print("银联支付%d元." % money)
class ApplePay:
def cost(self, money):
print("苹果支付%d元." % money)
# # 类适配器
# class NewBankPay(Payment, BankPay):
# def pay(self, money):
# self.cost(money)
# 对象适配器
class PaymentAdapter(Payment):
def __init__(self, payment):
self.payment = payment
def pay(self, money):
self.payment.cost(money)
p = PaymentAdapter(BankPay())
p.pay(100)
# 组合
# class A:
# pass
#
# class B:
# def __init__(self):
# self.a = A()
2)桥模式
bridge.py
# coding: utf-8
# author: ztypl
# date: 2018/12/20
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, shape):
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 Blue(Color):
def paint(self, shape):
print("蓝色的%s" % shape.name)
shape = Line(Blue())
shape.draw()
shape2 = Circle(Green())
shape2.draw()
3)组合模式
composite.py
# coding: utf-8
# author: ztypl
# date: 2018/12/21
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 "线段[%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)
l1 = Line(Point(3,4), Point(6,7))
l2 = Line(Point(1,5), Point(2,8))
pic1 = Picture([p1, l1, l2])
p2 = Point(4,4)
l3 = Line(Point(1,1), Point(0,0))
pic2 = Picture([p2, l3])
pic = Picture([pic1, pic2])
pic.draw()
4)外观模式
facade.py
# coding: utf-8
# author: ztypl
# date: 2018/12/26
class CPU:
def run(self):
print("CPU开始运行")
def stop(self):
print("CPU停止运行")
class Disk:
def run(self):
print("硬盘开始工作")
def stop(self):
print("硬盘停止工作")
class Memory:
def run(self):
print("内存通电")
def stop(self):
print("内存断电")
class Computer: # Facade
def __init__(self):
self.cpu = CPU()
self.disk = Disk()
self.memory = Memory()
def run(self):
self.cpu.run()
self.disk.run()
self.memory.run()
def stop(self):
self.cpu.stop()
self.disk.stop()
self.memory.stop()
# Client
computer = Computer()
computer.run()
computer.stop()
5)代理模式
proxy.py
# coding: utf-8
# author: ztypl
# date: 2018/12/26
from abc import ABCMeta, abstractmethod
class Subject(metaclass=ABCMeta):
@abstractmethod
def get_content(self):
pass
@abstractmethod
def set_content(self, content):
pass
class RealSubject(Subject):
def __init__(self, filename):
self.filename = filename
f = open(filename, 'r', encoding='utf-8')
print("读取文件内容")
self.content = f.read()
f.close()
def get_content(self):
return self.content
def set_content(self, content):
f = open(self.filename, 'w', encoding='utf-8')
f.write(content)
f.close()
class VirtualProxy(Subject):
def __init__(self, filename):
self.filename = filename
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 subj:
self.subj = RealSubject(self.filename)
return self.subj.set_content(content)
class ProtectedProxy(Subject):
def __init__(self, filename):
self.subj = RealSubject(filename)
def get_content(self):
return self.subj.get_content()
def set_content(self, content):
raise PermissionError("无写入权限")
#subj = RealSubject("test.txt")
#subj.get_content()
subj = ProtectedProxy("test.txt")
print(subj.get_content())
subj.set_content("abc")
7、行为型模式
1)责任链模式
chain_of_responsibility.py
# coding: utf-8
# author: ztypl
# date: 2018/12/26
from abc import ABCMeta, abstractmethod
class Handler(metaclass=ABCMeta):
@abstractmethod
def handle_leave(self, day):
pass
class GeneralManager(Handler):
def handle_leave(self, day):
if day <= 10:
print("总经理准假%d天" % day)
else:
print("你还是辞职吧")
class DepartmentManager(Handler):
def __init__(self):
self.next = GeneralManager()
def handle_leave(self, day):
if day <= 5:
print("部门经理准假%s天" % day)
else:
print("部门经理职权不足")
self.next.handle_leave(day)
class ProjectDirector(Handler):
def __init__(self):
self.next = DepartmentManager()
def handle_leave(self, day):
if day <= 3:
print("项目主管准假%d天" % day)
else:
print("项目主管职权不足")
self.next.handle_leave(day)
# Client
day = 12
h = ProjectDirector()
h.handle_leave(day)
2)观察者模式
observer.py
# coding: utf-8
# author: ztypl
# date: 2018/12/27
from abc import ABCMeta, abstractmethod
class Observer(metaclass=ABCMeta): # 抽象订阅者
@abstractmethod
def update(self, notice): # notice 是一个Notice类的对象
pass
class Notice: # 抽象发布者
def __init__(self):
self.observers = []
def attach(self, obs):
self.observers.append(obs)
def detach(self, obs):
self.observers.remove(obs)
def notify(self): # 推送
for obs in self.observers:
obs.update(self)
class StaffNotice(Notice): # 具体发布者
def __init__(self, company_info=None):
super().__init__()
self.__company_info = company_info
@property
def company_info(self):
return self.__company_info
@company_info.setter
def company_info(self, info):
self.__company_info = info
self.notify() # 推送
class Staff(Observer):
def __init__(self):
self.company_info = None
def update(self, notice):
self.company_info = notice.company_info
# Client
notice = StaffNotice("初始公司信息")
s1 = Staff()
s2 = Staff()
notice.attach(s1)
notice.attach(s2)
notice.company_info = "公司今年业绩非常好,给大家发奖金!!!"
print(s1.company_info)
print(s2.company_info)
notice.detach(s2)
notice.company_info = "公司明天放假!!!"
print(s1.company_info)
print(s2.company_info)
3)策略模式
strategy.py
# coding: utf-8
# author: ztypl
# date: 2018/12/27
from abc import ABCMeta,abstractmethod
class Strategy(metaclass=ABCMeta):
@abstractmethod
def execute(self, data):
pass
class FastStrategy(Strategy):
def execute(self, data):
print("用较快的策略处理%s" % data)
class SlowStrategy(Strategy):
def execute(self, data):
print("用较慢的策略处理%s" % data)
class Context:
def __init__(self, strategy, data):
self.data = data
self.strategy = strategy
def set_strategy(self, strategy):
self.strategy = strategy
def do_strategy(self):
self.strategy.execute(self.data)
# Client
data = "[...]"
s1 = FastStrategy()
s2 = SlowStrategy()
context = Context(s1, data)
context.do_strategy()
context.set_strategy(s2)
context.do_strategy()
4)模板方法模式
template_method.py
# coding: utf-8
# author: ztypl
# date: 2018/12/27
from abc import ABCMeta, abstractmethod
from time import sleep
class Window(metaclass=ABCMeta):
@abstractmethod
def start(self):
pass
@abstractmethod
def repaint(self):
pass
@abstractmethod
def stop(self): # 原子操作/钩子操作
pass
def run(self): # 模板方法
self.start()
while True:
try:
self.repaint()
sleep(1)
except KeyboardInterrupt:
break
self.stop()
class MyWindow(Window):
def __init__(self, msg):
self.msg = msg
def start(self):
print("窗口开始运行")
def stop(self):
print("窗口结束运行")
def repaint(self):
print(self.msg)
MyWindow("Hello...").run()
8、视频链接
【Python之常用设计模式-哔哩哔哩】 https://b23.tv/P8D78qx