python常用设计模式

一、设计模式基础

1. 基础知识

  • 设计模式:对软件设计中普遍存在(反复出现)的各种问题,所提出的解决方案。每一个设计模式系统地命名、解释和评价了面向对象系统中一个重要的和重复出现的设计。

  • 面向对象的三大特性:

    1. 封装

    2. 继承

    3. 多态

    这三大特性顺序不能错,因为他们之间不是并列关系而是递进关系。

  • 接口:若干抽象方法的集合。

    作用:限制实现接口的类必须按照接口给定的调用方式实现这些方法;对高层模块隐藏了类的内部实现。

    代码示例:

    # 接口方法一:
    # class Payment:
    #     def pay(self,money):
    #         raise NotImplementedError  # 抛出一个没有实现错误,要求继承Payment的类必须实现pay方法
    
    # 接口方法二:常用
    from abc import ABCMeta, abstractmethod
    class Payment(metaclass=ABCMeta):
        # abc: 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 = Alipay()
    p = WechatPay()
    p.pay(100)
    
  • 如果一个类里有抽象方法,那么该类就是一个抽象类。上述代码中Payment类有抽象方法def pay(),所以Payment是一个抽象类。

  • 上述代码的Alipay类和Wechat类就算底层代码,对类的调用p.pay(100)就属于高层代码(模块),如果有了接口进行限制,编写高层代码的人只需要读懂接口就可以正确调用函数,而不必把底层的每个类是如何实现的挨个看一遍。

2. 面向对象设计SOLID原则

  • 单一职责原则(Single Responsibility Principle):不要存在多于一个导致类变更的原因。通俗的说,即一个类只负责一项职责。

  • 开放封闭原则(Open Closed Principle):一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。即软件实体应尽量在不修改原有代码的情况下进行扩展。

  • 里氏替换原则(Liskov Substitution Principle):所有引用父类的地方必须能透明地使用其子类的对象。

  • 接口隔离原则(Interface-Segregation Principles):使用多个专门的接口,而不使用单一的总接口,即客户端(高层模块)不应该依赖那些它不需要的接口。

    解释:设计模式中客户端的概念通常是指高层代码(模块),并不是网络通信server、client概念下的客户端。

  • 依赖倒置原则(Dependence Inversion Principle):高层模块不应该依赖底层模块,二者都应该依赖其抽象(即接口);抽象不应该依赖细节;细节应该依赖抽象。换言之,要针对接口编程,而不是针对实现编程。

    解释:这样如果底层代码进行了改动,高层代码(模块)则不用随之改动。抽象就是上述代码的class Payment接口,细节就是class Alipay和class WechatPay,应该是先定义好接口,然后根据接口规则去实现细节;不能先写好细节,根据细节去定义接口。

    代码示例:

    # 接口隔离原则
    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):
        def walk(self):
            print("青蛙走路")
        def swim(self):
            print("青蛙游泳")
    

3. 设计模式分类

  • 创建型模式(5种):工厂方法模式、抽象工厂模式、创建者模式、原型模式、单例模式。
  • 结构型模式(7种):适配器模式、桥模式、组合模式、装饰模式、外观模式、享元模式、代理模式。
  • 行为型模式(11种):解释器模式、责任链模式、命令模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、访问者模式、模版方法模式。

4. 简单工厂模式(Simple Factory Pattern)

  • 简单工厂模式不属于23种设计模式。

  • 内容:不直接向客户端暴露对象创建的实现细节,而是通过一个工厂类来负责创建产品类的实例。

  • 角色:

    工厂角色(Creator)

    抽象产品角色(Product)

    具体产品角色(Concrete Product)

代码示例:

# 简单工厂模式
from abc import ABCMeta, abstractmethod

class Payment(metaclass=ABCMeta):  # 抽象产品角色
    # abc: abstract class
    @abstractmethod
    def pay(self,money):
        pass

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 PaymentFactor:   # 工厂角色
    def creat_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 = PaymentFactor()
p = pf.creat_payment('huabei')
p.pay(100)
  • 优点:
    1. 隐藏了对象创建的实现细节。
    2. 客户端client(高层模块)不需要修改代码。
  • 缺点:
    1. 违反了单一职责原则,将创建逻辑集中到一个工厂类里。
    2. 当添加新产品时,需要修改工厂类代码,违反了开放封闭原则。

二、创建型模式(5种)

1. 工厂方法模式(Factory Pattern)

  • 内容:定义一个用于创建对象的接口(工厂接口),让子类决定实例化哪一个产品类。

  • 角色:

    抽象工厂角色(Creator)

    具体工厂角色(Concrete Creator)

    抽象产品角色(Product)

    具体产品角色(Concrete Product)

代码示例:

# 工厂方法模式
from abc import ABCMeta, abstractmethod

class Payment(metaclass=ABCMeta):   # 抽象产品角色
    # abc: abstract class
    @abstractmethod
    def pay(self,money):
        pass

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 BankPay(Payment):   # 具体产品角色
    def pay(self,money):
        print('银行卡支付%d元' % money)

class PaymentFactory(metaclass=ABCMeta):  # 抽象工厂角色
    @abstractmethod
    def creat_payment(self):
        pass

class AlipayFactory(PaymentFactory):   # 具体工厂角色
    def creat_payment(self):
        return Alipay()

class WechatpayFactory(PaymentFactory):   # 具体工厂角色
    def creat_payment(self):
        return WechatPay()

class HuabeiFactory(PaymentFactory):   # 具体工厂角色
    def creat_payment(self):
        return Alipay(use_huabei=True)

class BankPayFactory(PaymentFactory):   # 具体工厂角色
    def creat_payment(self):
        return BankPay()

# client (高层代码模块)
pf = HuabeiFactory()
p = pf.creat_payment()
p.pay(<
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值