窗体顶端
设计模式
什么是设计模式
o Christopher Alexander:“每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的解决方案的核心。这样你就能一次又一次地使用该方案而不必做重复劳动。”
o 每一个设计模式系统地命名、解释和评价了面向对象系统中一个重要的和重复出现的设计。
o GoF(Gang of Four)
o 设计模式四个基本要素:模式名称、问题、解决方案、效果
讲在设计模式之前
o 对象/类
n 封装
n 继承
n 多态
o 接口:一种特殊的类,声明了若干方法,要求继承该接口的类必须实现这些方法。
n 作用:限制继承接口的类的方法的名称及调用方式;隐藏了类的内部实现。
n 接口就是一种抽象的基类(父类),限制继承它的类必须实现接口中定义的某些方法
Python中接口的两种写法
设计模式六大原则
o 开闭原则:一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。即软件实体应尽量在不修改原有代码的情况下进行扩展。
o 里氏(Liskov)替换原则:所有引用基类(父类)的地方必须能透明地使用其子类的对象。
o 依赖倒置原则:高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。换言之,要针对接口编程,而不是针对实现编程。
o 接口隔离原则:使用多个专门的接口,而不使用单一的总接口,即客户端不应该依赖那些它不需要的接口。
o 迪米特法则:一个软件实体应当尽可能少地与其他实体发生相互作用。
o 单一职责原则:不要存在多于一个导致类变更的原因。通俗的说,即一个类只负责一项职责。
设计模式分类
o 创建型模式:
n 工厂方法模式
n 抽象工厂模式
n 创建者模式
n 原型模式
n 单例模式
o 结构型模式
n 适配器模式
n 桥模式
n 组合模式
n 装饰模式
n 外观模式
n 享元模式
n 代理模式
o 行为型模式
n 解释器模式
n 责任链模式
n 命令模式
n 迭代器模式
n 中介者模式
n 备忘录模式
n 观察者模式
n 状态模式
n 策略模式
n 访问者模式
n 模板方法模式
简单工厂模式
o 内容:不直接向客户端暴露对象创建的实现细节,而是通过一个工厂类来负责创建产品类的实例。
o 角色:
n 工厂角色(Factory)
n 抽象产品角色(Product)
n 具体产品角色(Concrete Product)
o 优点:
n 隐藏了对象创建的实现细节
n 客户端不需要修改代码
o 缺点:
n 违反了单一职责原则,将创建逻辑几种到一个工厂类里
n 当添加新产品时,需要修改工厂类代码,违反了开闭原则
工厂方法模式
o 内容:定义一个用于创建对象的接口(工厂接口),让子类决定实例化哪一个产品类。
o 角色:
n 抽象工厂角色(Creator)
n 具体工厂角色(Concrete Creator)
n 抽象产品角色(Product)
n 具体产品角色(Concrete Product)
o 工厂方法模式相比简单工厂模式将每个具体产品都对应了一个具体工厂。
工厂方法模式
工厂方法模式
o 适用场景:
n 需要生产多种、大量复杂对象的时候
n 需要降低耦合度的时候
n 当系统中的产品种类需要经常扩展的时候
o 优点:
n 每个具体产品都对应一个具体工厂类,不需要修改工厂类代码
n 工厂类可以不知道它所创建的对象的类
n 隐藏了对象创建的实现细节
o 缺点
n 每增加一个具体产品类,就必须增加一个相应的具体工厂类
抽象工厂模式
o 内容:定义一个工厂类接口,让工厂子类来创建一系列相关或相互依赖的对象。
o 例:生产一部手机,需要手机壳、CPU、操作系统三类对象进行组装,其中每类对象都有不同的种类。对每个具体工厂,分别生产一部手机所需要的三个对象。
o 角色:
n 抽象工厂角色(Creator)
n 具体工厂角色(Concrete Creator)
n 抽象产品角色(Product)
n 具体产品角色(Concrete Product)
n 客户端(Client)
o 相比工厂方法模式,抽象工厂模式中的每个具体工厂都生产一套产品。
抽象工厂模式
抽象工厂模式
o 适用场景:
n 系统要独立于产品的创建与组合时
n 强调一系列相关的产品对象的设计以便进行联合使用时
n 提供一个产品类库,想隐藏产品的具体实现时
o 优点:
n 将客户端与类的具体实现相分离
n 每个工厂创建了一个完整的产品系列,使得易于交换产品系列
n 有利于产品的一致性(即产品之间的约束关系)
o 缺点:
n 难以支持新种类的(抽象)产品
建造者模式
o 内容:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
o 角色:
n 抽象建造者(Builder)
n 具体建造者(Concrete Builder)
n 指挥者(Director)
n 产品(Product)
o 建造者模式与抽象工厂模式相似,也用来创建复杂对象。主要区别是建造者模式着重一步步构造一个复杂对象,而抽象工厂模式着重于多个系列的产品对象。
建造者模式
建造者模式
o 适用场景:
n 当创建复杂对象的算法(Director)应该独立于该对象的组成部分以及它们的装配方式(Builder)时
n 当构造过程允许被构造的对象有不同的表示时(不同Builder)。
o 优点:
n 隐藏了一个产品的内部结构和装配过程
n 将构造代码与表示代码分开
n 可以对构造过程进行更精细的控制
单例模式
o 内容:保证一个类只有一个实例,并提供一个访问它的全局访问点。
o 角色:
n 单例(Singleton)
o 适用场景
n 当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时
o 优点:
n 对唯一实例的受控访问
n 单例相当于全局变量,但防止了命名空间被污染
o 与单例模式功能相似的概念:全局变量、静态变量(方法)
创建型模式小结
o 依赖于继承的创建型模式:工厂方法模式
o 依赖于组合的创建性模式:抽象工厂模式、创建者模式
适配器模式
o 内容:将一个类的接口转换成客户希望的另一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
o 角色:
n 目标接口(Target)
n 待适配的类(Adaptee)
n 适配器(Adapter)
o 两种实现方式:
n 类适配器:使用多继承
n 对象适配器:使用组合
适配器模式
适配器模式
o 适用场景:
n 想使用一个已经存在的类,而它的接口不符合你的要求
n (对象适配器)想使用一些已经存在的子类,但不可能对每一个都进行子类化以匹配它们的接口。对象适配器可以适配它的父类接口。
组合模式
o 内容:将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
o 角色:
n 抽象组件(Component)
n 叶子组件(Leaf)
n 复合组件(Composite)
n 客户端(Client)
组合模式
组合模式
o 适用场景:
n 表示对象的“部分-整体”层次结构(特别是结构是递归的)
n 希望用户忽略组合对象与单个对象的不同,用户统一地使用组合结构中的所有对象
o 优点:
n 定义了包含基本对象和组合对象的类层次结构
n 简化客户端代码,即客户端可以一致地使用组合对象和单个对象
n 更容易增加新类型的组件
o 缺点:
n 很难限制组合中的组件
代理模式
o 内容:为其他对象提供一种代理以控制对这个对象的访问。
o 角色:
n 抽象实体(Subject)
n 实体(RealSubject)
n 代理(Proxy)
o 适用场景:
n 远程代理:为远程的对象提供代理
n 虚代理:根据需要创建很大的对象
n 保护代理:控制对原始对象的访问,用于对象有不同访问权限时
o 优点:
n 远程代理:可以隐藏对象位于远程地址空间的事实
n 虚代理:可以进行优化,例如根据要求创建对象
n 保护代理:允许在访问一个对象时有一些附加的内务处理
代理模式
责任链模式
o 内容:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
o 角色:
n 抽象处理者(Handler)
n 具体处理者(ConcreteHandler)
n 客户端(Client)
o 例:
n 请假部门批准:leaderà部门经理à总经理
n Javascript事件浮升机制
责任链模式
责任链模式
o 适用场景:
n 有多个对象可以处理一个请求,哪个对象处理由运行时决定
n 在不明确接收者的情况下,向多个对象中的一个提交一个请求
o 优点:
n 降低耦合度:一个对象无需知道是其他哪一个对象处理其请求
o 缺点:
n 请求不保证被接收:链的末端没有处理或链配置错误
迭代器模式
o 内容:提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示
o 实现方法:__iter__、__next__
观察者模式
o 内容:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。观察者模式又称“发布-订阅”模式
o 角色:
n 抽象主题(Subject)
n 具体主题(ConcreteSubject)——发布者
n 抽象观察者(Observer)
n 具体观察者(ConcreteObserver)——订阅者
观察者模式
观察者模式
o 适用场景:
n 当一个抽象模型有两方面,其中一个方面依赖于另一个方面。将这两者封装在独立对象中以使它们可以各自独立地改变和复用。
n 当对一个对象的改变需要同时改变其它对象,而不知道具体有多少对象有待改变。
n 当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换言之,你不希望这些对象是紧密耦合的。
o 优点:
n 目标和观察者之间的抽象耦合最小
n 支持广播通信
o 缺点:
n 多个观察者之间互不知道对方存在,因此一个观察者对主题的修改可能造成错误的更新。
策略模式
o 内容:定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。
o 角色:
n 抽象策略(Strategy)
n 具体策略(ConcreteStrategy)
n 上下文(Context)
o 适用场景:
n 许多相关的类仅仅是行为有异
n 需要使用一个算法的不同变体
n 算法使用了客户端无需知道的数据
n 一个类中的多种行为以多个条件语句的形式存在,可以将这些行为封装如不同的策略类中。
策略模式
策略模式
o 优点:
n 定义了一系列可重用的算法和行为
n 消除了一些条件语句
n 可以提供相同行为的不同实现
o 缺点:
n 客户必须了解不同的策略
n 策略与上下文之间的通信开销
n 增加了对象的数目
模板方法模式
o 内容:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
o 角色:
n 抽象类(AbstractClass):定义抽象的原子操作(钩子操作);实现一个模板方法作为算法的骨架。
n 具体类(ConcreteClass):实现原子操作
o 适用场景:
n 一次性实现一个算法的不变的部分
n 各个子类中的公共行为应该被提取出来并集中到一个公共父类中以避免代码重复
n 控制子类扩展
模板方法模式
代码如下:0_interface.py
# coding : utf-8
# create by ztypl on 2017/5/24
from abc import abstractmethod, ABCMeta
class Payment(metaclass=ABCMeta):
@abstractmethod
def pay(self, money):
raise NotImplementedError
class Alipay(Payment):
def pay(self, money):
print("支付宝支付%s元"%money)
class ApplePay(Payment):
def pay(self, money):
print("苹果支付%s元"%money)
class WechatPay(Payment):
def pay(self, money):
print("微信支付%s元"%money)
1_factory.py
# coding : utf-8
# create by ztypl on 2017/5/24
from abc import abstractmethod, ABCMeta
class Payment(metaclass=ABCMeta):
@abstractmethod
def pay(self, money):
raise NotImplementedError
class Alipay(Payment):
def pay(self, money):
print("支付宝支付%s元" % money)
class ApplePay(Payment):
def pay(self, money):
print("苹果支付%s元" % money)
class PaymentFactory:
def create_payment(self, method):
if method == "alipay":
return Alipay()
elif method == "applepay":
return ApplePay()
else:
raise NameError(method)
2_factory_method.py
# coding : utf-8
# create by ztypl on 2017/5/25
from abc import abstractmethod, ABCMeta
class Payment(metaclass=ABCMeta):
@abstractmethod
def pay(self, money):
raise NotImplementedError
class Alipay(Payment):
def pay(self, money):
print("支付宝支付%s元" % money)
class ApplePay(Payment):
def pay(self, money):
print("苹果支付%s元"%money)
class PaymentFactory:
def create_payment(self):
raise NotImplementedError
class AlipayFactory(PaymentFactory):
def create_payment(self):
return Alipay()
class ApplePayFactory(PaymentFactory):
def create_payment(self):
return ApplePay()
# 用户输入
# 支付宝,120
af = AlipayFactory()
ali = af.create_payment()
ali.pay(120)
3_abstract_factory.py
# coding : utf-8
# create by ztypl on 2017/5/25
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(MiFactory())
p1.show_info()
4_builder.py
# coding : utf-8
# create by ztypl on 2017/5/25
from abc import abstractmethod, ABCMeta
#------产品------
class Player:
def __init__(self, face=None, body=None, arm=None, leg=None):
self.face = face
self.arm = arm
self.leg = leg
self.body = body
def __str__(self):
return "%s, %s, %s, %s" % (self.face, self.arm, self.body, self.leg)
#------建造者------
class PlayerBuilder(metaclass=ABCMeta):
@abstractmethod
def build_face(self):
pass
@abstractmethod
def build_arm(self):
pass
@abstractmethod
def build_leg(self):
pass
@abstractmethod
def build_body(self):
pass
@abstractmethod
def get_player(self):
pass
class BeautifulWomanBuilder(PlayerBuilder):
def __init__(self):
self.player = Player()
def build_face(self):
self.player.face = "漂亮脸蛋"
def build_arm(self):
self.player.arm="细胳膊"
def build_body(self):
self.player.body="细腰"
def build_leg(self):
self.player.leg="长腿"
def get_player(self):
return self.player
class PlayerDirector:
def build_player(self, builder):
builder.build_face()
builder.build_arm()
builder.build_leg()
builder.build_body()
return builder.get_player()
pd = PlayerDirector()
pb = BeautifulWomanBuilder()
p = pd.build_player(pb)
print(p)
5_singleton.py
# coding : utf-8
# create by ztypl on 2017/5/25
from abc import abstractmethod, ABCMeta
class Singleton(object):
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, name=None):
if name is not None:
self.name = name
a = MyClass("a")
print(a)
print(a.name)
b = MyClass("b")
print(b)
print(b.name)
print(a)
print(a.name)
6_adapter.py
# coding : utf-8
# create by ztypl on 2017/5/25
from abc import abstractmethod, ABCMeta
class Payment(metaclass=ABCMeta):
@abstractmethod
def pay(self, money):
raise NotImplementedError
class Alipay(Payment):
def pay(self, money):
print("支付宝支付%s元"%money)
class ApplePay(Payment):
def pay(self, money):
print("苹果支付%s元"%money)
#------待适配类------
class WechatPay:
def huaqian(self, money):
print("微信支付%s元"%money)
#------类适配器------
class RealWeChatPay(Payment, WechatPay):
def pay(self, money):
return self.huaqian(money)
#------对象适配器------
class PayAdapter(Payment):
def __init__(self, payment):
self.payment = payment
def pay(self, money):
return self.payment.huaqian(money)
RealWeChatPay().pay(100)
#PayAdapter(WechatPay()).pay(1000)
7_composite
# coding : utf-8
# create by ztypl on 2017/5/25
from abc import abstractmethod, ABCMeta
class Graphic(metaclass=ABCMeta):
@abstractmethod
def draw(self):
pass
@abstractmethod
def add(self, graphic):
pass
def getchildren(self):
pass
class Point(Graphic):
def __init__(self, x, y):
self.x = x
self.y = y
def draw(self):
print(self)
def add(self, graphic):
raise TypeError
def getchildren(self):
raise TypeError
def __str__(self):
return "点(%s, %s)" % (self.x, self.y)
class Line(Graphic):
def __init__(self, p1, p2):
self.p1 = p1
self.p2 = p2
def draw(self):
print(self)
def add(self, graphic):
raise TypeError
def getchildren(self):
raise TypeError
def __str__(self):
return "线段[%s, %s]" % (self.p1, self.p2)
class Picture(Graphic):
def __init__(self):
self.children = []
def add(self, graphic):
self.children.append(graphic)
def getchildren(self):
return self.children
def draw(self):
print("------复合图形------")
for g in self.children:
g.draw()
print("------END------")
pic1 = Picture()
pic1.add(Point(2,3))
pic1.add(Line(Point(1,2), Point(4,5)))
pic1.add(Line(Point(0,1), Point(2,1)))
pic2 = Picture()
pic2.add(Point(-2,-1))
pic2.add(Line(Point(0,0), Point(1,1)))
pic = Picture()
pic.add(pic1)
pic.add(pic2)
pic.draw()
8_proxy.py
# coding : utf-8
# create by ztypl on 2017/5/26
from abc import ABCMeta, abstractmethod
class Subject(metaclass=ABCMeta):
@abstractmethod
def get_content(self):
pass
class RealSubject(Subject):
def __init__(self, filename):
print("读取%s文件内容"%filename)
f = open("filename")
self.content = f.read()
f.close()
def get_content(self):
return self.content
class ProxyA(Subject):
def __init__(self, filename):
self.subj = RealSubject(filename)
def get_content(self):
return self.subj.get_content()
class ProxyB(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()
class ProxyC(Subject):
def __init__(self, filename):
self.subj = RealSubject(filename)
def get_content(self):
return "???"
9_chain_of_responsibility.py
# coding : utf-8
# create by ztypl on 2017/5/27
from abc import ABCMeta, abstractmethod
class Handler(metaclass=ABCMeta):
@abstractmethod
def handle_leave(self, day):
pass
class GeneralManagerliHandler(Handler):
def handle_leave(self, day):
if day < 10:
print("总经理批准%d天假"%day)
else:
print("呵呵")
class DepartmentManagerHandler(Handler):
def __init__(self):
self.successor = GeneralManagerliHandler()
def handle_leave(self, day):
if day < 7:
print("部门经理批准%d天假"%day)
else:
print("部门经理无权准假")
self.successor.handle_leave(day)
class ProjectDirectorHandler(Handler):
def __init__(self):
self.successor = DepartmentManagerHandler()
def handle_leave(self, day):
if day < 3:
print("项目主管批准%d天假")
else:
print("项目主管无权准假")
self.successor.handle_leave(day)
day = 10
h = ProjectDirectorHandler()
h.handle_leave(day)
#--高级例子--模仿js事件处理
# class Handler(metaclass=ABCMeta):
# @abstractmethod
# def add_event(self, func):
# pass
#
# @abstractmethod
# def handle(self):
# pass
#
#
# class BodyHandler(Handler):
# def __init__(self):
# self.func = None
#
# def add_event(self, func):
# self.func = func
#
# def handle(self):
# if self.func:
# return self.func()
# else:
# print("已到最后一级,无法处理")
#
#
# class ElementHandler(Handler):
# def __init__(self, successor):
# self.func = None
# self.successor = successor
#
# def add_event(self, func):
# self.func = func
#
# def handle(self):
# if self.func:
# return self.func()
# else:
# return self.successor.handle()
#
#
# # 客户端
#
# # <body><div><a>
#
# body = {'type': 'body', 'name': 'body', 'children': [], 'father': None}
#
# div = {'type': 'div', 'name': 'div', 'children': [], 'father': body}
#
# a = {'type': 'a', 'name': 'a', 'children': [], 'father': div}
#
# body['children'].append(div)
# div['children'].append(a)
#
# body['event_handler'] = BodyHandler()
# div['event_handler'] = ElementHandler(div['father']['event_handler'])
# a['event_handler'] = ElementHandler(a['father']['event_handler'])
#
# def attach_event(element, func):
# element['event_handler'].add_event(func)
#
# #test
#
# def func_div():
# print("这是给div的函数")
#
# def func_a():
# print("这是给a的函数")
#
# def func_body():
# print("这是给body的函数")
#
# #attach_event(div, func_div)
# #attach_event(a, func_a)
# #attach_event(body, func_body)
#
#
#
#
#
# a['event_handler'].handle()
10_iterator.py
# coding : utf-8
# create by ztypl on 2017/5/27
class LinkList:
"""链表 头结点保存链表的长度"""
class Node:
def __init__(self, item=None):
self.item = item
self.next = None
class LinkListIterator:
def __init__(self, node):
self.node = node
def __next__(self):
if self.node:
cur_node = self.node
self.node = cur_node.next
return cur_node.item
else:
raise StopIteration
def __iter__(self):
return self
def __init__(self, iterable=None):
self.head = LinkList.Node(0)
self.tail = self.head
self.extend(iterable)
def append(self, obj):
s = LinkList.Node(obj)
self.tail.next = s
self.tail = s
def extend(self, iterable):
for obj in iterable:
self.append(obj)
self.head.item += len(iterable)
def __iter__(self):
return self.LinkListIterator(self.head.next)
def __len__(self):
return self.head.item
def __str__(self):
return "<<"+", ".join(map(str, self))+">>"
li = [i for i in range(100)]
print(li)
lk = LinkList(li)
print(lk)
print(len(lk))
11_observer.py
# coding : utf-8
# create by ztypl on 2017/5/27
from abc import ABCMeta, abstractmethod
class Observer(metaclass=ABCMeta):
@abstractmethod
def update(self, 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 obj in self.observers:
obj.update(self)
class ManagerNotice(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 Manager(Observer):
def __init__(self):
self.company_info = None
def update(self, noti):
self.company_info = noti.company_info
notice = ManagerNotice()
alex = Manager()
wusir = Manager()
print(alex.company_info)
print(wusir.company_info)
notice.attach(alex)
notice.attach(wusir)
notice.company_info="公司运行良好"
print(alex.company_info)
print(wusir.company_info)
notice.detach(wusir)
notice.company_info="公司要破产了"
print(alex.company_info)
print(wusir.company_info)
12_strategy.py
# coding : utf-8
# create by ztypl on 2017/5/27
from abc import ABCMeta, abstractmethod
import random
class Sort(metaclass=ABCMeta):
@abstractmethod
def sort(self, data):
pass
class QuickSort(Sort):
def quick_sort(self, data, left, right):
if left < right:
mid = self.partition(data, left, right)
self.quick_sort(data, left, mid - 1)
self.quick_sort(data, mid + 1, right)
def partition(self, data, left, right):
tmp = data[left]
while left < right:
while left < right and data[right] >= tmp:
right -= 1
data[left] = data[right]
while left < right and data[left] <= tmp:
left += 1
data[right] = data[left]
data[left] = tmp
return left
def sort(self, data):
print("快速排序")
return self.quick_sort(data, 0, len(data) - 1)
class MergeSort(Sort):
def merge(self, data, low, mid, high):
i = low
j = mid + 1
ltmp = []
while i <= mid and j <= high:
if data[i] <= data[j]:
ltmp.append(data[i])
i += 1
else:
ltmp.append(data[j])
j += 1
while i <= mid:
ltmp.append(data[i])
i += 1
while j <= high:
ltmp.append(data[j])
j += 1
data[low:high + 1] = ltmp
def merge_sort(self, data, low, high):
if low < high:
mid = (low + high) // 2
self.merge_sort(data, low, mid)
self.merge_sort(data, mid + 1, high)
self.merge(data, low, mid, high)
def sort(self, data):
print("归并排序")
return self.merge_sort(data, 0, len(data) - 1)
class Context:
def __init__(self, data, strategy=None):
self.data = data
self.strategy = strategy
def set_strategy(self, strategy):
self.strategy = strategy
def do_strategy(self):
if self.strategy:
self.strategy.sort(self.data)
else:
raise TypeError
li = list(range(100000))
random.shuffle(li)
context = Context(li, MergeSort())
context.do_strategy()
#print(context.data)
random.shuffle(context.data)
context.set_strategy(QuickSort())
context.do_strategy()
13_template_method.py
# coding : utf-8
# create by ztypl on 2017/5/27
from abc import ABCMeta, abstractmethod
class IOHandler(metaclass=ABCMeta):
@abstractmethod
def open(self, name):
pass
@abstractmethod
def deal(self, change):
pass
@abstractmethod
def close(self):
pass
def process(self, name, change):
self.open(name)
self.deal(change)
self.close()
窗体顶端
设计模式
什么是设计模式
o Christopher Alexander:“每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的解决方案的核心。这样你就能一次又一次地使用该方案而不必做重复劳动。”
o 每一个设计模式系统地命名、解释和评价了面向对象系统中一个重要的和重复出现的设计。
o GoF(Gang of Four)
o 设计模式四个基本要素:模式名称、问题、解决方案、效果
讲在设计模式之前
o 对象/类
n 封装
n 继承
n 多态
o 接口:一种特殊的类,声明了若干方法,要求继承该接口的类必须实现这些方法。
n 作用:限制继承接口的类的方法的名称及调用方式;隐藏了类的内部实现。
n 接口就是一种抽象的基类(父类),限制继承它的类必须实现接口中定义的某些方法
Python中接口的两种写法
设计模式六大原则
o 开闭原则:一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。即软件实体应尽量在不修改原有代码的情况下进行扩展。
o 里氏(Liskov)替换原则:所有引用基类(父类)的地方必须能透明地使用其子类的对象。
o 依赖倒置原则:高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。换言之,要针对接口编程,而不是针对实现编程。
o 接口隔离原则:使用多个专门的接口,而不使用单一的总接口,即客户端不应该依赖那些它不需要的接口。
o 迪米特法则:一个软件实体应当尽可能少地与其他实体发生相互作用。
o 单一职责原则:不要存在多于一个导致类变更的原因。通俗的说,即一个类只负责一项职责。
设计模式分类
o 创建型模式:
n 工厂方法模式
n 抽象工厂模式
n 创建者模式
n 原型模式
n 单例模式
o 结构型模式
n 适配器模式
n 桥模式
n 组合模式
n 装饰模式
n 外观模式
n 享元模式
n 代理模式
o 行为型模式
n 解释器模式
n 责任链模式
n 命令模式
n 迭代器模式
n 中介者模式
n 备忘录模式
n 观察者模式
n 状态模式
n 策略模式
n 访问者模式
n 模板方法模式
简单工厂模式
o 内容:不直接向客户端暴露对象创建的实现细节,而是通过一个工厂类来负责创建产品类的实例。
o 角色:
n 工厂角色(Factory)
n 抽象产品角色(Product)
n 具体产品角色(Concrete Product)
o 优点:
n 隐藏了对象创建的实现细节
n 客户端不需要修改代码
o 缺点:
n 违反了单一职责原则,将创建逻辑几种到一个工厂类里
n 当添加新产品时,需要修改工厂类代码,违反了开闭原则
工厂方法模式
o 内容:定义一个用于创建对象的接口(工厂接口),让子类决定实例化哪一个产品类。
o 角色:
n 抽象工厂角色(Creator)
n 具体工厂角色(Concrete Creator)
n 抽象产品角色(Product)
n 具体产品角色(Concrete Product)
o 工厂方法模式相比简单工厂模式将每个具体产品都对应了一个具体工厂。
工厂方法模式
工厂方法模式
o 适用场景:
n 需要生产多种、大量复杂对象的时候
n 需要降低耦合度的时候
n 当系统中的产品种类需要经常扩展的时候
o 优点:
n 每个具体产品都对应一个具体工厂类,不需要修改工厂类代码
n 工厂类可以不知道它所创建的对象的类
n 隐藏了对象创建的实现细节
o 缺点
n 每增加一个具体产品类,就必须增加一个相应的具体工厂类
抽象工厂模式
o 内容:定义一个工厂类接口,让工厂子类来创建一系列相关或相互依赖的对象。
o 例:生产一部手机,需要手机壳、CPU、操作系统三类对象进行组装,其中每类对象都有不同的种类。对每个具体工厂,分别生产一部手机所需要的三个对象。
o 角色:
n 抽象工厂角色(Creator)
n 具体工厂角色(Concrete Creator)
n 抽象产品角色(Product)
n 具体产品角色(Concrete Product)
n 客户端(Client)
o 相比工厂方法模式,抽象工厂模式中的每个具体工厂都生产一套产品。
抽象工厂模式
抽象工厂模式
o 适用场景:
n 系统要独立于产品的创建与组合时
n 强调一系列相关的产品对象的设计以便进行联合使用时
n 提供一个产品类库,想隐藏产品的具体实现时
o 优点:
n 将客户端与类的具体实现相分离
n 每个工厂创建了一个完整的产品系列,使得易于交换产品系列
n 有利于产品的一致性(即产品之间的约束关系)
o 缺点:
n 难以支持新种类的(抽象)产品
建造者模式
o 内容:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
o 角色:
n 抽象建造者(Builder)
n 具体建造者(Concrete Builder)
n 指挥者(Director)
n 产品(Product)
o 建造者模式与抽象工厂模式相似,也用来创建复杂对象。主要区别是建造者模式着重一步步构造一个复杂对象,而抽象工厂模式着重于多个系列的产品对象。
建造者模式
建造者模式
o 适用场景:
n 当创建复杂对象的算法(Director)应该独立于该对象的组成部分以及它们的装配方式(Builder)时
n 当构造过程允许被构造的对象有不同的表示时(不同Builder)。
o 优点:
n 隐藏了一个产品的内部结构和装配过程
n 将构造代码与表示代码分开
n 可以对构造过程进行更精细的控制
单例模式
o 内容:保证一个类只有一个实例,并提供一个访问它的全局访问点。
o 角色:
n 单例(Singleton)
o 适用场景
n 当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时
o 优点:
n 对唯一实例的受控访问
n 单例相当于全局变量,但防止了命名空间被污染
o 与单例模式功能相似的概念:全局变量、静态变量(方法)
创建型模式小结
o 依赖于继承的创建型模式:工厂方法模式
o 依赖于组合的创建性模式:抽象工厂模式、创建者模式
适配器模式
o 内容:将一个类的接口转换成客户希望的另一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
o 角色:
n 目标接口(Target)
n 待适配的类(Adaptee)
n 适配器(Adapter)
o 两种实现方式:
n 类适配器:使用多继承
n 对象适配器:使用组合
适配器模式
适配器模式
o 适用场景:
n 想使用一个已经存在的类,而它的接口不符合你的要求
n (对象适配器)想使用一些已经存在的子类,但不可能对每一个都进行子类化以匹配它们的接口。对象适配器可以适配它的父类接口。
组合模式
o 内容:将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
o 角色:
n 抽象组件(Component)
n 叶子组件(Leaf)
n 复合组件(Composite)
n 客户端(Client)
组合模式
组合模式
o 适用场景:
n 表示对象的“部分-整体”层次结构(特别是结构是递归的)
n 希望用户忽略组合对象与单个对象的不同,用户统一地使用组合结构中的所有对象
o 优点:
n 定义了包含基本对象和组合对象的类层次结构
n 简化客户端代码,即客户端可以一致地使用组合对象和单个对象
n 更容易增加新类型的组件
o 缺点:
n 很难限制组合中的组件
代理模式
o 内容:为其他对象提供一种代理以控制对这个对象的访问。
o 角色:
n 抽象实体(Subject)
n 实体(RealSubject)
n 代理(Proxy)
o 适用场景:
n 远程代理:为远程的对象提供代理
n 虚代理:根据需要创建很大的对象
n 保护代理:控制对原始对象的访问,用于对象有不同访问权限时
o 优点:
n 远程代理:可以隐藏对象位于远程地址空间的事实
n 虚代理:可以进行优化,例如根据要求创建对象
n 保护代理:允许在访问一个对象时有一些附加的内务处理
代理模式
责任链模式
o 内容:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
o 角色:
n 抽象处理者(Handler)
n 具体处理者(ConcreteHandler)
n 客户端(Client)
o 例:
n 请假部门批准:leaderà部门经理à总经理
n Javascript事件浮升机制
责任链模式
责任链模式
o 适用场景:
n 有多个对象可以处理一个请求,哪个对象处理由运行时决定
n 在不明确接收者的情况下,向多个对象中的一个提交一个请求
o 优点:
n 降低耦合度:一个对象无需知道是其他哪一个对象处理其请求
o 缺点:
n 请求不保证被接收:链的末端没有处理或链配置错误
迭代器模式
o 内容:提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示
o 实现方法:__iter__、__next__
观察者模式
o 内容:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。观察者模式又称“发布-订阅”模式
o 角色:
n 抽象主题(Subject)
n 具体主题(ConcreteSubject)——发布者
n 抽象观察者(Observer)
n 具体观察者(ConcreteObserver)——订阅者
观察者模式
观察者模式
o 适用场景:
n 当一个抽象模型有两方面,其中一个方面依赖于另一个方面。将这两者封装在独立对象中以使它们可以各自独立地改变和复用。
n 当对一个对象的改变需要同时改变其它对象,而不知道具体有多少对象有待改变。
n 当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换言之,你不希望这些对象是紧密耦合的。
o 优点:
n 目标和观察者之间的抽象耦合最小
n 支持广播通信
o 缺点:
n 多个观察者之间互不知道对方存在,因此一个观察者对主题的修改可能造成错误的更新。
策略模式
o 内容:定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。
o 角色:
n 抽象策略(Strategy)
n 具体策略(ConcreteStrategy)
n 上下文(Context)
o 适用场景:
n 许多相关的类仅仅是行为有异
n 需要使用一个算法的不同变体
n 算法使用了客户端无需知道的数据
n 一个类中的多种行为以多个条件语句的形式存在,可以将这些行为封装如不同的策略类中。
策略模式
策略模式
o 优点:
n 定义了一系列可重用的算法和行为
n 消除了一些条件语句
n 可以提供相同行为的不同实现
o 缺点:
n 客户必须了解不同的策略
n 策略与上下文之间的通信开销
n 增加了对象的数目
模板方法模式
o 内容:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
o 角色:
n 抽象类(AbstractClass):定义抽象的原子操作(钩子操作);实现一个模板方法作为算法的骨架。
n 具体类(ConcreteClass):实现原子操作
o 适用场景:
n 一次性实现一个算法的不变的部分
n 各个子类中的公共行为应该被提取出来并集中到一个公共父类中以避免代码重复
n 控制子类扩展
模板方法模式
代码如下:0_interface.py
# coding : utf-8
# create by ztypl on 2017/5/24
from abc import abstractmethod, ABCMeta
class Payment(metaclass=ABCMeta):
@abstractmethod
def pay(self, money):
raise NotImplementedError
class Alipay(Payment):
def pay(self, money):
print("支付宝支付%s元"%money)
class ApplePay(Payment):
def pay(self, money):
print("苹果支付%s元"%money)
class WechatPay(Payment):
def pay(self, money):
print("微信支付%s元"%money)
1_factory.py
# coding : utf-8
# create by ztypl on 2017/5/24
from abc import abstractmethod, ABCMeta
class Payment(metaclass=ABCMeta):
@abstractmethod
def pay(self, money):
raise NotImplementedError
class Alipay(Payment):
def pay(self, money):
print("支付宝支付%s元" % money)
class ApplePay(Payment):
def pay(self, money):
print("苹果支付%s元" % money)
class PaymentFactory:
def create_payment(self, method):
if method == "alipay":
return Alipay()
elif method == "applepay":
return ApplePay()
else:
raise NameError(method)
2_factory_method.py
# coding : utf-8
# create by ztypl on 2017/5/25
from abc import abstractmethod, ABCMeta
class Payment(metaclass=ABCMeta):
@abstractmethod
def pay(self, money):
raise NotImplementedError
class Alipay(Payment):
def pay(self, money):
print("支付宝支付%s元" % money)
class ApplePay(Payment):
def pay(self, money):
print("苹果支付%s元"%money)
class PaymentFactory:
def create_payment(self):
raise NotImplementedError
class AlipayFactory(PaymentFactory):
def create_payment(self):
return Alipay()
class ApplePayFactory(PaymentFactory):
def create_payment(self):
return ApplePay()
# 用户输入
# 支付宝,120
af = AlipayFactory()
ali = af.create_payment()
ali.pay(120)
3_abstract_factory.py
# coding : utf-8
# create by ztypl on 2017/5/25
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(MiFactory())
p1.show_info()
4_builder.py
# coding : utf-8
# create by ztypl on 2017/5/25
from abc import abstractmethod, ABCMeta
#------产品------
class Player:
def __init__(self, face=None, body=None, arm=None, leg=None):
self.face = face
self.arm = arm
self.leg = leg
self.body = body
def __str__(self):
return "%s, %s, %s, %s" % (self.face, self.arm, self.body, self.leg)
#------建造者------
class PlayerBuilder(metaclass=ABCMeta):
@abstractmethod
def build_face(self):
pass
@abstractmethod
def build_arm(self):
pass
@abstractmethod
def build_leg(self):
pass
@abstractmethod
def build_body(self):
pass
@abstractmethod
def get_player(self):
pass
class BeautifulWomanBuilder(PlayerBuilder):
def __init__(self):
self.player = Player()
def build_face(self):
self.player.face = "漂亮脸蛋"
def build_arm(self):
self.player.arm="细胳膊"
def build_body(self):
self.player.body="细腰"
def build_leg(self):
self.player.leg="长腿"
def get_player(self):
return self.player
class PlayerDirector:
def build_player(self, builder):
builder.build_face()
builder.build_arm()
builder.build_leg()
builder.build_body()
return builder.get_player()
pd = PlayerDirector()
pb = BeautifulWomanBuilder()
p = pd.build_player(pb)
print(p)
5_singleton.py
# coding : utf-8
# create by ztypl on 2017/5/25
from abc import abstractmethod, ABCMeta
class Singleton(object):
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, name=None):
if name is not None:
self.name = name
a = MyClass("a")
print(a)
print(a.name)
b = MyClass("b")
print(b)
print(b.name)
print(a)
print(a.name)
6_adapter.py
# coding : utf-8
# create by ztypl on 2017/5/25
from abc import abstractmethod, ABCMeta
class Payment(metaclass=ABCMeta):
@abstractmethod
def pay(self, money):
raise NotImplementedError
class Alipay(Payment):
def pay(self, money):
print("支付宝支付%s元"%money)
class ApplePay(Payment):
def pay(self, money):
print("苹果支付%s元"%money)
#------待适配类------
class WechatPay:
def huaqian(self, money):
print("微信支付%s元"%money)
#------类适配器------
class RealWeChatPay(Payment, WechatPay):
def pay(self, money):
return self.huaqian(money)
#------对象适配器------
class PayAdapter(Payment):
def __init__(self, payment):
self.payment = payment
def pay(self, money):
return self.payment.huaqian(money)
RealWeChatPay().pay(100)
#PayAdapter(WechatPay()).pay(1000)
7_composite
# coding : utf-8
# create by ztypl on 2017/5/25
from abc import abstractmethod, ABCMeta
class Graphic(metaclass=ABCMeta):
@abstractmethod
def draw(self):
pass
@abstractmethod
def add(self, graphic):
pass
def getchildren(self):
pass
class Point(Graphic):
def __init__(self, x, y):
self.x = x
self.y = y
def draw(self):
print(self)
def add(self, graphic):
raise TypeError
def getchildren(self):
raise TypeError
def __str__(self):
return "点(%s, %s)" % (self.x, self.y)
class Line(Graphic):
def __init__(self, p1, p2):
self.p1 = p1
self.p2 = p2
def draw(self):
print(self)
def add(self, graphic):
raise TypeError
def getchildren(self):
raise TypeError
def __str__(self):
return "线段[%s, %s]" % (self.p1, self.p2)
class Picture(Graphic):
def __init__(self):
self.children = []
def add(self, graphic):
self.children.append(graphic)
def getchildren(self):
return self.children
def draw(self):
print("------复合图形------")
for g in self.children:
g.draw()
print("------END------")
pic1 = Picture()
pic1.add(Point(2,3))
pic1.add(Line(Point(1,2), Point(4,5)))
pic1.add(Line(Point(0,1), Point(2,1)))
pic2 = Picture()
pic2.add(Point(-2,-1))
pic2.add(Line(Point(0,0), Point(1,1)))
pic = Picture()
pic.add(pic1)
pic.add(pic2)
pic.draw()
8_proxy.py
# coding : utf-8
# create by ztypl on 2017/5/26
from abc import ABCMeta, abstractmethod
class Subject(metaclass=ABCMeta):
@abstractmethod
def get_content(self):
pass
class RealSubject(Subject):
def __init__(self, filename):
print("读取%s文件内容"%filename)
f = open("filename")
self.content = f.read()
f.close()
def get_content(self):
return self.content
class ProxyA(Subject):
def __init__(self, filename):
self.subj = RealSubject(filename)
def get_content(self):
return self.subj.get_content()
class ProxyB(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()
class ProxyC(Subject):
def __init__(self, filename):
self.subj = RealSubject(filename)
def get_content(self):
return "???"
9_chain_of_responsibility.py
# coding : utf-8
# create by ztypl on 2017/5/27
from abc import ABCMeta, abstractmethod
class Handler(metaclass=ABCMeta):
@abstractmethod
def handle_leave(self, day):
pass
class GeneralManagerliHandler(Handler):
def handle_leave(self, day):
if day < 10:
print("总经理批准%d天假"%day)
else:
print("呵呵")
class DepartmentManagerHandler(Handler):
def __init__(self):
self.successor = GeneralManagerliHandler()
def handle_leave(self, day):
if day < 7:
print("部门经理批准%d天假"%day)
else:
print("部门经理无权准假")
self.successor.handle_leave(day)
class ProjectDirectorHandler(Handler):
def __init__(self):
self.successor = DepartmentManagerHandler()
def handle_leave(self, day):
if day < 3:
print("项目主管批准%d天假")
else:
print("项目主管无权准假")
self.successor.handle_leave(day)
day = 10
h = ProjectDirectorHandler()
h.handle_leave(day)
#--高级例子--模仿js事件处理
# class Handler(metaclass=ABCMeta):
# @abstractmethod
# def add_event(self, func):
# pass
#
# @abstractmethod
# def handle(self):
# pass
#
#
# class BodyHandler(Handler):
# def __init__(self):
# self.func = None
#
# def add_event(self, func):
# self.func = func
#
# def handle(self):
# if self.func:
# return self.func()
# else:
# print("已到最后一级,无法处理")
#
#
# class ElementHandler(Handler):
# def __init__(self, successor):
# self.func = None
# self.successor = successor
#
# def add_event(self, func):
# self.func = func
#
# def handle(self):
# if self.func:
# return self.func()
# else:
# return self.successor.handle()
#
#
# # 客户端
#
# # <body><div><a>
#
# body = {'type': 'body', 'name': 'body', 'children': [], 'father': None}
#
# div = {'type': 'div', 'name': 'div', 'children': [], 'father': body}
#
# a = {'type': 'a', 'name': 'a', 'children': [], 'father': div}
#
# body['children'].append(div)
# div['children'].append(a)
#
# body['event_handler'] = BodyHandler()
# div['event_handler'] = ElementHandler(div['father']['event_handler'])
# a['event_handler'] = ElementHandler(a['father']['event_handler'])
#
# def attach_event(element, func):
# element['event_handler'].add_event(func)
#
# #test
#
# def func_div():
# print("这是给div的函数")
#
# def func_a():
# print("这是给a的函数")
#
# def func_body():
# print("这是给body的函数")
#
# #attach_event(div, func_div)
# #attach_event(a, func_a)
# #attach_event(body, func_body)
#
#
#
#
#
# a['event_handler'].handle()
10_iterator.py
# coding : utf-8
# create by ztypl on 2017/5/27
class LinkList:
"""链表 头结点保存链表的长度"""
class Node:
def __init__(self, item=None):
self.item = item
self.next = None
class LinkListIterator:
def __init__(self, node):
self.node = node
def __next__(self):
if self.node:
cur_node = self.node
self.node = cur_node.next
return cur_node.item
else:
raise StopIteration
def __iter__(self):
return self
def __init__(self, iterable=None):
self.head = LinkList.Node(0)
self.tail = self.head
self.extend(iterable)
def append(self, obj):
s = LinkList.Node(obj)
self.tail.next = s
self.tail = s
def extend(self, iterable):
for obj in iterable:
self.append(obj)
self.head.item += len(iterable)
def __iter__(self):
return self.LinkListIterator(self.head.next)
def __len__(self):
return self.head.item
def __str__(self):
return "<<"+", ".join(map(str, self))+">>"
li = [i for i in range(100)]
print(li)
lk = LinkList(li)
print(lk)
print(len(lk))
11_observer.py
# coding : utf-8
# create by ztypl on 2017/5/27
from abc import ABCMeta, abstractmethod
class Observer(metaclass=ABCMeta):
@abstractmethod
def update(self, 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 obj in self.observers:
obj.update(self)
class ManagerNotice(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 Manager(Observer):
def __init__(self):
self.company_info = None
def update(self, noti):
self.company_info = noti.company_info
notice = ManagerNotice()
alex = Manager()
wusir = Manager()
print(alex.company_info)
print(wusir.company_info)
notice.attach(alex)
notice.attach(wusir)
notice.company_info="公司运行良好"
print(alex.company_info)
print(wusir.company_info)
notice.detach(wusir)
notice.company_info="公司要破产了"
print(alex.company_info)
print(wusir.company_info)
12_strategy.py
# coding : utf-8
# create by ztypl on 2017/5/27
from abc import ABCMeta, abstractmethod
import random
class Sort(metaclass=ABCMeta):
@abstractmethod
def sort(self, data):
pass
class QuickSort(Sort):
def quick_sort(self, data, left, right):
if left < right:
mid = self.partition(data, left, right)
self.quick_sort(data, left, mid - 1)
self.quick_sort(data, mid + 1, right)
def partition(self, data, left, right):
tmp = data[left]
while left < right:
while left < right and data[right] >= tmp:
right -= 1
data[left] = data[right]
while left < right and data[left] <= tmp:
left += 1
data[right] = data[left]
data[left] = tmp
return left
def sort(self, data):
print("快速排序")
return self.quick_sort(data, 0, len(data) - 1)
class MergeSort(Sort):
def merge(self, data, low, mid, high):
i = low
j = mid + 1
ltmp = []
while i <= mid and j <= high:
if data[i] <= data[j]:
ltmp.append(data[i])
i += 1
else:
ltmp.append(data[j])
j += 1
while i <= mid:
ltmp.append(data[i])
i += 1
while j <= high:
ltmp.append(data[j])
j += 1
data[low:high + 1] = ltmp
def merge_sort(self, data, low, high):
if low < high:
mid = (low + high) // 2
self.merge_sort(data, low, mid)
self.merge_sort(data, mid + 1, high)
self.merge(data, low, mid, high)
def sort(self, data):
print("归并排序")
return self.merge_sort(data, 0, len(data) - 1)
class Context:
def __init__(self, data, strategy=None):
self.data = data
self.strategy = strategy
def set_strategy(self, strategy):
self.strategy = strategy
def do_strategy(self):
if self.strategy:
self.strategy.sort(self.data)
else:
raise TypeError
li = list(range(100000))
random.shuffle(li)
context = Context(li, MergeSort())
context.do_strategy()
#print(context.data)
random.shuffle(context.data)
context.set_strategy(QuickSort())
context.do_strategy()
13_template_method.py
# coding : utf-8
# create by ztypl on 2017/5/27
from abc import ABCMeta, abstractmethod
class IOHandler(metaclass=ABCMeta):
@abstractmethod
def open(self, name):
pass
@abstractmethod
def deal(self, change):
pass
@abstractmethod
def close(self):
pass
def process(self, name, change):
self.open(name)
self.deal(change)
self.close()
窗体顶端
设计模式
什么是设计模式
o Christopher Alexander:“每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的解决方案的核心。这样你就能一次又一次地使用该方案而不必做重复劳动。”
o 每一个设计模式系统地命名、解释和评价了面向对象系统中一个重要的和重复出现的设计。
o GoF(Gang of Four)
o 设计模式四个基本要素:模式名称、问题、解决方案、效果
讲在设计模式之前
o 对象/类
n 封装
n 继承
n 多态
o 接口:一种特殊的类,声明了若干方法,要求继承该接口的类必须实现这些方法。
n 作用:限制继承接口的类的方法的名称及调用方式;隐藏了类的内部实现。
n 接口就是一种抽象的基类(父类),限制继承它的类必须实现接口中定义的某些方法
Python中接口的两种写法
设计模式六大原则
o 开闭原则:一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。即软件实体应尽量在不修改原有代码的情况下进行扩展。
o 里氏(Liskov)替换原则:所有引用基类(父类)的地方必须能透明地使用其子类的对象。
o 依赖倒置原则:高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。换言之,要针对接口编程,而不是针对实现编程。
o 接口隔离原则:使用多个专门的接口,而不使用单一的总接口,即客户端不应该依赖那些它不需要的接口。
o 迪米特法则:一个软件实体应当尽可能少地与其他实体发生相互作用。
o 单一职责原则:不要存在多于一个导致类变更的原因。通俗的说,即一个类只负责一项职责。
设计模式分类
o 创建型模式:
n 工厂方法模式
n 抽象工厂模式
n 创建者模式
n 原型模式
n 单例模式
o 结构型模式
n 适配器模式
n 桥模式
n 组合模式
n 装饰模式
n 外观模式
n 享元模式
n 代理模式
o 行为型模式
n 解释器模式
n 责任链模式
n 命令模式
n 迭代器模式
n 中介者模式
n 备忘录模式
n 观察者模式
n 状态模式
n 策略模式
n 访问者模式
n 模板方法模式
简单工厂模式
o 内容:不直接向客户端暴露对象创建的实现细节,而是通过一个工厂类来负责创建产品类的实例。
o 角色:
n 工厂角色(Factory)
n 抽象产品角色(Product)
n 具体产品角色(Concrete Product)
o 优点:
n 隐藏了对象创建的实现细节
n 客户端不需要修改代码
o 缺点:
n 违反了单一职责原则,将创建逻辑几种到一个工厂类里
n 当添加新产品时,需要修改工厂类代码,违反了开闭原则
工厂方法模式
o 内容:定义一个用于创建对象的接口(工厂接口),让子类决定实例化哪一个产品类。
o 角色:
n 抽象工厂角色(Creator)
n 具体工厂角色(Concrete Creator)
n 抽象产品角色(Product)
n 具体产品角色(Concrete Product)
o 工厂方法模式相比简单工厂模式将每个具体产品都对应了一个具体工厂。
工厂方法模式
工厂方法模式
o 适用场景:
n 需要生产多种、大量复杂对象的时候
n 需要降低耦合度的时候
n 当系统中的产品种类需要经常扩展的时候
o 优点:
n 每个具体产品都对应一个具体工厂类,不需要修改工厂类代码
n 工厂类可以不知道它所创建的对象的类
n 隐藏了对象创建的实现细节
o 缺点
n 每增加一个具体产品类,就必须增加一个相应的具体工厂类
抽象工厂模式
o 内容:定义一个工厂类接口,让工厂子类来创建一系列相关或相互依赖的对象。
o 例:生产一部手机,需要手机壳、CPU、操作系统三类对象进行组装,其中每类对象都有不同的种类。对每个具体工厂,分别生产一部手机所需要的三个对象。
o 角色:
n 抽象工厂角色(Creator)
n 具体工厂角色(Concrete Creator)
n 抽象产品角色(Product)
n 具体产品角色(Concrete Product)
n 客户端(Client)
o 相比工厂方法模式,抽象工厂模式中的每个具体工厂都生产一套产品。
抽象工厂模式
抽象工厂模式
o 适用场景:
n 系统要独立于产品的创建与组合时
n 强调一系列相关的产品对象的设计以便进行联合使用时
n 提供一个产品类库,想隐藏产品的具体实现时
o 优点:
n 将客户端与类的具体实现相分离
n 每个工厂创建了一个完整的产品系列,使得易于交换产品系列
n 有利于产品的一致性(即产品之间的约束关系)
o 缺点:
n 难以支持新种类的(抽象)产品
建造者模式
o 内容:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
o 角色:
n 抽象建造者(Builder)
n 具体建造者(Concrete Builder)
n 指挥者(Director)
n 产品(Product)
o 建造者模式与抽象工厂模式相似,也用来创建复杂对象。主要区别是建造者模式着重一步步构造一个复杂对象,而抽象工厂模式着重于多个系列的产品对象。
建造者模式
建造者模式
o 适用场景:
n 当创建复杂对象的算法(Director)应该独立于该对象的组成部分以及它们的装配方式(Builder)时
n 当构造过程允许被构造的对象有不同的表示时(不同Builder)。
o 优点:
n 隐藏了一个产品的内部结构和装配过程
n 将构造代码与表示代码分开
n 可以对构造过程进行更精细的控制
单例模式
o 内容:保证一个类只有一个实例,并提供一个访问它的全局访问点。
o 角色:
n 单例(Singleton)
o 适用场景
n 当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时
o 优点:
n 对唯一实例的受控访问
n 单例相当于全局变量,但防止了命名空间被污染
o 与单例模式功能相似的概念:全局变量、静态变量(方法)
创建型模式小结
o 依赖于继承的创建型模式:工厂方法模式
o 依赖于组合的创建性模式:抽象工厂模式、创建者模式
适配器模式
o 内容:将一个类的接口转换成客户希望的另一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
o 角色:
n 目标接口(Target)
n 待适配的类(Adaptee)
n 适配器(Adapter)
o 两种实现方式:
n 类适配器:使用多继承
n 对象适配器:使用组合
适配器模式
适配器模式
o 适用场景:
n 想使用一个已经存在的类,而它的接口不符合你的要求
n (对象适配器)想使用一些已经存在的子类,但不可能对每一个都进行子类化以匹配它们的接口。对象适配器可以适配它的父类接口。
组合模式
o 内容:将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
o 角色:
n 抽象组件(Component)
n 叶子组件(Leaf)
n 复合组件(Composite)
n 客户端(Client)
组合模式
组合模式
o 适用场景:
n 表示对象的“部分-整体”层次结构(特别是结构是递归的)
n 希望用户忽略组合对象与单个对象的不同,用户统一地使用组合结构中的所有对象
o 优点:
n 定义了包含基本对象和组合对象的类层次结构
n 简化客户端代码,即客户端可以一致地使用组合对象和单个对象
n 更容易增加新类型的组件
o 缺点:
n 很难限制组合中的组件
代理模式
o 内容:为其他对象提供一种代理以控制对这个对象的访问。
o 角色:
n 抽象实体(Subject)
n 实体(RealSubject)
n 代理(Proxy)
o 适用场景:
n 远程代理:为远程的对象提供代理
n 虚代理:根据需要创建很大的对象
n 保护代理:控制对原始对象的访问,用于对象有不同访问权限时
o 优点:
n 远程代理:可以隐藏对象位于远程地址空间的事实
n 虚代理:可以进行优化,例如根据要求创建对象
n 保护代理:允许在访问一个对象时有一些附加的内务处理
代理模式
责任链模式
o 内容:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
o 角色:
n 抽象处理者(Handler)
n 具体处理者(ConcreteHandler)
n 客户端(Client)
o 例:
n 请假部门批准:leaderà部门经理à总经理
n Javascript事件浮升机制
责任链模式
责任链模式
o 适用场景:
n 有多个对象可以处理一个请求,哪个对象处理由运行时决定
n 在不明确接收者的情况下,向多个对象中的一个提交一个请求
o 优点:
n 降低耦合度:一个对象无需知道是其他哪一个对象处理其请求
o 缺点:
n 请求不保证被接收:链的末端没有处理或链配置错误
迭代器模式
o 内容:提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示
o 实现方法:__iter__、__next__
观察者模式
o 内容:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。观察者模式又称“发布-订阅”模式
o 角色:
n 抽象主题(Subject)
n 具体主题(ConcreteSubject)——发布者
n 抽象观察者(Observer)
n 具体观察者(ConcreteObserver)——订阅者
观察者模式
观察者模式
o 适用场景:
n 当一个抽象模型有两方面,其中一个方面依赖于另一个方面。将这两者封装在独立对象中以使它们可以各自独立地改变和复用。
n 当对一个对象的改变需要同时改变其它对象,而不知道具体有多少对象有待改变。
n 当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换言之,你不希望这些对象是紧密耦合的。
o 优点:
n 目标和观察者之间的抽象耦合最小
n 支持广播通信
o 缺点:
n 多个观察者之间互不知道对方存在,因此一个观察者对主题的修改可能造成错误的更新。
策略模式
o 内容:定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。
o 角色:
n 抽象策略(Strategy)
n 具体策略(ConcreteStrategy)
n 上下文(Context)
o 适用场景:
n 许多相关的类仅仅是行为有异
n 需要使用一个算法的不同变体
n 算法使用了客户端无需知道的数据
n 一个类中的多种行为以多个条件语句的形式存在,可以将这些行为封装如不同的策略类中。
策略模式
策略模式
o 优点:
n 定义了一系列可重用的算法和行为
n 消除了一些条件语句
n 可以提供相同行为的不同实现
o 缺点:
n 客户必须了解不同的策略
n 策略与上下文之间的通信开销
n 增加了对象的数目
模板方法模式
o 内容:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
o 角色:
n 抽象类(AbstractClass):定义抽象的原子操作(钩子操作);实现一个模板方法作为算法的骨架。
n 具体类(ConcreteClass):实现原子操作
o 适用场景:
n 一次性实现一个算法的不变的部分
n 各个子类中的公共行为应该被提取出来并集中到一个公共父类中以避免代码重复
n 控制子类扩展
模板方法模式
代码如下:0_interface.py
# coding : utf-8
# create by ztypl on 2017/5/24
from abc import abstractmethod, ABCMeta
class Payment(metaclass=ABCMeta):
@abstractmethod
def pay(self, money):
raise NotImplementedError
class Alipay(Payment):
def pay(self, money):
print("支付宝支付%s元"%money)
class ApplePay(Payment):
def pay(self, money):
print("苹果支付%s元"%money)
class WechatPay(Payment):
def pay(self, money):
print("微信支付%s元"%money)
1_factory.py
# coding : utf-8
# create by ztypl on 2017/5/24
from abc import abstractmethod, ABCMeta
class Payment(metaclass=ABCMeta):
@abstractmethod
def pay(self, money):
raise NotImplementedError
class Alipay(Payment):
def pay(self, money):
print("支付宝支付%s元" % money)
class ApplePay(Payment):
def pay(self, money):
print("苹果支付%s元" % money)
class PaymentFactory:
def create_payment(self, method):
if method == "alipay":
return Alipay()
elif method == "applepay":
return ApplePay()
else:
raise NameError(method)
2_factory_method.py
# coding : utf-8
# create by ztypl on 2017/5/25
from abc import abstractmethod, ABCMeta
class Payment(metaclass=ABCMeta):
@abstractmethod
def pay(self, money):
raise NotImplementedError
class Alipay(Payment):
def pay(self, money):
print("支付宝支付%s元" % money)
class ApplePay(Payment):
def pay(self, money):
print("苹果支付%s元"%money)
class PaymentFactory:
def create_payment(self):
raise NotImplementedError
class AlipayFactory(PaymentFactory):
def create_payment(self):
return Alipay()
class ApplePayFactory(PaymentFactory):
def create_payment(self):
return ApplePay()
# 用户输入
# 支付宝,120
af = AlipayFactory()
ali = af.create_payment()
ali.pay(120)
3_abstract_factory.py
# coding : utf-8
# create by ztypl on 2017/5/25
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(MiFactory())
p1.show_info()
4_builder.py
# coding : utf-8
# create by ztypl on 2017/5/25
from abc import abstractmethod, ABCMeta
#------产品------
class Player:
def __init__(self, face=None, body=None, arm=None, leg=None):
self.face = face
self.arm = arm
self.leg = leg
self.body = body
def __str__(self):
return "%s, %s, %s, %s" % (self.face, self.arm, self.body, self.leg)
#------建造者------
class PlayerBuilder(metaclass=ABCMeta):
@abstractmethod
def build_face(self):
pass
@abstractmethod
def build_arm(self):
pass
@abstractmethod
def build_leg(self):
pass
@abstractmethod
def build_body(self):
pass
@abstractmethod
def get_player(self):
pass
class BeautifulWomanBuilder(PlayerBuilder):
def __init__(self):
self.player = Player()
def build_face(self):
self.player.face = "漂亮脸蛋"
def build_arm(self):
self.player.arm="细胳膊"
def build_body(self):
self.player.body="细腰"
def build_leg(self):
self.player.leg="长腿"
def get_player(self):
return self.player
class PlayerDirector:
def build_player(self, builder):
builder.build_face()
builder.build_arm()
builder.build_leg()
builder.build_body()
return builder.get_player()
pd = PlayerDirector()
pb = BeautifulWomanBuilder()
p = pd.build_player(pb)
print(p)
5_singleton.py
# coding : utf-8
# create by ztypl on 2017/5/25
from abc import abstractmethod, ABCMeta
class Singleton(object):
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, name=None):
if name is not None:
self.name = name
a = MyClass("a")
print(a)
print(a.name)
b = MyClass("b")
print(b)
print(b.name)
print(a)
print(a.name)
6_adapter.py
# coding : utf-8
# create by ztypl on 2017/5/25
from abc import abstractmethod, ABCMeta
class Payment(metaclass=ABCMeta):
@abstractmethod
def pay(self, money):
raise NotImplementedError
class Alipay(Payment):
def pay(self, money):
print("支付宝支付%s元"%money)
class ApplePay(Payment):
def pay(self, money):
print("苹果支付%s元"%money)
#------待适配类------
class WechatPay:
def huaqian(self, money):
print("微信支付%s元"%money)
#------类适配器------
class RealWeChatPay(Payment, WechatPay):
def pay(self, money):
return self.huaqian(money)
#------对象适配器------
class PayAdapter(Payment):
def __init__(self, payment):
self.payment = payment
def pay(self, money):
return self.payment.huaqian(money)
RealWeChatPay().pay(100)
#PayAdapter(WechatPay()).pay(1000)
7_composite
# coding : utf-8
# create by ztypl on 2017/5/25
from abc import abstractmethod, ABCMeta
class Graphic(metaclass=ABCMeta):
@abstractmethod
def draw(self):
pass
@abstractmethod
def add(self, graphic):
pass
def getchildren(self):
pass
class Point(Graphic):
def __init__(self, x, y):
self.x = x
self.y = y
def draw(self):
print(self)
def add(self, graphic):
raise TypeError
def getchildren(self):
raise TypeError
def __str__(self):
return "点(%s, %s)" % (self.x, self.y)
class Line(Graphic):
def __init__(self, p1, p2):
self.p1 = p1
self.p2 = p2
def draw(self):
print(self)
def add(self, graphic):
raise TypeError
def getchildren(self):
raise TypeError
def __str__(self):
return "线段[%s, %s]" % (self.p1, self.p2)
class Picture(Graphic):
def __init__(self):
self.children = []
def add(self, graphic):
self.children.append(graphic)
def getchildren(self):
return self.children
def draw(self):
print("------复合图形------")
for g in self.children:
g.draw()
print("------END------")
pic1 = Picture()
pic1.add(Point(2,3))
pic1.add(Line(Point(1,2), Point(4,5)))
pic1.add(Line(Point(0,1), Point(2,1)))
pic2 = Picture()
pic2.add(Point(-2,-1))
pic2.add(Line(Point(0,0), Point(1,1)))
pic = Picture()
pic.add(pic1)
pic.add(pic2)
pic.draw()
8_proxy.py
# coding : utf-8
# create by ztypl on 2017/5/26
from abc import ABCMeta, abstractmethod
class Subject(metaclass=ABCMeta):
@abstractmethod
def get_content(self):
pass
class RealSubject(Subject):
def __init__(self, filename):
print("读取%s文件内容"%filename)
f = open("filename")
self.content = f.read()
f.close()
def get_content(self):
return self.content
class ProxyA(Subject):
def __init__(self, filename):
self.subj = RealSubject(filename)
def get_content(self):
return self.subj.get_content()
class ProxyB(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()
class ProxyC(Subject):
def __init__(self, filename):
self.subj = RealSubject(filename)
def get_content(self):
return "???"
9_chain_of_responsibility.py
# coding : utf-8
# create by ztypl on 2017/5/27
from abc import ABCMeta, abstractmethod
class Handler(metaclass=ABCMeta):
@abstractmethod
def handle_leave(self, day):
pass
class GeneralManagerliHandler(Handler):
def handle_leave(self, day):
if day < 10:
print("总经理批准%d天假"%day)
else:
print("呵呵")
class DepartmentManagerHandler(Handler):
def __init__(self):
self.successor = GeneralManagerliHandler()
def handle_leave(self, day):
if day < 7:
print("部门经理批准%d天假"%day)
else:
print("部门经理无权准假")
self.successor.handle_leave(day)
class ProjectDirectorHandler(Handler):
def __init__(self):
self.successor = DepartmentManagerHandler()
def handle_leave(self, day):
if day < 3:
print("项目主管批准%d天假")
else:
print("项目主管无权准假")
self.successor.handle_leave(day)
day = 10
h = ProjectDirectorHandler()
h.handle_leave(day)
#--高级例子--模仿js事件处理
# class Handler(metaclass=ABCMeta):
# @abstractmethod
# def add_event(self, func):
# pass
#
# @abstractmethod
# def handle(self):
# pass
#
#
# class BodyHandler(Handler):
# def __init__(self):
# self.func = None
#
# def add_event(self, func):
# self.func = func
#
# def handle(self):
# if self.func:
# return self.func()
# else:
# print("已到最后一级,无法处理")
#
#
# class ElementHandler(Handler):
# def __init__(self, successor):
# self.func = None
# self.successor = successor
#
# def add_event(self, func):
# self.func = func
#
# def handle(self):
# if self.func:
# return self.func()
# else:
# return self.successor.handle()
#
#
# # 客户端
#
# # <body><div><a>
#
# body = {'type': 'body', 'name': 'body', 'children': [], 'father': None}
#
# div = {'type': 'div', 'name': 'div', 'children': [], 'father': body}
#
# a = {'type': 'a', 'name': 'a', 'children': [], 'father': div}
#
# body['children'].append(div)
# div['children'].append(a)
#
# body['event_handler'] = BodyHandler()
# div['event_handler'] = ElementHandler(div['father']['event_handler'])
# a['event_handler'] = ElementHandler(a['father']['event_handler'])
#
# def attach_event(element, func):
# element['event_handler'].add_event(func)
#
# #test
#
# def func_div():
# print("这是给div的函数")
#
# def func_a():
# print("这是给a的函数")
#
# def func_body():
# print("这是给body的函数")
#
# #attach_event(div, func_div)
# #attach_event(a, func_a)
# #attach_event(body, func_body)
#
#
#
#
#
# a['event_handler'].handle()
10_iterator.py
# coding : utf-8
# create by ztypl on 2017/5/27
class LinkList:
"""链表 头结点保存链表的长度"""
class Node:
def __init__(self, item=None):
self.item = item
self.next = None
class LinkListIterator:
def __init__(self, node):
self.node = node
def __next__(self):
if self.node:
cur_node = self.node
self.node = cur_node.next
return cur_node.item
else:
raise StopIteration
def __iter__(self):
return self
def __init__(self, iterable=None):
self.head = LinkList.Node(0)
self.tail = self.head
self.extend(iterable)
def append(self, obj):
s = LinkList.Node(obj)
self.tail.next = s
self.tail = s
def extend(self, iterable):
for obj in iterable:
self.append(obj)
self.head.item += len(iterable)
def __iter__(self):
return self.LinkListIterator(self.head.next)
def __len__(self):
return self.head.item
def __str__(self):
return "<<"+", ".join(map(str, self))+">>"
li = [i for i in range(100)]
print(li)
lk = LinkList(li)
print(lk)
print(len(lk))
11_observer.py
# coding : utf-8
# create by ztypl on 2017/5/27
from abc import ABCMeta, abstractmethod
class Observer(metaclass=ABCMeta):
@abstractmethod
def update(self, 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 obj in self.observers:
obj.update(self)
class ManagerNotice(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 Manager(Observer):
def __init__(self):
self.company_info = None
def update(self, noti):
self.company_info = noti.company_info
notice = ManagerNotice()
alex = Manager()
wusir = Manager()
print(alex.company_info)
print(wusir.company_info)
notice.attach(alex)
notice.attach(wusir)
notice.company_info="公司运行良好"
print(alex.company_info)
print(wusir.company_info)
notice.detach(wusir)
notice.company_info="公司要破产了"
print(alex.company_info)
print(wusir.company_info)
12_strategy.py
# coding : utf-8
# create by ztypl on 2017/5/27
from abc import ABCMeta, abstractmethod
import random
class Sort(metaclass=ABCMeta):
@abstractmethod
def sort(self, data):
pass
class QuickSort(Sort):
def quick_sort(self, data, left, right):
if left < right:
mid = self.partition(data, left, right)
self.quick_sort(data, left, mid - 1)
self.quick_sort(data, mid + 1, right)
def partition(self, data, left, right):
tmp = data[left]
while left < right:
while left < right and data[right] >= tmp:
right -= 1
data[left] = data[right]
while left < right and data[left] <= tmp:
left += 1
data[right] = data[left]
data[left] = tmp
return left
def sort(self, data):
print("快速排序")
return self.quick_sort(data, 0, len(data) - 1)
class MergeSort(Sort):
def merge(self, data, low, mid, high):
i = low
j = mid + 1
ltmp = []
while i <= mid and j <= high:
if data[i] <= data[j]:
ltmp.append(data[i])
i += 1
else:
ltmp.append(data[j])
j += 1
while i <= mid:
ltmp.append(data[i])
i += 1
while j <= high:
ltmp.append(data[j])
j += 1
data[low:high + 1] = ltmp
def merge_sort(self, data, low, high):
if low < high:
mid = (low + high) // 2
self.merge_sort(data, low, mid)
self.merge_sort(data, mid + 1, high)
self.merge(data, low, mid, high)
def sort(self, data):
print("归并排序")
return self.merge_sort(data, 0, len(data) - 1)
class Context:
def __init__(self, data, strategy=None):
self.data = data
self.strategy = strategy
def set_strategy(self, strategy):
self.strategy = strategy
def do_strategy(self):
if self.strategy:
self.strategy.sort(self.data)
else:
raise TypeError
li = list(range(100000))
random.shuffle(li)
context = Context(li, MergeSort())
context.do_strategy()
#print(context.data)
random.shuffle(context.data)
context.set_strategy(QuickSort())
context.do_strategy()
13_template_method.py
# coding : utf-8
# create by ztypl on 2017/5/27
from abc import ABCMeta, abstractmethod
class IOHandler(metaclass=ABCMeta):
@abstractmethod
def open(self, name):
pass
@abstractmethod
def deal(self, change):
pass
@abstractmethod
def close(self):
pass
def process(self, name, change):
self.open(name)
self.deal(change)
self.close()