Python与设计模式--设计原则
23种计模式之 前言 +(5)单例模式、工厂模式、简单工厂模式、抽象工厂模式、建造者模式、原型模式、+(7)代理模式、装饰器模式、适配器模式、门面模式、组合模式、享元模式、桥梁模式、+(11)策略模式、责任链模式、命令模式、中介者模式、模板模式、迭代器模式、访问者模式、观察者模式、解释器模式、备忘录模式、状态模式 + 设计原则
23-Python与设计模式–设计原则
一 六大设计原则
在法理学中,法律规则与法律原则都是法律规范的重要构成。但二者也会有些不同:法律规则是指采取一定的
结构形式具体规定人们的法律权利、法律义务以及相应的法律后果的行为规范,内容比较明确,比如,
交通法规中规定,禁止闯红灯;法律原则是指在一定法律体系中作为法律规则的指导思想,基本或本原的、
综合的、稳定的原理和准则,内容上只包含“大方针”,而并未有具体规则,比如,如果车上有马上临产的孕妇,
闯红灯不会被处罚,这是符合重视生命的原则。设计模式与设计原则,基本符合规则与原则的关系,
设计模式是一个个具体问题的解决方案,设计原则则反映了这些设计模式的指导思想;
同时,设计原则可衍生出的设计模式也不仅限于上述介绍到了23种设计模式,任何一种针对特定业务场景中的
解决方法,虽然找不到对应的设计模式与之匹配,但若符合设计原则,也可以认为是一种全新的设计模式。
从这个意义上来说,设计模式是程序设计方法的形,而设计原则是程序设计方法的神。
1、单一职责原则
单一职责原则英文原名为Single Responsibility Principle,简称SRP原则。
其含义为:应该有且仅有一个原因引起类的变更。举个例子来说明单一职责原则:一个视频播放系统,
一个客户端类有两个功能接口,即视频播放接口和音频播放接口。虽然这样的设计很常见,
但却不满足单一职责原则的。原因是,如果对视频播放有变更需求或者对音频播放有修改需求,
都会变更视频客户端的类结构。符合单一原则的设计是,将视频播放单元和音频播放单元各建一个类,
播放客户端继承两个类,构成客户端。单一职责原则的最大难点在于职责的划分,试想,以上划分是否是符合单一职责了?既是,也不是。
试想,如果将视频传输和音频传输的协议信息和数据信息区分开,为符合这种粒度的单一职责原则就必须要有
协议传输类和数据传输类的划分。如果接着细分,可能一个简单的小模块,都要设计非常多的类。
因此,单一职责原则粒度的选择,应该根据业务流程和人员分工来进行考虑。一些基本的划分,
似乎已经成了行业规范性的内容,比如,业务逻辑与用户信息管理的划分等。
2、里氏替换原则
里氏替换原则英文原名为Liskov Substitution Principle,简称LSP原则。
它是面向对象设计的最为基本原则之一。 里氏替换原则的含义为:任何基类可以出现的地方,
子类一定可以出现。 LSP是继承复用的基石,只有当子类可以替换掉基类,软件单位的功能不受到影响时,
基类才能真正被复用,子类也能够在基类的基础上增加新的行为。举例说明:对于一个鸟类,
可以衍生出麻雀、喜鹊、布谷等子类,这些子类都可继承鸟类的鸣叫、飞行、吃食等接口。
而对于一个鸡类,虽然它在生物学上属于鸟类,但它不会飞,那么符合LSP设计原则的情况下,
鸡就不应该是鸟的一个子类:在鸟类调用飞行接口的地方,鸡类并不能出现。如果鸡类要使用鸟类的接口,
应该使用关联关系,而不是继承关系。
3、依赖倒置原则
依赖倒置原则英文原名为Dependence Inversion Principle,简称DIP原则。
它的含义为:高层模块不应该依赖于低层模块,两者都应该依赖其抽象。抽象不应该依赖于细节,
细节应该依赖于抽象。我们将每个不可细分的逻辑叫作原子逻辑,原子逻辑组装,形成低层模块,
低层模块组装形成高层模块。依赖倒置原则的含义为,高层模块和低层模块都应该由各自的抽象模块派生而来,
同时接口设计应该依赖于抽象,而非具体模块。举个例子:司机与汽车是依赖的关系,司机可以有实习司机类、
老司机类等派生;汽车可以有轿车、SUV、卡车等派生类。如果司机中设计一个接口drive,汽车是其参数,
符合DIP设计原则的参数,应该是在基类司机类中,将基类汽车类作为参数,而司机的派生类中,
drive的参数同样应该为基类汽车类,而不应该是汽车类的任一个派生类。如果规定实习司机只能开轿车等
业务逻辑,应该在其接口中进行判断,而不应该将参数替换成子类轿车。
4、接口隔离原则
接口隔离原则英文原名为Interface Segregation Principle,简称ISP原则。
其含义为:类间的依赖关系不应该建立一个大的接口,而应该建立其最小的接口,
即客户端不应该依赖那些它不需要的接口。这里的接口的概念是非常重要的。从逻辑上来讲,
这里的接口可以指一些属性和方法的集合;
从业务上来讲,接口就可以指特定业务下的接口(如函数,URL调用等)。接口应该尽量小,
同时仅留给客户端必要的接口,弃用没有必要的接口。举例说明:如果要根据具体的数据,
生成饼图、直方图、表格,这个类该如何设计?如果将生成饼图、直方图、表格等“接口”
(这里的接口就是“操作”的集合的概念),写在一个类中,是不符合接口隔离原则的。
符合ISP原则的设计应该是设计三个类,每个类分别实现饼图、直方图、表格的绘制。接口隔离原则和单一职责原则一样,涉及到粒度的问题,解决粒度大小,同样依赖于具体的业务场景,
需要读者根据实践去权衡。
5、迪米特法则(最少知识原则)
迪米特法则(Law of Demeter)也叫最少知识原则,英文Least Knowledge Principle,简称LKP原则。
其含义为:一个对象应该对其它对象有最少的了解。举例说明:一个公司有多个部门,每个部门有多个员工,
如果公司CEO要下发通知给每个员工,是调用接口直接通知所有员工么?其实不然,CEO只需和它的“朋友”类部门
Leader交流就好,部门Leader再下发通知信息即可。而CEO类不需要与员工进行“交流”。
迪米特法则要求对象应该仅对自己的朋友类交流,而不应该对非朋友类交流。那什么才是朋友类呢?一般来说,
朋友类具有以下特征:
1)当前对象本身(self);
2)以参量形式传入到当前对象方法中的对象;
3)当前对象的实例变量直接引用的对象;
4)当前对象的实例变量如果是一个聚集,那么聚集中的元素也都是朋友;
5)当前对象所创建的对象。
6、开闭原则
开闭原则英文原名为Open Closed Principle,简称OCP原则。其含义为:一个软件实体,
如类、模块、函数等,应该对扩展开放,对修改关闭。开闭原则是非常基础的一个原则,
也有人把开闭原则称为“原则的原则”。前面讲到过,模块分原子模块,低层模块,高层模块,
业务层可以认为是最高层次的模块。对扩展开放,意味着模块的行为是可以扩展的,当高层模块需求改变时,
我们可以对低层模块进行扩展,使其具有满足高层模块的新功能;对修改关闭,即对低层模块行为进行扩展时,
不必改动模块的源代码。最理想的情况是,业务变动时,仅修改业务代码,不修改依赖的模块(类、函数等)
代码,通过扩展依赖的模块单元来实现业务变化。举例说明:假设一个原始基类水果类,苹果类是它的派生类,
苹果中包含水果的各种属性,如形状、颜色等;另有两个类,农民类和花园类,最高层次(业务层次)为农民
在花园种苹果。如果此时,农民决定不种苹果了,改种梨,符合OCP原则的设计应该为基于水果类构建一个
新的类,即梨类(对扩展开放),而并不应该去修改苹果类,使它成为一个梨类(对修改关闭)。
修改应仅在最高层,即业务层中进行。
二 遵循设计原则的好处
由于设计原则是设计模式的提炼,因而设计原则的好处与设计模式是一致的,
即:代码易于理解;更适于团体合作;适应需求变化等。
三、设计原则与设计模式
1、创建类设计模式与设计原则
工厂模式:工厂方法模式是一种解耦结构,工厂类只需要知道抽象产品类,符合最少知识原则(迪米特法则);
同时符合依赖倒置原则和里氏替换原则;抽象工厂模式:抽象工厂模式具有工厂模式的优点,但同时,如果产品族要扩展,工厂类也要修改,
违反了开闭原则;模板模式:优秀的扩展能力符合开闭原则。
2、结构类设计模式与设计原则
代理模式:代理模式在业务逻辑中将对主体对象的操作进行封装,合适的应用会符合开闭原则和单一职责原则;事实上,几乎带有解耦作用的结构类设计模式都多少符合些开闭原则;门面模式:门面模式不符合开闭原则,有时不符合单一职责原则,如若不注意,也会触碰接口隔离原则;组合模式:符合开闭原则,但由于一般在拼接树时使用实现类,故不符合依赖倒置原则;桥梁模式:桥梁模式堪称依赖倒置原则的典范,同时也符合开闭原则。
3、行为类设计模式与设计原则
策略模式:符合开闭原则,但高层模块调用时,不符合迪米特法则。
行为类设计模式多少会符合些单一职责原则,典型的如观察者模式、中介者模式、访问者模式等;责任链模式:符合单一职责原则和迪米特法则;命令模式:符合开闭原则。在不同的业务逻辑中,不同的设计模式也会显示出不同的设计原则特点,从这个意义上来说,
设计模式是设计原则的体现,但体现不是固定的,是根据业务而有所不同的。
相关文章:
Python与设计模式--设计原则
23种计模式之 前言 (5)单例模式、工厂模式、简单工厂模式、抽象工厂模式、建造者模式、原型模式、(7)代理模式、装饰器模式、适配器模式、门面模式、组合模式、享元模式、桥梁模式、(11)策略模式、责任链模式、命令模式、中介者模…...
Spire.Office 8.11.2 for NET fix Crack
内容摘自来自互联网------或者SDK官方本身手册 Spire.Doc for .NET A professional Word .NET library designed to create, read, write, convert and print Word document files in any .NET ( C#, VB.NET, ASP.NET, .NET Core, Xamarin ) application with fast and high qu…...
ubuntu终端代理配置
ubuntu浏览器的无需手动设置,主要解决在终端中的配置问题,按照下面配置后可能会ping不通一些ip,但wget/git都是可以的,具体原因以后再分析 查找端口 首先要找到自己代理对应的HTTP端口,以QV2ray软件作为示例,我为8889 手动配置 # 配置系统proxy export http_proxy=1…...
postgresql从入门到精通 - 第35讲:中间件PgBouncer部署|PostgreSQL教程
PostgreSQL从小白到专家,是从入门逐渐能力提升的一个系列教程,内容包括对PG基础的认知、包括安装使用、包括角色权限、包括维护管理、、等内容,希望对热爱PG、学习PG的同学们有帮助,欢迎持续关注CUUG PG技术大讲堂。 第35讲&#…...
因为jsp for循环的一个空格引起的错误
<c:forEach items"${user.role} " var"role"> <c:forEach items"${user.role}" var"role"> 去掉空格正确显示 ,为此排查了2个小时代码逻辑...
文件中找TopK问题
目录 1.解题思路2.创建一个文件并在文件中写入数据3.为什么要建立小堆而不建立大堆?4.如何在现有的数据中建立适合的大堆?5.代码实现 1.解题思路 TopK问题即是在众多数据中找出前K大的值,则可以根据堆的性质来实现,但在使用堆之前…...
React 入门使用 (官方文档向 Part2)
文章目录 用 State 响应输入声明式地考虑 UI步骤 1:定位组件中不同的视图状态步骤 2:确定是什么触发了这些状态的改变步骤 3:通过 useState 表示内存中的 state步骤 4:删除任何不必要的 state 变量步骤 5:连接事件处理…...
vue运用之el-cascader组件
前言 el-cascader 是 Element UI 的级联选择器组件。以下是一些常见的 el-cascader 问题以及对应的案例代码。 1. 如何使用 el-cascader 创建一个级联选择器 以下是一个简单的 el-cascader 示例: <template> <el-cascader v-model="selected" :option…...
layui提示框没有渲染bug解决
bug:使用layui时或许是依赖导入又或是ideal和浏览器缓存问题导致前面明明正常的页面显示,后面出现提示框没有css样式,弹出框没有背景css 效果如下 解决后 解决方法 在你的代码中引入layer.js 我这是jsp页面 <script type"text/jav…...
MATLAB和S7-1200PLC水箱液位高度PID控制联合仿真(MODBUSTCP通信)
MATLAB和SMART 200PLC的联合仿真请查看下面文章链接 MATLAB Simulink和SMART PLC水箱液位高度PID控制(联合仿真)-CSDN博客文章浏览阅读606次。SMART PLC 向导PID的详细介绍请查看下面文章链接:S7-200 SMART PLC PID向导详细介绍(如何实现P、PD、PID控制器)-CSDN博客文章浏览阅…...
QT 项目中添加文件夹(分类文件)
为了更方便的整理项目的文件,添加文件夹把文件进行分类。 1.首先在项目文件中创建新的文件夹 2.把需要归类的文件放入新建的文件中 3.右键然后选择add..... 4.运行此程序,会报错因为文件路径改变了,需要在.pro中修改路径 注意事项 文件夹内部…...
vue3 语音播报流程
npm 安装 "speak-tts": "^2.0.8", npm install speak-tts 在vue文件中引用 import Speech from "speak-tts"; const speech ref(null);onMounted(() > {speechInit(); });//语音播报初始化 const speechInit () > {speech.value ne…...
Linux MTR(My TraceRoute)command
Internet上有许多小型网络测试工具:Ping、Traceroute、Dig、Host等。 但是,这些工具的功能都比较单一。今天会给大家分享一个包含ping和traceroute功能的工具:MTR 文章目录 什么是MTR?MTR可以提供哪些功能Linux MTR可用选项Linux MTR用法推荐…...
第十一章 python基础之api
Python基础、函数、模块、面向对象、网络和并发编程、数据库和缓存、 前端、django、Flask、tornado、api、git、爬虫、算法和数据结构、Linux、设计题、客观题、其他 第十一章 api 1. 什么是webservice? Web服务(Web Services)是一种通过网…...
redis运维(十六) 有序集合
一 有序集合 把握一点: 各种redis 命令都提供各种语言对应的API 接口,后续API是关键 ① 概念 1、sorted set --> 有序集合2、redis有序集合也是集合类型的一部分,所以它保留了集合中元素不能重复的特性3、但是不同的是,有序集合给每个元素多设置…...
深入理解RC4加密算法
RC4(Rivest Cipher 4)是一种广泛应用的加密算法,由Ronald L. Rivest于1987年发明。它是一种流密码(stream cipher)算法,适用于对网络通信中的数据进行加密保护。 RC4加密解密 -- 一个覆盖广泛主题工具的高…...
sql24(Leetcode1141查询近30天活跃用户数)
代码: # Write your MySQL query statement belowselect v.activity_date as day, count(distinct(v.user_id)) as active_users from(select user_id,activity_datefrom Activitywhere activity_date between 2019-06-28 and 2019-07-27 ) as v group by v.activi…...
python爬取robomaster论坛数据,作为后端数据
一. 内容简介 python爬取robomaster论坛数据,作为后端数据 二. 软件环境 2.1vsCode 2.2Anaconda version: conda 22.9.0 2.3代码 三.主要流程 3.1 接口分析 # 接口分析 # 全部数据 # https://bbs.robomaster.com/forum.php?modforumdisplay&fid63 2…...
C++: string的模拟实现
C: string的模拟实现 一.前置说明1.模拟实现string容器的目的2.我们要实现的大致框架 二.默认成员函数1.构造函数2.拷贝构造函数1.传统写法2.现代写法 3.析构函数4.赋值运算符重载1.传统写法2.现代写法 三.遍历和访问1.operator[]运算符重载2.iterator迭代器 四.容量相关函数1.…...
[安洵杯 2019]easy_web
打开环境 img传参还有cmd img应该是base,先解码看看 3535352e706e67 这个好像是十六进制的,再解 访问一下看看,得到一张图片 尝试base解码,但是没有什么发现 再看看地址栏出现index.php,应该是要下载源码,但是还没有…...
.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
ssc377d修改flash分区大小
1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...
高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...
页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...
【算法训练营Day07】字符串part1
文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接:344. 反转字符串 双指针法,两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...
[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...
Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...
k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...
【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...
laravel8+vue3.0+element-plus搭建方法
创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...
