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,应该是要下载源码,但是还没有…...

IDEA运行Tomcat出现乱码问题解决汇总
最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…...

龙虎榜——20250610
上证指数放量收阴线,个股多数下跌,盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型,指数短线有调整的需求,大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的:御银股份、雄帝科技 驱动…...

《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)
CSI-2 协议详细解析 (一) 1. CSI-2层定义(CSI-2 Layer Definitions) 分层结构 :CSI-2协议分为6层: 物理层(PHY Layer) : 定义电气特性、时钟机制和传输介质(导线&#…...
2024年赣州旅游投资集团社会招聘笔试真
2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...

家政维修平台实战20:权限设计
目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色…...

苍穹外卖--缓存菜品
1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据,减少数据库查询操作。 缓存逻辑分析: ①每个分类下的菜品保持一份缓存数据…...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)
目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关࿰…...

【分享】推荐一些办公小工具
1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由:大部分的转换软件需要收费,要么功能不齐全,而开会员又用不了几次浪费钱,借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...
Go语言多线程问题
打印零与奇偶数(leetcode 1116) 方法1:使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...