设计模式之禅《一》 大旗不挥,谁敢冲锋 ——6大设计原则

article/2025/8/22 15:41:56

设计模式之禅《一》大旗不挥,谁敢冲锋 ——6大设计原则

《一》 六大原则

一:单一职责原则

1、单一职责原则最难划分的就是职责

2、有两个可以变化的原因放到了一个接口中,这就为以后的变化带来了风险。

3、对于单一职责原则,我的建议是接口一定要做到单一职责,类的设计尽量做到只有一个原因引起变化。

禅:不同对象对同一个接口进行调用时,如果其中的某个方法产生不同的实现就应该把他抽离出来形成以自己为中心的新的职责。创建自己的接口时职责一定要清晰清晰!,单一,不要让别人猜测这个方法可能是用来处理什么逻辑的。

二:里氏替换原则

里氏替换原则,父类出现的地方子类就可以出现

1.子类必须完全实现父类的方法

2.子类可以有自己的个性

3.覆盖或实现父类的方法时输入参数可以被放大

4.覆写或实现父类的方法时输出结果可以被缩小

禅:程序的健壮性和兼容性(在实际项目中,每个子类对应不同的业务含义,使用父类作为参数,传递不同的子类完成不同的业务逻辑)在项目中,采用里氏替换原则时,尽量避免子类的“个性”,一旦子类有“个性”,这个子类和父类之间的关系就很难调和了,把子类当做父类使用,子类的“个性”被抹杀——委屈了 点;把子类单独作为一个业务来使用,则会让代码间的耦合关系变得扑朔迷离——缺乏类替换的标准。

三:依赖倒置原则 (适用于10人以上开发团队的大项目开发)

● 模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系是通过接口或抽象类产生的;

● 接口或抽象类不依赖于实现类;

● 实现类依赖接口或抽象类。

要协作就要并行开发,要并行开发就要解决模块之间的项目依赖关系,依赖倒置原则!

//我们只需要一个ICar的接口,就可以对Driver类进行单元测试。
public class DriverTest extends TestCase {Mockery context = new JUnit4Mockery (); @Testpublic void testDriver( ){//根据接口虚拟一个对象final ICar car = context.mock(ICar.class) ;IDriver driver = new Driver () ;//内部类context.checking ( new Expectations ( ) { {oneof(car).run() ;} });driver.drive(car) ;}
}

只要做到抽象依赖,即使是多层的依赖传递也无所畏惧

1.构造函数传递依赖对象

2.-Setter方法传递依赖对象

3.接口声明依赖对象

禅:

● 每个类尽量都有接口或抽象类,或者抽象类和接口两者都具备

● 变量的表面类型尽量是接口或者是抽象类

● 任何类都不应该从具体类派生

● 尽量不要覆写基类的方法

● 结合里氏替换原则使用 (P-62)

四:接口隔离原则

● 接口要尽量小 根据接口隔离原则拆分接口时,首先必须满足单一职责原则。

● 接口要高内聚

具体到接口隔离原则就是,要求在接口中尽量少公布public方法,接口是对外的承诺,承诺越少对系统的开发越有利,变更的风险也就越少,同时也有利于降低成本。

● 定制服务

在这里插入图片描述

● 接口设计是有限度的

禅:

● 一个接口只服务于一个子模块或业务逻辑;

● 通过业务逻辑压缩接口中的public方法,接口时常去回顾,尽量让接口达到“满身筋骨肉”,而不是“肥嘟嘟”的一大堆方法;

● 已经被污染了的接口,尽量去修改,若变更的风险较大,则采用适配器模式进行转化处理;

● 了解环境,拒绝盲从。每个项目或产品都有特定的环境因素,别看到大师是这样做的你就照抄。千万别,环境不同,接口拆分的标准就不同。深入了解业务逻辑,最好的接口设计就出自你的手中!

五:迪米特法则

一个对象应该对其他对象有最少的了解

如果一个方法放在本类中,既不增加类间关系,也对本类不产生负面影响,那就放置在本类中。

禅:迪米特法则的核心观念就是类间解耦,弱耦合,只有弱耦合了以后,类的复用率才可以提高。

迪米特法则要求类“羞涩”一点,尽量不要对外公布太多的public方法和非静态的public变量,尽量内敛,多使用private、package-private、protected等访问权限。

六:开闭原则

软件实体应该对扩展开放,对修改关闭 ,其含义是说一个软件实体应该通过扩展来实现变化,而不是通过修改已有的代码来实现变化。

通过扩展实现变化

增加一个子类OffNovelBook,覆写getPrice方法,高层次的模块(也就是static静态模块区)通过OffNovelBook类产生新的对象,完成业务变化对系统的最小化开发。好办法,修改也少,风险也小,

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PRNstxo3-1648892415801)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220402171059152.png)]

项目开发、重构、测试、投产、运维,其中的重构可以对原有的设计和代码进行修改,运维尽量减少对原有代码的修改,保持历史代码的纯洁性,提高系统的稳定性。在面向对象的设计中,所有的逻辑都是从原子逻辑组合而来的,而不是在一个类中独立实现一个业务逻辑。只有这样代码才可以复用,粒度越小,被复用的可能性就越大

优势

1、开闭原则减轻测试压力

2、开闭原则可以提高复用性

3、开闭原则可以提高可维护性

4、开闭原则符合面向对象开发的要求

食用方式

1、抽象约束

第一,通过接口或抽象类约束扩展,对扩展进行边界限定,不允许出现在接口或抽象类中不存在的public方法;

第二,参数类型、引用对象尽量使用接口或者抽象类,而不是实现类;

第三,抽象层尽量保持稳定,一旦确定即不允许修改。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A9AHIHSg-1648892415802)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220402172755287.png)]

2、 元数据(metadata)控制模块行为

@ 什么是元数据(metadata)控制模块行为?

先检查IP地址是否在允许访问的列表中,然后再决定是否需要到数据库中验证密码(如果采用SSH架构,则可以通过Struts的拦截器来实现),该行为就是一个。典型的元数据控制模块行为的例子,其中达到极致的就是控制反转。

3、制定项目章程

4、封装变化

@ 什么是封装变化 ?

也就是受保护的变化(protected variations),找出预计有变化或不稳定的点,我们为这些变化点创建稳定的接口,准确地讲是封装可能发生的变化,一旦预测到或“第六感”发觉有变化,就可以进行封装。

第一,将相同的变化封装到一个接口或抽象类中;

第二,将不同的变化封装到不同的接口或抽象类中,不应该有两个不同的变化出现在同一个接口或 抽象类中。

禅:

● Single Responsibility Principle:单一职责原则

● Open Closed Principle:开闭原则

● Liskov Substitution Principle:里氏替换原则

● Law of Demeter:迪米特法则

● Interface Segregation Principle:接口隔离原则

● Dependence Inversion Principle:依赖倒置原则


http://chatgpt.dhexx.cn/article/jqQ1sxyG.shtml

相关文章

设计模式之禅(六大设计原则)

1.单一职责原则(Single Responsibility Principle) 也就是职责划分要明确,单一职责原则提出了一个编写程序的标准,用“职责”或者“变化原因”来衡量接口或者类设计的是否优良,但是“职责”或者“变化原因”都是不可度量的,因项目…

什么是ASCII码

ASCII码英文全称America Standard Code for Information Interchange,中文意思:美国信息交换标准码。它已被国际标准化组织(ISO)定为国际标准,称为ISO 646标准。适用于所有拉丁文字字母,ASCII码有7位码和8位…

最全ASCii 码表和说明

A的ASCII码是65,a的ASCII码是97。 ASCII码表中,小写字母排在大写字母的后面,一个字母的大小写数值相差32,一般知道大写字母的ASCII码数值,其对应的小写字母的ASCII码数值就算出来了,是大写字母的ASCII码数…

ASCII码

字符编码即ASCII码(American Standard Code for Information Interchange,美国信息交换标准码,国际通用的计算机内的字符数字的二进制编码),它是7位二进制编码,总共有128个符号,包括英文26个大写字母&#…

什么叫ASCII码

一个字符A,以 字符和整型都可以输出。因为字符A也是以二进制存储,这个二进制对应一个整数 那究竟什么是ASCII码? ASCII不是一个值,而是一种规定。 ASCII规定了不同字符是使用哪个整数值表示 它规定: A --65 B --…

关于ASCII码的转换

目录 ASCII码表ASCII码与字符之间的转换 ASCII码表 ASCII码与字符之间的转换 python中chr()和ord()两个函数可以实现ASCII码与字符之间的转换, 两者之间的关系 转换举例 stringbsuahisas num_list[ord(i) for i in string] str_list[chr(i) for i in num_list] p…

ASCII码介绍

ASCII码 概念 ASCII(American Standard Code for Information Interchange)的缩写(美国标准信息交换代码),已被国际标准化组织ISO采纳,作为国际通用的信息交换标准代码。 诞生背景 计算机对数据的识别、运算和存储都建立在二进制…

ASCII编码

ASCII编码 ASCII编码的概念对控制字符的解释详细说明 ASCII编码的概念 计算机是以二进制的形式来存储数据的,它只认识 0 和 1 两个数字,我们在屏幕上看到的文字,在存储之前都被转换成了二进制(0和1序列),在…

ascii码a和A为什么差32而不是26

ascii码a和A为什么差32而不是26? A的ASCII码是65,a的ASCII码是97; ASCII码表中,一个字母的大小写数值相差32,一般知道大写字母的ASCII码数值,其对应的小写字母的ASCII码数值就算出来了,是大写字…

ASCII码详解

ASCII简介 ASCII 码使用指定的 7 位或 8 位二进制数组合来表示 128 或 256 种可能的字符。标准 ASCII 码也叫基础ASCII码,使用 7 位二进制数来表示所有的大写和小写字母,数字 0 到 9、标点符号, 以及在美式英语中使用的特殊控制字符。其中&a…

a到z的ascii码值是多少_a和A对应的ASCII码数值分别是多少啊?

展开全部 A的ASCII码是65,a的ASCII码是97。 ASCII码表中,小写字母32313133353236313431303231363533e78988e69d8331333366303066排在大写字母的后面,一个字母的大小写数值相差32,一般知道大写字母的ASCII码数值,其对应…

输出ASCII码

输出字符的ASCII码 从键盘输入一个字符&#xff0c;按规定格式输出这个字符及它的ASCII码。例如&#xff1a; 输入 A 输出 “The ASCII of A is 65”.//输出的数值在双引号以内// 代码&#xff1a; ​ #include <stdio.h>int main() {char a;scanf("…

ascii码中的A的代码是什么?

ASCII&#xff08;American Standard Code for Information Interchange&#xff0c;美国标准信息交换代码&#xff09;是基于拉丁字母的一套电脑编码系统&#xff0c;主要用于显示现代英语和其他西欧语言。它是现今最通用的单字节编码系统&#xff0c;并等同于国际标准ISO/IEC…

system函数阻塞问题

system()函数是阻塞方式进行的&#xff0c;他会新建一个进程! system代码执行完毕才继续执行&#xff01; 注意一点&#xff0c;如下的命令&#xff1a; #include <bits/stdc.h> #include <windows.h> using namespace std; int main() {std::cout << "…

Linux system函数的执行命令并获取状态

在linux中&#xff0c;可以通过调用system函数执行linux命令&#xff0c;但是如何获取执行命令的结果状态呢&#xff0c;也就是是否执行成功。 #include <stdio.h> #include <stdlib.h>int main() {int ret -1;ret system("cat /proc/mounts | grep sda"…

system函数常见用法

system函数 1.用来执行windows常用命令 我们知道 C语言是没有自己的窗口的&#xff0c;比如我们用printf函数在黑框上输出Hello World是其实是调用了windows的DOS交互窗口。 我们在C语言程序中用system可以给操作系统发送指定&#xff0c;其作用与直接在DOS窗口发送指令进行交…

system函数的总结

system函数的总结 2014-10-30 20:22 1216人阅读 评论(2) 收藏 举报 分类&#xff1a; 系统编程&#xff08;17&#xff09; 最近在看APUE第10章中关于system函数的POSIX.1的实现。关于POSIX.1要求system函数忽略SIGINT和SIGQUIT&#xff0c;并且阻塞信号SIGCHLD的论述&…

c/c++中system函数

原文地址&#xff1a;http://www.cnblogs.com/tianzeng/p/9550379.html 在windows下的system函数中命令可以不区别大小写&#xff01; 函数名&#xff1a; system 功 能&#xff1a; 发出一个DOS命令 用 法&#xff1a; #include <stdlib.h>int system(char *command…

system函数返回值,Linux

理论 我们先看下man手册是怎么说的man system RETURN VALUEThe value returned is -1 on error (e.g., fork(2) failed), and the return status of the command otherwise. This latter return status is in the format speci‐fied in wait(2). Thus, the exit code of …

Linux---system函数

一、关于system函数 #include <stdlib.h>int system(const char *command);返回值&#xff1a;成功&#xff0c;返回进程的状态值&#xff1b;当sh不能运行时&#xff0c;返回127&#xff1b;失败&#xff0c;返回-1。 源代码如下&#xff1a; int system(const char …