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、行为类设计模式与设计原则

策略模式:符合开闭原则,但高层模块调用时,不符合迪米特法则。
行为类设计模式多少会符合些单一职责原则,典型的如观察者模式、中介者模式、访问者模式等;责任链模式:符合单一职责原则和迪米特法则;命令模式:符合开闭原则。在不同的业务逻辑中,不同的设计模式也会显示出不同的设计原则特点,从这个意义上来说,
设计模式是设计原则的体现,但体现不是固定的,是根据业务而有所不同的。

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

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

相关文章

二分查找(折半查找)探究学习

1.引入 当我们想要查找在一个数组中某一个特定的数它的下标是什么的时候&#xff0c;我们最先想的方法是遍历数组&#xff0c;如下&#xff1a; #include<stdio.h> #include<string.h> int main() { int arr[10]{1,2,3,4,5,6,7,8,9,10}; int key 8;//要找的数是8…

如何高效解析不定长度的协议帧

通信设计中考虑协议的灵活性&#xff0c;经常把协议设计成“不定长度”。一个实例如下图&#xff1a;锐米LoRa终端的通信协议帧。 如果一个系统接收上述“不定长度”的协议帧&#xff0c;将会有一个挑战--如何高效接收与解析。 为简化系统设计&#xff0c;我们强烈建议您采用“…

hql面试题之字符串使用split分割,并选择其中的一部分字段的问题

版本&#xff1a;20231109 1.题目&#xff1a; 有两张表,a表有id和abstringr两个字段&#xff0c;b表也有id和bstr两个字段&#xff0c;具体如下 A表&#xff1a; 1abc,bcd,cdf2123,456,789 B表: 1acddef2123456 在a表的abstring字段中用‘,’分割&#xff0c;并取出前两…

关于MySQL的66个问题

SQL基础掌握不错的小伙伴可以跳过这一部分。当然&#xff0c;可能会现场写一些SQL语句&#xff0c;SQ语句可以通过牛客、LeetCode、LintCode之类的网站来练习。 1. 什么是内连接、外连接、交叉连接、笛卡尔积呢&#xff1f; 内连接&#xff08;inner join&#xff09;&#xf…

05_MySQL主从复制架构

任务背景 ##一、真实案例 某同学刚入职公司&#xff0c;在熟悉公司业务环境的时候&#xff0c;发现他们的数据库架构是一主两从&#xff0c;但是两台从数据库和主库不同步。询问得知&#xff0c;已经好几个月不同步了&#xff0c;但是每天会全库备份主服务器上的数据到从服务…

k8s安装步骤

环境&#xff1a; 操作系统&#xff1a;win10 虚拟机&#xff1a;VMware linux发行版&#xff1a;CentOS7.9 CentOS镜像&#xff1a;CentOS-7-x86_64-DVD-2009 master和node节点通信的ip(master)&#xff1a; 192.168.29.164 0.检查配置 本次搭建的集群共三个节点&#xff0c;…

2023年【安全员-A证】考试题及安全员-A证最新解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 安全员-A证考试题考前必练&#xff01;安全生产模拟考试一点通每个月更新安全员-A证最新解析题目及答案&#xff01;多做几遍&#xff0c;其实通过安全员-A证模拟考试题很简单。 1、【多选题】下列关于高处作业吊篮叙…

【Redis基础】Redis基本的全局命令

✅作者简介&#xff1a;大家好&#xff0c;我是小杨 &#x1f4c3;个人主页&#xff1a;「小杨」的csdn博客 &#x1f433;希望大家多多支持&#x1f970;一起进步呀&#xff01; Redis基本的全局命令 1&#xff0c;KEYS命令 语法&#xff1a;KEYS pattern KEYS命令用来查询服…

C语言:输入10个整数,写一个函数将其中最小的数和第一个数对换,把最大的数和最后一个数对换。(指针)

分析&#xff1a; 定义三个函数&#xff1a;input、sort、print。其中&#xff0c;input 函数用于输入十个整数&#xff0c;sort 函数用于对这十个整数进行排序&#xff0c;print 函数用于输出排序后的十个整数。这三个函数都是 void 类型&#xff0c;即不返回任何值。 在主函数…

Python内置类属性`__name__`属性的使用教程

更多Python学习内容&#xff1a;ipengtao.com Python中的__name__是一种内置的特殊属性&#xff0c;通常用于判断模块是作为主程序运行还是作为模块被导入。本文将深入讲解__name__属性的用法&#xff0c;通过丰富的示例代码展示其在不同情景下的应用。 模块作为主程序运行 当一…

统信UOS_麒麟KYLINOS上使用远程SSH连接的工具electerm

原文链接&#xff1a;统信UOS/麒麟KYLINOS上使用SSH工具electerm Hello&#xff0c;大家好啊&#xff01;在我们日常的工作和学习中&#xff0c;远程控制和管理服务器已经成为一项常见且必要的技能。尤其是对于IT专业人士和开发者来说&#xff0c;一个高效、稳定的远程SSH连接工…

一款LED段码显示屏驱动芯片方案

一、基本概述 TM1620是一种LED&#xff08;发光二极管显示器&#xff09;驱动控制专用IC,内部集成有MCU数字接口、数据锁存器、LED驱动等电路。本产品质量可靠、稳定性好、抗干扰能力强。 二、基本特性 采用CMOS工艺 显示模式&#xff08;8段6位&#xff5e;10段4位&#xff…

模拟Spring源码思想,手写源码,理解@Component,@Value,@Autowired,@Qualifier四个注解

1、BeanDefinition package com.csdn.myspring; import lombok.AllArgsConstructor; import lombok.Data; Data AllArgsConstructor public class BeanDefinition {private String beanName;private Class beanClass; }2、扫描包的工具类MyTools package com.csdn.myspring; im…

排序算法基本原理及实现2

&#x1f4d1;打牌 &#xff1a; da pai ge的个人主页 &#x1f324;️个人专栏 &#xff1a; da pai ge的博客专栏 ☁️宝剑锋从磨砺出&#xff0c;梅花香自苦寒来 &#x1f324;️冒泡排序 &#x1…

简单位运算

文章目录 求 n n n 的第 k k k 位是二进制的几lowbit(n)操作求解 n n n 的最后一个 1 1 1题目练习AcWing 801. 二进制中1的个数CODE1 原码、补码、反码 求 n n n 的第 k k k 位是二进制的几 我们需要用到&运算符&#xff1a;两位都为 1 1 1 时结果才为 1 1 1 &…

题目标题:数字游戏(杨鼎强)

题目描述&#xff1a; 小明正在学习C语言程序设计&#xff0c;一天小明觉得无聊&#xff0c;便去找小刚玩&#xff0c;小刚给小明出了一道题&#xff0c;让小明输入一个五位以内的正整数&#xff0c;然后需要做到三件事。首先&#xff0c;判断输入的是几位数&#xff1b;然后&…

Linux小程序之进度条

> 作者简介&#xff1a;დ旧言~&#xff0c;目前大二&#xff0c;现在学习Java&#xff0c;c&#xff0c;c&#xff0c;Python等 > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 目标&#xff1a;自己能实现进度条 > 毒鸡汤&#xff1a; > …

制作心理咨询小程序的详细指南

随着科技的的发展&#xff0c;小程序已经成为了人们日常生活中不可或缺的一部分。特别是在心理咨询这个领域&#xff0c;小程序可以提供一个更为便捷、高效的服务平台。本文将通过乔拓云平台为例&#xff0c;详细介绍如何制作一个心理咨询小程序。 首先&#xff0c;我们需要注册…

【软件测试】盘一盘工作中遇到的 Redis 异常测试

在测试工作中&#xff0c;涉及到与 redis 交互的场景变的越来越多了。关于redis本身就不作赘述了&#xff0c;网上随便搜&#xff0c;本人也做过一些整理。 今天只来复盘一下&#xff0c;在测试过程中与 redis 的二三事儿。其中提到的案例是经过抽象化的&#xff0c;用作辅助说…

第十七章 其他-rpc、rabbitmq(如何对消息做持久化、如何控制消息被消费的顺序)、celery(应用场景、运行机制、如何实现定时任务)

Python基础、函数、模块、面向对象、网络和并发编程、数据库和缓存、 前端、django、Flask、tornado、api、git、爬虫、算法和数据结构、Linux、设计题、其他 第十七章 其他 1. 什么是rpc&#xff1f; RPC&#xff08;Remote Procedure Call&#xff0c;远程过程调用&#x…