社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

聊聊 Python 面试最常被问到的几种设计模式(下)

AirPython • 3 年前 • 215 次点击  

点击上方“AirPython”,选择“加为星标

第一时间关注 Python 技术干货!


1. 前言

上篇文章 写到了 Python 最常用的 2 种设计模式,单例模式和工厂模式

本篇文章我们继续聊聊面试中,Python 面试经常被问到的设计模式,即:

  • 构建者模式

  • 代理模式

  • 观察者模式

2. 构建者模式

构建者模式,是将一个复杂对象的构造与表现进行分离,利用多个步骤进行创建,同一个构建过程可用于创建多个不同的表现

简单来说,就是将一个复杂对象实例化的过程,按照自己的想法,一步步设置参数,定制一个我们需要的对象

构建者模式一般由 Director(指挥官)和 Builder(建设者)构成

其中:

Builder 用于定义目标对象部件的方法和参数

Director 用于构造一个 Builder 的接口,由 Director 去指导 Builder 生成一个复杂的对象

以购买一辆车( 含:准备钱、看车、试驾、购买 4 个步骤)为例

首先,定义一个车的实体,并定义属性变量

class Car(object):
    def __init__ (self):
        # 准备的钱
        self.money = None

        # 去哪里看车
        self.address = None

        # 试驾什么车
        self.car_name = None

        # 购买时间是
        self.buy_time = None

    def __str__(self):
        return "准备了:%s,去%s看车,试驾了%s,下单了,购买时间是:%s" % (self.money, self.address, self.car_name, self.buy_time)

然后,创建一个 Builder,实例化一个 Car 对象;针对上面 4 个步骤,通过定义 4 个方法

分别是:准备多少钱、去哪里看车、试驾什么车、下单购买的时间

# 创建者
class CarBuilder(object):
    def __init__(self):
        self.car = Car()

    def ready_money(self, money):
        """
        准备的金额
        :param money:
        :return:
        """

        self.car.money = money
        sleep(0.5)
        return self

    def see_car(self, address):
        """
        去哪里看车
        :param address:
        :return:
        """

        self.car.address = address
        sleep(0.5)
        return self

    def test_drive(self, car_name):
        """
        试驾了什么车
        :param car_name:
        :return:
        """

        self.car.car_name = car_name
        sleep(0.5)
        return self

     def buy_car(self, buy_time):
        """
        下单时间
        :param buy_time:
        :return:
        """

        self.car.buy_time = buy_time
        sleep(0.5)
        return self

接着,创建 Director,创建 build 方法,使用 Builder 一步步构建一个车对象并返回

class Director(object):
    def __init__(self):
        self.builder = None

    def build(self, builder):
        self.builder = builder
        self.builder. \
            ready_money("100万"). \
            see_car("4S店"). \
            test_drive("奥迪Q7"). \
            buy_car("2020年8月1日")

        # 返回构建的对象
        return self.builder.car

最后使用的时候,只需要实例化一个 Builder 对象和 Director 对象,然后通过 Director 对象构建一个车对象即可

if __name__ == '__main__':
    # 实例化一个构建者对象
    car_builder = CarBuilder()
    # 实例化一个负责人
    director = Director()

    # 构建的对象
    car = director.build(car_builder)

    print(car)

3. 代理模式

代理模式,会引入一个代理对象以代替真实的对象,解耦调用方和被调用方之间的联系
Python 中的实现方式也简单易懂
首先,我们定义一个真实对象实体类,并定义一个方法
class RealObject(object):
    """
    实际对象
    """

    def __init__(self, arg):
        self.arg = arg

    def foo(self):
        print('参数值为:', self.arg)
然后,创建一个代理对象,在初始化函数 __init__ 中拿到真实对象的实例,定义一个相同的方法,并调用真实对象的方法
class ProxyObject(object):
    """
    代理对象
    """

    def __init__(self, real_object):
        self.real_object = real_object

    def foo(self):
        # 实际对象调用
        self.real_object.foo()
最后的使用方式如下:
if __name__ == '__main__':
    # 实例化代理对象
    proxy_object = ProxyObject(RealObject('AirPython'))
    # 调用方法
    proxy_object.foo()
如此,就实现了代理替换真实对象的目的

4. 观察者模式

观察者模式在 Python 中很常见,会定义了对象之间的一对多依赖关系,当被观察者(也称为主体对象)改变状态时,其他所有观察者都会收到事件并处理预定的事情
首先,我们创建一个观察者,在初始化函数中注册到被观察对象上,并且自定义一个更新函数
# 观察者
class Observer(object):

    def __init__(self, subject):
        # 初始化观察者,并注册
        subject.register(self)

    def update(self, arg1):
        """获取通知"""
        print('观察者收到监听消息,参数为:', arg1)
然后,新建一个被观察对象,创建注册观察者、注销观察者方法
class Subject(object):

    def __init__(self):
        # 所有的观察者
        self.observers = []
        self.foo = None

    def register(self, observer):
        """添加观察者"""
        if observer not in self.observers:
            self.observers.append(observer)
        else:
            print('已经存在,添加失败!')

    def unregister(self, observer):
        """注销观察者"""
        try:
            self.observers.remove(observer)
        except ValueError:
            print('注销观察者失败')
接着,通过模拟修改变量的值,通知给所有的观察者
def notify(self):
    """通知所有的观察者"""
    for item in self.observers:
       item.update(self.foo)

def modify_value(self):
   """
   修改变量的值
   :return:
   """

   self.foo = "公众号:AirPython"

   # 修改后,通知所有观察者
   self.notify()
最后的使用方式如下:
if __name__ == '__main__':
    # 主体对象
    subject = Subject()
    # 观察者
    observer = Observer(subject)

    # 测试
    subject.modify_value()

5. 最后

这两篇一共介绍了 5 种设计模式,它们在 Python 的各领域中被广泛使用,也是面试中最常被问到的几种设计模式

我已经将文中全部源码上传到后台,关注公众号后回复「 设计模式 」即可获得全部源码

如果你觉得文章还不错,请大家 点赞、分享、留言下,因为这将是我持续输出更多优质文章的最强动力!



留言送书

本周赠书:《Python大数据与机器学习实战
PS:中奖名单将于下周一在交流群/朋友圈同步公布

本书致力于系统地阐释 Python 大数据和机器学习技术,从数据的采集、存储、清洗,到建立模型、统计分析,然后用前端程序呈现给用户数据展示以及后台的系统服务支持。本书结合了 Python 数据工具使用、算法原理以及典型实例各个层面,希望读者通过阅读本书,少走弯路,以最小的学习成本获得更大的知识收益。


程序员通过阅读本书可以学习大数据和机器学习行业的具体技能和方法;创业者和产品设计人员通过阅读本书可以了解数据建模的功能、涉及的技术点,从而更好地设计产品。



推荐阅读


聊聊 Python 面试最常被问到的几种设计模式

一篇文章带你用 Python 玩转 BDD

自动化篇 | 这些自动化场景,批处理脚本完全可以取代 Python!



Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/72500
 
215 次点击