Python之设计模式学习

Python之设计模式学习

python是面向对象的动态编程语言。
面向对象的三大特性:封装、继承、多态

1、接口:抽象方法的集合

from abc import ABCMeta, abstractmethod
# 定义抽象接口
class Payment(met=ABCMeta):
    @abstractmethod
    def pay(self, money):
        pass

2、设计原则:
开放封闭原则,
里氏替换原则
依赖倒置原则
接口隔离原则
单一责任原则

3、设计模式分类:
创建型模式:5(用户主要以借口为准,不需要了解内部实现)
工厂方法模式、抽象工厂模式、创建者模式、原型模式、单例模式

结构型模式:7
适配器模式、桥模式、组合模式、装饰模式、外观模式、享元模式、代理模式

行为型模式:11
解释器模式、责任链模式、命令模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、访问者模式、模板方法模式

创建型模式

工厂方法模式

通过定义工厂的抽象接口,使得接口隔离、责任单一。
对象包括抽象工厂、具体工厂、抽象产品、具体产品。

优缺点:
实现具体工厂不需要修改代码、实现隐藏对象的细节。
没个具体产品对应一个工厂,代码多。

class Payment(met=ABCMeta):
    @abstractmethod
    def pay(self, money):
        pass

抽象工厂模式

通过定义抽象接口,中包括多个对象生成一套。需限制产品配套使用,设计具体工厂。

优缺点:
参照接口,具体工厂直接封装,利于产品一致性,改变具体工厂中单个属性较容易。
工厂增加新的属性困难。

创建者模式

在抽象工厂基础上,进一步封装一个Director进行指挥代码调用顺序。

优缺点:
构造代码与标识代码分离,能对结构中流程控制更加灵活,隐藏内部实现。

单例模式

应用于确保唯一的数据,
通过定义new魔术方法,确保一个类只返回一个实例,物理地址唯一。

优点:
对唯一实例的受控访问,相当于全局变量,但命名空间未被污染。

# 单例模式
class singlee:
    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, "_instance"):
            cls._instance = super(singlee, cls).__new__(cls)
        return cls._instance


class Myclass(singlee):
    def __init__(self, a):
        self.a = a


a = Myclass(10)
# 被b调用覆盖前
print(a, id(a))
print(a.a)
b = Myclass(20)
# 被b调用覆盖前
print(a, id(a))
print(a.a)
print(b, id(b))
print(b.a)
<__main__.Myclass object at 0x7f47d147a240> 139946430538304
10
<__main__.Myclass object at 0x7f47d147a240> 139946430538304
20
<__main__.Myclass object at 0x7f47d147a240> 139946430538304
20

结构型模式 :

适配器模式

通过增加中间转换,将一方方法通过另一种的方法的封装进行调用
(目标接口、待适配的类、适配器)
解决存在于两个系统合并,代码定义属性名称不一致,无法调用等问题

# 类适配器模式——少数对象不一致
class NewPay(转换为对象, 装换的对象):
    def 转换为对象de属性名称(self, 参数):
        self.装换的对象de属性名称(参数)
# 对象适配器——多个对象
class NewPay(转换为对象):
    def __init__(self, 转换为对象):
        self.转换为对象 = 转换为对象
    # 对对象进行封装再通过类方法调用
    def 转换为对象de属性名称(self, 参数):
        self.装换的对象de属性名称(参数)

p = NewPay(装换的类对象)
# 调用方法进行转换
P.转换为对象de属性名称(参数)     

桥模式

数据联系方式——继承、组合
继承,紧耦合不方便扩展
组合,松耦合方便不同维度扩展
(包括抽象、细化抽象、实现者、具体实现者)

事物有两个维度上扩展的需求时使用。

优缺点:
抽象和实现相分离,采用组合方式高扩展性。

from abc import ABCMeta, abstractmethod

class Hang(metaclass=ABCMeta):
    # 通过定义成属性,将Lie类与Hang类组合
    def __init__(self, lie):
        self.lie = lie
    @abstractmethod
    def hanghao(self):
        pass


class Lie(metaclass=ABCMeta):
    @abstractmethod
    def liehao(self, hang):
        pass

class hang3(Hang):
    v = "第三行"
    def hanghao(self):
        self.lie.liehao(self)

class hang4(Hang):
    v = '第四行'
    def hanghao(self):
        self.lie.liehao(self)

class lie2(Lie):
    def liehao(self, hang):
        print("%s这是第二列" % hang.v)

class lie3(Lie):
    def liehao(self, hang):
        print("%s这是第三列" % hang.v)


hangss = hang3(lie2())
hangss.hanghao()
第三行这是第二列

组合模式

表现部分与整体的层次结构,特别是有递归需求。希望组合对象与单个对象均采用统一抽象接口,适用于结构中所有对象。
(抽象组件、叶子组件、复合组件、#客户端)

优缺点:更容易增加新功能组件(可扩展性),结构层次——树状,统一抽象接口。

from abc import ABCMeta, abstractmethod

class Abstac(metaclass=ABCMeta):
    @abstractmethod
    def draw(self):
        pass
# 叶子组件
class Poin(Abstac):
    def __init__(self, poin):
        self.poin = poin
    def __str__(self):
        return "%s点" % self.poin
    def draw(self):
        print(str(self))

# 叶子组件
class Lin(Abstac):
    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))
# 简单组合模型
# a = Lin(Poin(2), Poin(10))
# print(a)

# 复合组件
class Comp(Abstac):
    def __init__(self, iterable):
# 创建child列表接收数据
        self.child = []
        for c in iterable:
# 调用方法追加入child
            self.adds(c)
    def adds(self, grapsh):
        self.child.append(grapsh)
# 递归函数
    def draw(self):
        print("----复合图形----")
# 从child列表中循环调用draw方法
        for g in self.child:
            g.draw()
        print("----复合图形----")

#复合组成(树状结构)
b = Poin(12)
a = Lin(Poin(2), Poin(10))
c = Lin(Poin(44), Poin(9))
com = Comp([b, a, c])
com.draw()

外观模式

将功能进一步整合封装,调用封装的类产生不同的模式。
(外观、子系统类)

优缺点:
减少系统底层和高层依赖(都依赖于实例化的接口),降低复杂系统调用错误率,更高程度封装不显示底层细节,侧重于接口提供的功能模式。

代理模式

为其他对象控制此对象设置的中介
(抽象实体、实体、代理)

三大代理模式:
1、远程代理;访问远端或其他数据做出转接
2、虚代理;对现有对象功能进行继承重写(扩展)
3、保护代理;(控制访问权限)

优缺点:
远程:隐藏对象远程地址空间
虚代理:优化功能,创建对象
保护代理:访问对象附加业务处理

# 代理模式
from abc import ABCMeta, abstractmethod


class Age(metaclass=ABCMeta):
    @abstractmethod
    def open_fi(self):
        pass

    @abstractmethod
    def close_fi(self, content):
        pass


# 文件写入——远端代理
class Realsub(Age):
    def __init__(self, filename):
        self.filename = filename
        f = open(self.filename, 'r', encoding='utf-8')
        self.content = f.read()
        f.close()

    def open_fi(self):
        return self.content

    def close_fi(self, content):
        f = open(self.filename, 'w', encoding='utf-8')
        f.write(content)
        f.close()


# 虚代理(调用时判断状态,文件写入方法调用时才打开,节省内存空间)
class VirturlPro(Age):
    def __init__(self, filename):
        self.filename = filename
        self.subj = None

    def open_fi(self):
        if not self.subj:
        #增加判断,使得open_fi只有在调用时才会启动。
            self.subj = Realsub(self.filename)
        return self.subj.open_fi()

    def close_fi(self, content):
        pass


# 保护代理(设置访问权限)
class ProtectPor(Age):
    def __init__(self, filename):
        self.subj = Realsub(filename)

    def open_fi(self):
        return self.subj.open_fi()

    def close_fi(self, content):
        raise PermissionError("无写入权限")

# sub = Realsub('books.txt')
# sub.open_fi()
# sub1 = VirturlPro('books.txt')
# sub1.open_fi()
# sub = ProtectPor('books.txt')
# sub.close_fi("abc")

行为型模式

责任链模式

传入请求可能需要多个对象处理,为避免请求处理的耦合关系。将对象串联或并联成链,进行判断处理。(一对多)
(抽象处理者、具体处理者、#用户端)

优缺点:
降低耦合度,无需知道谁处理,只需从链头传入进行判断。

案例:python中的scrapy的pipeling

观察者模式(发布-订阅模式)

一对多的发布—订阅依赖关系。——松耦合
用于封装多对多,往往一方依赖于另一方,但两则需要独立封装(不希望紧密耦合)。发布者改变后订阅者自动改变,不需要知道有哪些需要手动改变。
(抽象主题、具体主题、抽象观察者、具体观察者)

优缺点:
抽象耦合性小,支持广播通信。

from abc import ABCMeta, abstractmethod

# 抽象订阅者
class Users(metaclass=ABCMeta):
    @abstractmethod
    def update(self, notice):
        pass

# 抽象发布者
class Cortlcent:
    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 Duyueming(Cortlcent):
    def __init__(self, centel_info):
        super().__init__()
        # 创建为私有属性
        self.__centel_info = centel_info
    # 属性装饰器语法
    @property
    def centel_info(self):
        return self.__centel_info
    # 负责重写方法
    @centel_info.setter
    def centel_info(self, info):
        self.__centel_info = info # 实现自己更新
        self.notify() # 推送


class Used(Users):
    def __init__(self):
        self.centel_info = None

    def update(self, notice):
        self.centel_info = notice.centel_info


notice = Duyueming("公司信息")
# 订阅者
s1 = Used()
s2 = Used()
# 绑定订阅者
notice.attach(s1)
notice.attach(s2)
# 发布信息
notice.centel_info = "信息已发布"
print(s1.centel_info)
# 取消订阅
notice.detach(s2)
notice.centel_info = "无信息发布"
print(s1.centel_info)
print(s2.centel_info)

策略模式

定义算法后分别封装,且相互可替换。使根据条件切换不同算法。
(抽象策略、具体策略、上下文)

优缺点:
可重用算法和行为,消除一些条件语句,可提供相同行为不同实现方式(封装可替换)。
使用者必须清楚不同策略的使用场景

模板方法模式

定义抽象接口中存在部分算法核心代码已经实现细节,其他方法框架搭建需要开发。
各子类公共部分代码提取到公共父类(代码复用),控制子类扩展,实现核心代码不变
(抽象类【原子操作、钩子操作】、具体类【实现原子操作】)

优缺点:
代码复用,框架搭建更快
模板代码公用导致个别方法无法实现。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值