【设计模式|中】结构型模式

every blog every motto: You can do more than you think.
https://blog.csdn.net/weixin_39190382?type=blog

0. 前言

【设计模式|上】【创建型】
【设计模式 | 中】【结构型】

  1. 适配器模式
  2. 代理模式
  3. 装饰器模式
  4. 桥接模式
  5. 组合模式
  6. 外观模式
  7. 享元模式

【设计模式 | 下】【行为型】

1. 正文

1.2 结构型

1.2.1 适配器模式(Adapter)

场景: 不改变接口的情况下,修改实现功能是实现方式

'''
Adapter
'''
#适配器模式
# 将一个类的接口转换成客户希望的另外一个接口。使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
# 应用场景:希望复用一些现存的类,但是接口又与复用环境要求不一致。def printInfo(info):print(info)#球员类
class Player():name = ''def __init__(self,name):self.name = namedef Attack(self,name):passdef Defense(self):pass#前锋
class Forwards(Player):def __init__(self,name):Player.__init__(self,name)def Attack(self):printInfo("前锋%s 进攻" % self.name)def Defense(self):printInfo("前锋%s 防守" % self.name)#中锋(目标类)
class Center(Player):def __init__(self,name):Player.__init__(self,name)def Attack(self):printInfo("中锋%s 进攻" % self.name)def Defense(self):printInfo("中锋%s 防守" % self.name)#后卫
class Guards(Player):def __init__(self,name):Player.__init__(self,name)def Attack(self):printInfo("后卫%s 进攻" % self.name)def Defense(self):printInfo("后卫%s 防守" % self.name)#外籍中锋(待适配类)
#中锋
class ForeignCenter(Player):name = ''def __init__(self,name):Player.__init__(self,name)def ForeignAttack(self):printInfo("外籍中锋%s 进攻" % self.name)def ForeignDefense(self):printInfo("外籍中锋%s 防守" % self.name)#翻译(适配类)
class Translator(Player):foreignCenter = Nonedef __init__(self,name):self.foreignCenter = ForeignCenter(name)def Attack(self):self.foreignCenter.ForeignAttack()def Defense(self):self.foreignCenter.ForeignDefense()def clientUI():b = Forwards('巴蒂尔')ym = Guards('姚明')m = Translator('麦克格雷迪')b.Attack()m.Defense()ym.Attack()b.Defense()returnif __name__ == '__main__':clientUI()

1.2.2 代理模式

场景: 不方便直接访问,需要中间过程作为过渡才能访问

 
'''
Proxy
'''# 代理模式
# 应用特性:需要在通信双方中间需要一些特殊的中间操作时引用,多加一个中间控制层。
# 结构特性:建立一个中间类,创建一个对象,接收一个对象,然后把两者联通起来class sender_base:def __init__(self):passdef send_something(self, something):passclass send_class(sender_base):def __init__(self, receiver):self.receiver = receiverdef send_something(self, something):print("SEND " + something + ' TO ' + self.receiver.name)class agent_class(sender_base):def __init__(self, receiver):self.send_obj = send_class(receiver)def send_something(self, something):self.send_obj.send_something(something)class receive_class:def __init__(self, someone):self.name = someoneif '__main__' == __name__:receiver = receive_class('Burgess')agent = agent_class(receiver)agent.send_something('agentinfo')print(receiver.__class__)print(agent.__class__)

1.2.3 装饰模式

 
'''
Decorator
'''class foo(object):def f1(self):print("original f1")def f2(self):print("original f2")class foo_decorator(object):def __init__(self, decoratee):self._decoratee = decorateedef f1(self):print("decorated f1")self._decoratee.f1()def __getattr__(self, name):return getattr(self._decoratee, name)u = foo()
v = foo_decorator(u)
v.f1()
v.f2()

1.2.4 桥模式(Bridge)

'''
Bridge
'''
class AbstractRoad(object):'''路基类'''car = Noneclass AbstractCar(object):'''车辆基类'''def run(self):raise NotImplementedErrorclass Street(AbstractRoad):'''市区街道'''def run(self):self.car.run()print("在市区街道上行驶")class SpeedWay(AbstractRoad):'''高速公路'''def run(self):self.car.run()print("在高速公路上行驶")class Car(AbstractCar):'''小汽车'''def run(self):print("小汽车在")class Bus(AbstractCar):'''公共汽车'''def run(self):print("公共汽车在")if __name__ == "__main__":#小汽车在高速上行驶road1 = SpeedWay()road1.car = Car()road1.run()#road2 = SpeedWay()road2.car = Bus()road2.run()road3 = Street()road3.car = Bus()road3.run()

1.2.5 组合模式(Composite)

"""
Composite
"""class Component:def __init__(self, strName):self.m_strName = strNamedef Add(self, com):passdef Display(self, nDepth):passclass Leaf(Component):def Add(self, com):print("leaf can't add")def Display(self, nDepth):strtemp = "-" * nDepthstrtemp = strtemp + self.m_strNameprint(strtemp)class Composite(Component):def __init__(self, strName):self.m_strName = strNameself.c = []def Add(self, com):self.c.append(com)def Display(self, nDepth):strtemp = "-" * nDepthstrtemp = strtemp + self.m_strNameprint(strtemp)for com in self.c:com.Display(nDepth + 2)if __name__ == "__main__":p = Composite("Wong")p.Add(Leaf("Lee"))p.Add(Leaf("Zhao"))p1 = Composite("Wu")p1.Add(Leaf("San"))p.Add(p1)p.Display(1)

1.2.6 外观模式(Facade)

'''
Facade外观模式(Facade),为子系统中的一组接口提供一个一致的界面,定义一个高层接口,这个接口使得这一子系统更加容易使用。
在以下情况下可以考虑使用外观模式:
(1)设计初期阶段,应该有意识的将不同层分离,层与层之间建立外观模式。
(2) 开发阶段,子系统越来越复杂,增加外观模式提供一个简单的调用接口。
(3) 维护一个大型遗留系统的时候,可能这个系统已经非常难以维护和扩展,但又包含非常重要的功能,为其开发一个外观类,以便新系统与其交互。优点编辑
(1)实现了子系统与客户端之间的松耦合关系。
(2)客户端屏蔽了子系统组件,减少了客户端所需处理的对象数目,并使得子系统使用起来更加容易。
'''def printInfo(info):print(info)class Stock():name = '股票'def buy(self):printInfo('买 '+self.name)def sell(self):printInfo('卖 '+self.name)class ETF():name = '指数型基金'def buy(self):printInfo('买 '+self.name)def sell(self):printInfo('卖 '+self.name)class Future():name = '期货'def buy(self):printInfo('买 '+self.name)def sell(self):printInfo('卖 '+self.name)class NationDebt():name = '国债'def buy(self):printInfo('买 '+self.name)def sell(self):printInfo('卖 '+self.name)class Option():name = '权证'def buy(self):printInfo('买 '+self.name)def sell(self):printInfo('卖 '+self.name)#基金
class Fund():def __init__(self):self.stock = Stock()self.etf = ETF()self.future = Future()self.debt = NationDebt()self.option = Option()def buyFund(self):self.stock.buy()self.etf.buy()self.debt.buy()self.future.buy()self.option.buy()def sellFund(self):self.stock.sell()self.etf.sell()self.future.sell()self.debt.sell()self.option.sell()def clientUI():myFund = Fund()myFund.buyFund()myFund.sellFund()returnif __name__ == '__main__':clientUI()

1.2.7 享元模式–Flyweight

'''
Flyweight
'''
class FlyweightBase(object):_instances = dict()  #皴法实例化的对象内存地址def __init__(self,*args,**kwargs):#继承的子类必须初始化raise NotImplementedErrordef __new__(cls, *args, **kwargs):print(cls._instances,type(cls))  #cls 就是你要实例化的子类如:obj = Spam(1,abc)return cls._instances.setdefault((cls,args,tuple(kwargs.items())), #key   (实例和参数)obj = Spam(y,x)super(FlyweightBase,cls).__new__(cls)  # value  #实例化新的对象的内存地址# 调用自身的_instances字典,如果没有往父类找_instances字典# setdefault:判断_instances字典是否有该key:obj = Spam(y,x)实例 ,#               如果有,返回该key的value(上次实例化对象(内存地址))# setdefault: 如果找不到key:obj = Spam(y,x)实例 ,就在_instances字典就创建该key,value为新实例化对象(内存地址)#               返回该新创建key的value(该次实例化的对象(内存地址)# 这也就说明你实例化对象的时候,如果形参相同的话,不用实例化,直接返回已存在的实例的内存))
class Spam(FlyweightBase):'''精子类'''def test_data(self):passdef __init__(self,a,b):self.a = aself.b = bdef test_data(self):print("精子准备好了",self.a,self.b)
class Egg(FlyweightBase):'''卵类'''def __init__(self,x,y):self.x = xself.y = ydef test_data(self):print("卵子准备好了",self.x,self.y)spam1 = Spam(1,'abc')
spam2 = Spam(1,'abc')
spam3 = Spam(3,'DEF')egg1 = Egg(1,'abc')
print(id(spam1),id(spam2),id(spam3))#egg2 = Egg(4,'abc')
# assert spam1 is spam2
# assert egg1 is not spam1
# print(id(spam1),id(spam2))
# spam2.test_data()
# egg1.test_data()
# print(egg1._instances)
# print(egg1._instances.keys())

[1] https://blog.csdn.net/hbu_pig/article/details/80509629
[2] https://zhuanlan.zhihu.com/p/92051694
[3] https://blog.csdn.net/weixin_41624982/article/details/86843476
[4] https://zhuanlan.zhihu.com/p/78985339
[5] https://www.jianshu.com/p/013985a58841
[6] https://blog.csdn.net/weixin_42234345/article/details/106992960
[7] https://blog.csdn.net/longyanbuhui/article/details/103781286
[8] https://blog.csdn.net/ericzhong83/article/details/7596420
[9] https://zhuanlan.zhihu.com/p/591820449
[10] https://blog.csdn.net/hbuxiaofei/article/details/106888178
[11] https://blog.csdn.net/hbuxiaofei/article/details/106875759
[12] https://zhuanlan.zhihu.com/p/56360529
[13] https://blog.csdn.net/qq_38923792/article/details/100920500
[14] https://blog.csdn.net/qq_29518275/article/details/119450806
[15] https://www.cnblogs.com/lifei01/p/13273970.html
[16] https://blog.csdn.net/hbu_pig/article/details/80568749

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/24129.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

6.s081/6.1810(Fall 2022)Lab3: page tables

文章目录 前言其他篇章参考链接0. 前置环境1. Speed up system calls (easy)1.1 简单分析1.2 映射1.3 页分配1.4 页释放1.5 测试 2. Print a page table (easy)2.1 简单分析2.2 实现2.3 测试 3. Detect which pages have been accessed (hard)3.1 简单分析3.2 实现3.2.1 获取参…

8.物联网操作系统之事件标志组

。事件标志组定义 FreeRTOS事件标志组介绍 FreeRTOS事件标志组工作原理 一。事件标志组定义 信号量信号量只能实现任务与单个事件或任务间的同步。但是某些任务可能会需要与多个事件或任务进行同步,此时就可以使用事件标志组来解决。事件标志组能够实现某个任务与…

Webpack5 动态导入按需加载

文章目录 一、 什么是动态导入和按需加载?二、 具体用法示例二、 总结 一、 什么是动态导入和按需加载? 传统上,在Webpack中,我们使用import语句可以在代码中静态地导入模块。这意味着所有的模块都会在构建时被打包到bundle中。然…

【PostgreSQL】系列之 一 用户创建和授权(三)

🍁 博主 "开着拖拉机回家"带您 Go to New World.✨🍁 🦄 个人主页——🎐开着拖拉机回家_Linux,Java基础学习,大数据运维-CSDN博客 🎐✨🍁 🪁🍁 希望本文能够给您带来一定的…

如何在 Android 上恢复已删除的视频|快速找回丢失的记忆

想知道是否有任何成功的方法可以从 Android 手机中检索已删除的视频?好吧,本指南将向您展示分步说明,让您轻松从手机中找回丢失的视频文件! 您是否不小心从 Android 智能手机中删除了珍贵的生日视频?难道是无处可寻吗…

前端监控概述

前端监控埋点概览 前端监控主要分为三类:数据监控、性能监控、异常监控 数据监控 记录上报产品在用户端的使用情况,以数据为导向,帮助团队做决策,数据监控有时也被称为行为监控,常见的包括: PV/UV&…

宝塔面板Mysql数据库无法启动(已解决)

1、错误排查 Mysql 无法正常启动直接使用官方提供的脚本检查出错 wget -O sql-repair.sh http://download.bt.cn/install/sql-repair.sh && sh sql-repair.shwget -O sql-repair.sh http://download.bt.cn/install/sql-repair.sh && sh sql-repair.sh 打印出…

LoadRunner

✏️作者:银河罐头 📋系列专栏:JavaEE 🌲“种一棵树最好的时间是十年前,其次是现在” 目录 LoadRunner 安装LoadRunner 三大组件之间的关系LoadRunner 脚本录制WebTours 系统 脚本加强事务插入插入集合点插入检查点参数…

增量式PID算法及其MATLAB实现

增量式PID算法是一种常用的控制算法,用于控制系统中的反馈控制。它通过对系统的误差进行递推式的计算,实现对系统输出的调节,使得系统的输出逐渐趋向于设定值。 delta u(k)=u(k)-u(k-1)=Kp*(e(k)-e(k-1))+Ki*e(k)+Kd*(e(k)-2*e(k-1)+e(k-2)) PID算法由三个部分组成:比例(…

Cat.1如何成为物联网业务加速器?

随着Cat.1芯片及模组在功耗和成本上的不断优化,在窄带物联网领域,越来越多的终端客户把Cat.1当做与NB-IoT相比较的第二选择。越来越多的表计、烟感、市政等行业终端将Cat.1模组应用于非集中化部署的上报类终端业务中,Cat.1这只“网红猫”仍保…

在 spark-sql / spark-shell / hive / beeline 中粘贴 sql、程序脚本时的常见错误

一个很小的问题,简单记录一下。有时候我们会粘贴一段已经成功运行过的SQL或程序脚本,但是在spark-sql / spark-shell / hive / beeline 中执行时可能会报这样的错误: hive> CREATE EXTERNAL TABLE IF NOT EXISTS ORDERS(> Display all…

基于vue医院分时段预约挂号系统java病历管理系统snsj0

伴随着我国社会的发展,人民生活质量日益提高。互联网逐步进入千家万户,改变传统的管理方式,医院病历管理系统以互联网为基础,利用java技术,和mysql数据库开发设计一套医院病历管理系统,提高工作效率的同时&…

点击表格行高亮

css中三元表达式 :class"[activeIndex index ? color : , item]"点击行高亮 <div click"actvied(index)" :class"[activeIndex index ? color : , item]"v-for"(item, index) in tableData" :key"index">{{ item…

[Linux]理解文件系统!动静态库详细制作使用!(缓冲区、inode、软硬链接、动静态库)

hello&#xff0c;大家好&#xff0c;这里是bang___bang_&#xff0c;今天来谈谈的文件系统知识&#xff0c;包含有缓冲区、inode、软硬链接、动静态库。本篇旨在分享记录知识&#xff0c;如有需要&#xff0c;希望能有所帮助。 目录 1️⃣缓冲区 &#x1f359;缓冲区的意义 …

Python(六十九)为什么要将元组设计成不可变序列

❤️ 专栏简介&#xff1a;本专栏记录了我个人从零开始学习Python编程的过程。在这个专栏中&#xff0c;我将分享我在学习Python的过程中的学习笔记、学习路线以及各个知识点。 ☀️ 专栏适用人群 &#xff1a;本专栏适用于希望学习Python编程的初学者和有一定编程基础的人。无…

nginx服务

目录 基本介绍 nginx的主要功能 nginx的主要应用场景 nginx常用命令 nginx另外一种安装方式 nginx常用的信号符&#xff1a; nginx配置文件详解 全局配置 event模块 http模块 server模块 location模块&#xff1a; 模块的划分 基本介绍 nginx&#xff1a;高性能、…

06 Ubuntu22.04上的miniconda3安装、深度学习常用环境配置

下载脚本 我依然是在清华镜像当中寻找的脚本。这里找脚本真的十分方便&#xff0c;我十分推荐。 wget https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda/Miniconda3-latest-Linux-x86_64.sh 下载十分快速&#xff0c;10秒解决问题 运行miniconda3安装脚本 赋予执…

python数据容器

目录 数据容器 反向索引 list列表 语法 案例 列表的特点 列表的下表索引 list的常用操作 list列表的遍历 while循环遍历 for循环遍历 tuple元组 前言 元组定义 元组特点 获取元组元素 元组的相关操作 元组的遍历 while循环遍历 for循环遍历 字符串 前言…

SpringBoot复习:(19)Condition接口和@Conditional注解

Condition接口代码如下&#xff1a; public interface Condition {boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);}它是一个函数式接口&#xff0c;只有一个方法matches用来表示条件是否满足。matches方法中的ConditionContext类对象context可以…

OPENCV C++(五)滤波函数+sobel边缘检测+人脸磨皮mask

滤波函数 中值滤波 medianBlur(frame, detectmat, 5); 平均滤波 blur(frame, detectmat, Size(5, 5)); 高斯滤波&#xff08;最后一个是方差 越大越模糊&#xff09; GaussianBlur(frame, detectmat, Size(5, 5),0); sobel的边缘检测函数 Sobel(gray, dx, CV_16S, 1, 0, 3…