当前位置: 首页 > news >正文

Python 设计模式(第2版) -- 第二部分(结构型模式)

Python 设计模式(第2版)

然后介绍下结构型设计模式。

下面是一些结构型设计模式的例子:

  • 适配器模式:将一个接口转换成客户希望的另外一个接口。它试图根据客户端的需求来匹配不同类的接口。
  • 桥接模式:该模式将对象的接口与其实现进行解耦,使得两者可以独立工作。
  • 装饰器模式:该模式允许在运行时或以动态方式为对象添加职责。我们可以通过接口给对象添加某些属性。

门面模式 – 与门面相适

门面在隐藏内部系统复杂性的同时,为客户端提供了一个接口,以便它们可以非常轻松地访问系统。

假设要在家中举行一场婚礼,必须预订一家酒店或场地,与餐饮人员交代酒菜、布置场景,并安排背景音乐,下面我们从门面模式的角度来看待这些事情。

  • 客户端:需要在婚礼前及时完成所有的准备工作。每一项安排都应该是顶级的,这样客人才会喜欢这些庆祝活动。
  • 门面:会务经理负责与所有相关人员进行交涉,这些人员负责处理食物、花卉装饰等。
  • 子系统:它们代表提供餐饮、酒店管理和花卉装饰等服务的系统。

EventManager 扮演了门面的角色。Hotelier 类用于预订酒店。它有一个方法,用于检查当天是否有免费的酒店(__isAvailable)。Florist 类负责花卉装饰。这个类提供了 setFlowerRequirements() 方法,用于指定要使用哪些种类的花卉来装饰婚礼。Caterer 类用于跟备办宴席者打交道,并负责安排餐饮。Caterer 提供了一个公开的 setCuisine() 法,用来指定婚宴的菜肴类型。 Musician 类用来安排婚礼的音乐,它使用 setMusicType() 方法来了解会务的音乐要求。

class EventManager(object):def __init__(self):print("Event Manager:: Let me talk to the folks\n")def arrange(self):self.hotelier = Hotelier()self.hotelier.bookHotel()self.florist = Florist()self.florist.setFlowerRequirements()self.caterer = Caterer()self.caterer.setCuisine()self.musician = Musician()self.musician.setMusicType()class Hotelier(object):def __init__(self):print("Arranging the Hotel for Marriage? --")def __isAvailable(self):print("Is the Hotel free for the event on given day? ")return Truedef bookHotel(self):if self. __isAvailable():print("Registered the Booking\n\n")class Florist(object):def __init__(self):print("Flower Decorations for the Event? --")def setFlowerRequirements(self):print("Carnations, Roses and Lilies would be used for Decorations\n\n")class Caterer(object):def __init__(self):print("Food Arrangements for the Event --")def setCuisine(self):print("Chinese & Continental Cuisine to be served\n\n")class Musician(object):def __init__(self):print("Musical Arrangements for the Marriage --")def setMusicType(self):print("Jazz and Classical will be played\n\n")class You(object):def __init__(self):print("You:: Whoa! Marriage Arrangements? ? ! ! ! ")def askEventManager(self):print("You:: Let's Contact the Event Manager\n\n")em = EventManager()em.arrange()def __del__(self):print("You:: Thanks to Event Manager, all preparations done! Phew! ")you = You()
you.askEventManager()

代理模式 – 控制对象访问

代理通常就是一个介于寻求方和提供方之间的中介系统。寻求方是发出请求的一方,而提供方则是根据请求提供资源的一方。

先通过一个简单的例子来理解该模式。不妨以演员与他的经纪人为例,当制作公司想要找演员拍电影时,他们通常会与经纪人交流,而不是直接跟演员交流。

其中 Actor 是代理。对象 Agent 用于查看 Actor 是否正处于忙碌状态。如果 Actor 正忙,则调用 Actor().occupied() 方法;如果 Actor 不忙,则返回 Actor().available() 方法。

class Actor(object):def __init__(self):self.isBusy = Falsedef occupied(self):self.isBusy = Trueprint(type(self). __name__ , "is occupied with current movie")def available(self):self.isBusy = Falseprint(type(self). __name__ , "is free for the movie")def getStatus(self):return self.isBusyclass Agent(object):def __init__(self):self.principal = Nonedef work(self):self.actor = Actor()if self.actor.getStatus():self.actor.occupied()else:self.actor.available()if __name__ == '__main__':r = Agent()r.work()

代理设计模式主要完成了以下工作。

  • 它为其他对象提供了一个代理,从而实现了对原始对象的访问控制。
  • 它可以用作一个层或接口,以支持分布式访问。
  • 它通过增加代理,保护真正的组件不受意外的影响。

这里将通过付款用例来展示代理模式的现实应用场景。假设,你在商场溜达,看中了一件漂亮的牛仔衫。你想买这件衬衫,但手里的现金却不够了。这要是在不久以前,你可以去 ATM 取钱,然后来到商场付款。在更早的时候,通常使用的是银行支票,这样你就必须去银行提款,然后再回商场付款。得益于银行业务的发展,后来出现了一种称为借记卡的东西。所以现在,你买东西的时候,只要在商家刷一下借记卡,这笔钱就会划入商家的账户,从而完成支付。

行为由类 You(即客户端)来表示。该类提供了 make_payment() 方法。主题是 Payment 类。它是一个抽象基类,代表一个接口。具有一个 do_pay() 方法,该方法需要借助代理和真实主题来实现。

Bank 类提供了多个方法来处理付款。代理使用 setCard() 方法将借记卡详细信息发送给银行。由 Bank 类(通过 Payment 接口)实现的 do_pay() 方法实际上负责根据可用资金向商家付款。

DebitCard 类是此处的代理。当你想要付款时,它会调用 do_pay() 方法。DebitCard 类充当真实主题(银行)的代理。

from abc import ABCMeta, abstractmethodclass Payment(metaclass=ABCMeta):@abstractmethoddef do_pay(self):passclass Bank(Payment):def __init__(self):self.card = Noneself.account = Nonedef __getAccount(self):self.account = self.card # Assume card number is account numberreturn self.accountdef __hasFunds(self):print("Bank:: Checking if Account", self. __getAccount(), "has enough funds")return Truedef setCard(self, card):self.card = carddef do_pay(self):if self. __hasFunds():print("Bank:: Paying the merchant")return Trueelse:print("Bank:: Sorry, not enough funds! ")return Falseclass DebitCard(Payment):def __init__(self):self.bank = Bank()def do_pay(self):card = input("Proxy:: Punch in Card Number: ")self.bank.setCard(card)return self.bank.do_pay()class You:def __init__(self):print("You:: Lets buy the Denim shirt")self.debitCard = DebitCard()self.isPurchased = Nonedef make_payment(self):self.isPurchased = self.debitCard.do_pay()def __del__(self):if self.isPurchased:print("You:: Wow! Denim shirt is Mine :-)")else:print("You:: I should earn more :(")you = You()
you.make_payment()

代理模式的优点:

  • 代理可以通过缓存笨重的对象或频繁访问的对象来提高应用程序的性能。
  • 代理还提供对于真实主题的访问授权。因此,只有提供合适权限的情况下,这个模式才会接受委派。
  • 远程代理还便于与可用作网络连接和数据库连接的远程服务器进行交互,并可用于监视系统。

门面模式和代理模式的比较

代理模式门面模式
为其他对象提供了代理或占位符,以控制对原始对象的访问为类的大型子系统提供了一个接口
代理对象具有与其目标对象相同的接口,并保存有目标对象的引用实现了子系统之间的通信和依赖性的最小化
充当客户端和被封装的对象之间的中介门面对象提供了单一的简单接口

相关文章:

  • Java启动jar设置内存分配详解
  • JWT整合Gateway实现鉴权(RSA与公私密钥工具类)
  • 示例:WPF中DataGrid简单设置合并列头
  • 数据结构和算法之复杂度比较
  • 数据治理:如何通过优化数据提取流程提高数据分析效果
  • 使用 Python 中的美丽汤进行网络数据解析的完整指南
  • python从入门到精通6:变量类型
  • ES6数组新增API
  • Jenkins简要说明
  • uniapp中u-input点击事件失效
  • 流媒体传输协议HTTP-FLV、WebSocket-FLV、HTTP-TS 和 WebSocket-TS的详细介绍、应用场景及对比
  • 高通Android13 WIFI配置国家码
  • 汇聚荣做拼多多口碑怎么样?
  • FLEXPART拉格朗日粒子扩散模式建模技术及研究大气污染物源-汇关系
  • CheckPoint 防火墙 CVE-2024-24919 VPN 漏洞修复说明
  • ComponentOne 2017 V2版本正式发布
  • ES6 学习笔记(一)let,const和解构赋值
  • Java Agent 学习笔记
  • JavaScript标准库系列——Math对象和Date对象(二)
  • oschina
  • SpringBoot 实战 (三) | 配置文件详解
  • spring学习第二天
  • 半理解系列--Promise的进化史
  • 从伪并行的 Python 多线程说起
  • 记一次删除Git记录中的大文件的过程
  • 精益 React 学习指南 (Lean React)- 1.5 React 与 DOM
  • 可能是历史上最全的CC0版权可以免费商用的图片网站
  • 入手阿里云新服务器的部署NODE
  • 项目实战-Api的解决方案
  • 学习笔记:对象,原型和继承(1)
  • 一、python与pycharm的安装
  • 原生 js 实现移动端 Touch 滑动反弹
  • LevelDB 入门 —— 全面了解 LevelDB 的功能特性
  • 浅谈sql中的in与not in,exists与not exists的区别
  • 树莓派用上kodexplorer也能玩成私有网盘
  • 资深实践篇 | 基于Kubernetes 1.61的Kubernetes Scheduler 调度详解 ...
  • ​​​【收录 Hello 算法】9.4 小结
  • ​批处理文件中的errorlevel用法
  • #FPGA(基础知识)
  • #stm32整理(一)flash读写
  • #window11设置系统变量#
  • #微信小程序:微信小程序常见的配置传旨
  • (11)工业界推荐系统-小红书推荐场景及内部实践【粗排三塔模型】
  • (2)关于RabbitMq 的 Topic Exchange 主题交换机
  • (2022 CVPR) Unbiased Teacher v2
  • (c语言版)滑动窗口 给定一个字符串,只包含字母和数字,按要求找出字符串中的最长(连续)子串的长度
  • (第30天)二叉树阶段总结
  • (翻译)terry crowley: 写给程序员
  • (附源码)springboot车辆管理系统 毕业设计 031034
  • (附源码)springboot炼糖厂地磅全自动控制系统 毕业设计 341357
  • (经验分享)作为一名普通本科计算机专业学生,我大学四年到底走了多少弯路
  • (转)平衡树
  • (转载)hibernate缓存
  • ./configure、make、make install 命令
  • .a文件和.so文件