设计模式-六大原则

设计模式的六大原则是软件工程中的基本概念,使得构建可维护、可扩展和可重用的代码。
1.单一职责原则(Single Responsibility Principle):一个类或方法应该只有一个引起变化的原因,确保类或模块的功能高度内聚。
案例:

public class Affair {public void study(String animal){System.out.println(animal+"学习了");}
}
public class Client {public static void main(String[] args) {Affair affair=new Affair();affair.study("张三");}
}

遵循单一职责原则的优点有:
1.可以降低类的复杂度,一个类只负责一项职责,其逻辑肯定要比负责多项职责简单的多;
2.提高类的可读性,提高系统的可维护性;
3.变更引起的风险降低,变更是必然的,如果单一职责原则遵守的好,当修改一个功能时,可以显著降低对其他功能的影响。

2.开闭原则(Open-Closed Principle):软件实体(如类、模块等)应对扩展开放,对修改封闭。这意味着系统可以轻易地增加新功能而不需要修改已有的代码。

3.里氏替换原则(Liskov Substitution Principle):子类应该能够替换其基类,而不会改变程序的正确性。这保证了继承体系中的类型安全。
里氏替换原则:子类可以扩展父类的功能,但不能改变父类原有的功能。
1.子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法。
2.子类中可以增加自己特有的方法。
3.当子类的方法重载父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松。
4.当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更严格。
案例:

public class Student {public double grossScore(double m,double n){return m+n;}
}
public class Student1 extends Student{public double grossScore(double m,double n){return m+n;}public double average(double m,double n){return (m+n)/2;}
}
public class Client {public static void main(String[] args) {Student student=new Student();System.out.println("学生总分数为:"+student.grossScore(98.3, 81.3));Student1 student1=new Student1();System.out.println("学生平均分数为:"+student1.average(98.3, 81.3));}
}

4.依赖倒置原则(Dependency Inversion Principle):高层模块不应直接依赖于低层模块,而是都应该依赖于抽象。抽象不应该依赖细节,细节应该依赖抽象。这有助于减少代码之间的耦合,提高系统的可维护性。

public interface Campaign {String getMovement();
}
public class Exercise {public void motion(Campaign campaign){System.out.println("开始运动了");System.out.println(campaign.getMovement());}
}
public class BasketBall implements Campaign{@Overridepublic String getMovement() {return "打篮球咯!!!";}
}
public class Football implements Campaign{@Overridepublic String getMovement() {return "踢足球了咯!!!";}
}
public class Client {public static void main(String[] args) {Exercise exercise=new Exercise();exercise.motion(new BasketBall());exercise.motion(new Football());}
}

在这里插入图片描述
5.接口隔离原则(Interface Segregation Principle):客户端不应被要求依赖它们不需要的接口。这有助于减少类对接口的依赖,提高系统的灵活性和可重用性。
反例,代码臃肿:

//接口
public interface ConnectorsA {void methodA();void methodB();void methodC();void methodD();void methodE();
}
//调用
public class BasicsA {public void dependA(ConnectorsA connectorsA){connectorsA.methodA();}public void dependB(ConnectorsA connectorsA){connectorsA.methodB();}public void dependC(ConnectorsA connectorsA){connectorsA.methodC();}
}
//接口实现
public class BasicsADepend implements ConnectorsA {@Overridepublic void methodA() {System.out.println("类BasicsDepend实现接口ConnectorsA的方法A");}@Overridepublic void methodB() {System.out.println("类BasicsDepend实现接口ConnectorsA的方法B");}@Overridepublic void methodC() {System.out.println("类BasicsDepend实现接口ConnectorsA的方法C");}@Overridepublic void methodD() {}@Overridepublic void methodE() {}
}
//调用
public class BasicsB {public void dependA(ConnectorsA connectorsA){connectorsA.methodA();}public void dependB(ConnectorsA connectorsA){connectorsA.methodD();}public void dependC(ConnectorsA connectorsA){connectorsA.methodE();}
}
//接口实现
public class BasicsBDepend implements ConnectorsA {@Overridepublic void methodA() {System.out.println("类BasicsBDepend实现接口ConnectorsA的方法A");}@Overridepublic void methodB() {}@Overridepublic void methodC() {}@Overridepublic void methodD() {System.out.println("类BasicsBDepend实现接口ConnectorsA的方法D");}@Overridepublic void methodE() {System.out.println("类BasicsBDepend实现接口ConnectorsA的方法E");}
}
//Test
public class Client {public static void main(String[] args) {BasicsA basicsA=new BasicsA();basicsA.dependA(new BasicsADepend());basicsA.dependB(new BasicsADepend());basicsA.dependC(new BasicsADepend());BasicsB basicsB=new BasicsB();basicsB.dependA(new BasicsBDepend());basicsB.dependB(new BasicsBDepend());basicsB.dependC(new BasicsBDepend());}
}

使得接口分离优化为正例:

//接口拆分
public interface ConnectorsA1 {void methodA();
}
//接口拆分
public interface ConnectorsA2 {void methodB();void methodC();
}
//接口拆分
public interface ConnectorsA3 {void methodD();void methodE();
}
//调用
public class BasicsA {public void dependA(ConnectorsA1 connectorsA1){connectorsA1.methodA();}public void dependB(ConnectorsA2 connectorsA2){connectorsA2.methodB();}public void dependC(ConnectorsA2 connectorsA2){connectorsA2.methodC();}
}
//接口实现
public class BasicsADepend implements ConnectorsA1,ConnectorsA2 {@Overridepublic void methodA() {System.out.println("类BasicsDepend实现接口ConnectorsA1的方法A");}@Overridepublic void methodB() {System.out.println("类BasicsDepend实现接口ConnectorsA2的方法B");}@Overridepublic void methodC() {System.out.println("类BasicsDepend实现接口ConnectorsA2的方法C");}
}
//调用
public class BasicsB {public void dependA(ConnectorsA1 connectorsA1){connectorsA1.methodA();}public void dependB(ConnectorsA3 connectorsA1){connectorsA1.methodD();}public void dependC(ConnectorsA3 connectorsA3){connectorsA3.methodE();}
}
//接口实现
public class BasicsBDepend implements ConnectorsA1,ConnectorsA3 {@Overridepublic void methodA() {System.out.println("类BasicsBDepend实现接口ConnectorsA1的方法A");}@Overridepublic void methodD() {System.out.println("类BasicsBDepend实现接口ConnectorsA3的方法D");}@Overridepublic void methodE() {System.out.println("类BasicsBDepend实现接口ConnectorsA3的方法E");}
}
//Test
public class Client {public static void main(String[] args) {BasicsA basicsA=new BasicsA();basicsA.dependA(new BasicsADepend());basicsA.dependB(new BasicsADepend());basicsA.dependC(new BasicsADepend());BasicsB basicsB=new BasicsB();basicsB.dependA(new BasicsBDepend());basicsB.dependB(new BasicsBDepend());basicsB.dependC(new BasicsBDepend());}
}

采用接口隔离原则对接口进行约束时,要注意
1.接口尽量小,要适度。对接口进行细化,提高程序设计灵活性。过小,则会造成接口数量过多,使设计复杂化,即要适度。
2.为依赖接口的类定制服务,只暴露给调用的类它需要的方法,不需要的方法则隐藏起来。只有专注地为一个模块提供定制服务,才能建立最小的依赖关系。
3.提高内聚,减少对外交互。使接口用最少的方法去完成最多的事情。

6.迪米特法则(Law of Demeter):一个对象应对其他对象有最少的了解。这有助于降低类之间的耦合度,提高系统的稳定性和可维护性。
反例:一集团公司,下属单位有分公司和直属部门,现在要求打印出所有下属单位的员工ID。

//总公司
public class Employee {private String id;public String getId() {return id;}public void setId(String id) {this.id = id;}
}
//分公司
public class SubEmployee {private String id;public String getId() {return id;}public void setId(String id) {this.id = id;}
}
//分公司ID管理
public class SubCompanyManager {public List<SubEmployee> getAllEmployeee(){List<SubEmployee> list = new ArrayList<>();for (int i = 0; i < 20; i++) {SubEmployee employee = new SubEmployee();employee.setId("分公司"+i);list.add(employee);}return list;}
}
//总公司ID管理
public class CompanyManager {public List<Employee> getAllWmployee(){ArrayList<Employee> list = new ArrayList<>();for (int i = 0; i < 10; i++) {Employee employee = new Employee();employee.setId("总公司"+i);list.add(employee);}return list;}public void printAllEmployee(SubCompanyManager subCM){List<SubEmployee> allEmployeee = subCM.getAllEmployeee();for (SubEmployee subEmployee : allEmployeee) {System.out.print(subEmployee.getId()+" ");}System.out.println();System.out.println("------------------------------------------------------------");List<Employee> allWmployee = this.getAllWmployee();for (Employee employee : allWmployee) {System.out.print(employee.getId()+" ");}}
}
//Test
public class Client {public static void main(String[] args) {CompanyManager companyManager = new CompanyManager();companyManager.printAllEmployee(new SubCompanyManager());}
}

优化CompanyManager后

public class SubCompanyManager {public List<SubEmployee> getAllEmployeee(){List<SubEmployee> list = new ArrayList<>();for (int i = 0; i < 20; i++) {SubEmployee employee = new SubEmployee();employee.setId("分公司"+i);list.add(employee);}return list;}public void printEmployee(){List<SubEmployee> list = this.getAllEmployeee();for (SubEmployee subEmployee : list) {System.out.print(subEmployee.getId());}}
}public class CompanyManager {public List<Employee> getAllWmployee(){ArrayList<Employee> list = new ArrayList<>();for (int i = 0; i < 10; i++) {Employee employee = new Employee();employee.setId("总公司"+i);list.add(employee);}return list;}public void printAllEmployee(SubCompanyManager subCM){subCM.printEmployee();System.out.println();System.out.println("------------------------------------------------------------");List<Employee> allWmployee = this.getAllWmployee();for (Employee employee : allWmployee) {System.out.print(employee.getId()+" ");}}
}

优化后:达到解耦

转自:https://www.cnblogs.com/bruce1992/p/15096265.html
学习分享输出是一种对大脑的刺激

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

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

相关文章

VMware-Linux切换桥接模式上网教程(超详细)

这里写目录标题 1. 虚拟机关机2. VMware 虚拟网络配置2.1 检查是否存在 VMnet02.2 修改桥接模式2.3 修改Linux虚拟机网络适配器 3. Linux 系统配置3.1 修改系统网卡配置3.1.1 配置项含义解释3.1.2 查看物理机网络信息3.3.3 修改配置 3.2 重启服务 4. 测试网络连接情况5. 注意事…

【SpringBoot整合系列】SpringBoot整合JPA

目录 前期回顾ORM解决方案 JPA简介JPA的组成技术ORM映射元数据Java持久化API查询语言&#xff08;JPQL&#xff09; JPA的优势JPA的缺点 Spring Data JPASpring Data JPA简介Spring Data 家族Spring Data JPA、JPA和其他框架之间的关系 SpringBoot整合JPAJPA的核心注解1.依赖2.…

element-ui upload 组件 手动多次出发 submit

element 上传组件 upload 上传成功以后&#xff0c;想重新 调用 submit()函数&#xff0c;发现是不可以进行多次触发的,。 直接上解决方法&#xff0c;在上传成功后的钩子函数里添加:fileList[0l.status ready fileList是文件列表&#xff0c;status是单文件的状态改成ready就…

【Fastadmin】表格导出excel,图片显示太大

目录 1.直接导出示例 2.解决办法 3. 再次导出效果 1.直接导出示例 图片过大&#xff0c;格式错乱 2.解决办法 在js页面加入代码 // 导出图片过大处理 exportOptions: {ignoreColumn: [0, operate],onBeforeSaveToFile: function (data, fileName, type, charset, encoding,…

《深入Linux设备驱动程序内核机制》学习笔记-第4章

前言 本文是《深入Linux设备驱动程序内核机制》的读书笔记&#xff0c;本文因为是读书笔记所以抄写引用了该书中的大量内容&#xff0c;写读书笔记的目的是在写作的过程中加深对书中内容的理解。 建议读者直接阅读《深入Linux设备驱动程序内核机制》&#xff0c;这本书是Linu…

mPEG-Dansyl,Methoxy PEG Dansyl由甲氧基-聚乙二醇(mPEG)和丹磺酰氯(Dansyl)两部分组成

【试剂详情】 英文名称 mPEG-Dansyl&#xff0c;Methoxy PEG Dansyl 中文名称 聚乙二醇单甲醚丹磺酸酯&#xff0c;甲氧基-聚乙二醇-丹磺酰胺 外观性状 由分子量决定&#xff0c;液体或者固体 分子量 0.4k&#xff0c;0.6k&#xff0c;1k&#xff0c;2k&#xff0c;3.4k…

前端发送请求,显示超时取消

前端发送请求&#xff0c;显示超时取消 问题说明&#xff1a;后台接口请求60s尚未完成&#xff0c;前端控制台显示取消&#xff08;canceled&#xff09; 原因 1、前端设置60s超时则取消 2、后台接口响应时间过长&#xff0c;过长的原因统计的数据量多&#xff08;实际也才17…

LLM 安全 | 大语言模型应用安全入门

一、背景 2023年以来&#xff0c;LLM 变成了相当炙手可热的话题&#xff0c;以 ChatGPT 为代表的 LLM 的出现&#xff0c;让人们看到了无限的可能性。ChatGPT能写作&#xff0c;能翻译&#xff0c;能创作诗歌和故事&#xff0c;甚至能一定程度上做一些高度专业化的工作&#x…

BUUCTF-Misc20

[ACTF新生赛2020]NTFS数据流1 1.打开附件 是一堆文件&#xff0c;随便打开一个内容是flag不在这 2.pyton脚本 编写查找文件夹下一堆文件中那个文件藏有flag的Python脚本 import os def search_flag_files(folder_path, flag): flag_files [] for root, dirs, files …

HAL STM32 SSI/SPI方式读取MT6701磁编码器获取角度例程

HAL STM32 SSI/SPI方式读取MT6701磁编码器获取角度例程 &#x1f4cd;相关篇《HAL STM32 I2C方式读取MT6701磁编码器获取角度例程》&#x1f4cc;当前最新MT6701数据手册&#xff1a;https://www.magntek.com.cn/upload/MT6701_Rev.1.8.pdf&#x1f4dc;SSI协议读角度&#xff…

【stomp实战】搭建一套websocket推送平台

前面几个小节我们已经学习了stomp协议&#xff0c;了解了stomp客户端的用法&#xff0c;并且搭建了一个小的后台demo&#xff0c;前端页面通过html页面与后端服务建立WebSocket连接。发送消息给后端服务。后端服务将消息内容原样送回。通过这个demo我们学习了前端stomp客户端的…

剑指 Offer 03.:数组中重复的数字

剑指 Offer 03. 数组中重复的数字 找出数组中重复的数字。 在一个长度为 n 的数组 nums 里的所有数字都在 0&#xff5e;n-1 的范围内。数组中某些数字是重复的&#xff0c;但不知道有几个数字重复了&#xff0c;也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。…

DIN特征加权、POSO特征增强、SENET特征选择

本文转自&#xff1a;DIN、POSO、SENet 聊聊推荐模型中常用的Attention-腾讯云开发者社区-腾讯云 一、前言 聊起模型结构的时候&#xff0c;经常听做推荐的同学说&#xff1a; "这里加了个self-attention" "类似于一个SENet" "一个魔改的POSO"…

[Visual Studio 报错] error 找不到指定的 SDK“Microsoft

[Visual Studio 2022 报错] error : 找不到指定的 SDK“Microsoft.NET.Sdk.Web” 问题描述&#xff1a; 在新电脑上安装了VS2022&#xff0c;打开现有项目的解决方案后的时候报了这个错&#xff0c;所有projet文件都加载失败,如图所示&#xff1a; 报错分析及解决 打开项目配…

经验丰富也被裁了,失业快2年找不到工作?

前几天徐工说&#xff0c;他有个邻居&#xff0c;最近逮到他总是要跟他扯上几句。 原因是徐工一直是做嵌入式开发&#xff0c;而他一直做纯软件开发&#xff0c;具体不知道做后端还是前端。 他说&#xff0c;他至少有半年没上班了&#xff0c;之前在一家龙头物流公司上班。 碰上…

STM32 HAL库F103系列之DAC实验(二)

DAC输出正弦波实验 实验简要 1&#xff0c;功能描述 通过DAC1通道1(PA4)输出正弦波&#xff0c;然后通过DS100示波器查看波形 2&#xff0c;使用定时器7 TRGO事件触发转换 TEN1位置1、TSEL1[2:0]010 3&#xff0c;关闭输出缓冲 BOFF1位置1 4&#xff0c;使用DMA模式 DMAE…

SLMs之Phi-3:Phi-3的简介、安装和使用方法、案例应用之详细攻略

SLMs之Phi-3&#xff1a;Phi-3的简介、安装和使用方法、案例应用之详细攻略 导读&#xff1a;2024年4月23日&#xff0c;微软发布Phi-3&#xff0c;这是微软推出的一款新的开源AI模型家族Phi-3。背景痛点&#xff1a;小语言模型(SLM)尽管规模不大&#xff0c;但在语言理解、代码…

盲盒商城小程序(有米就出)

一款前端采用uniapp&#xff0c;后端采用Django框架开发的小程序&#xff0c;包含后台管理&#xff0c;如有人需要可联系演示功能&#xff08;个人开发&#xff0c;可商用/学习&#xff09;。 部分截图如下&#xff1a;

文件摆渡:安全、高效的摆渡系统助力提升效率

很多组织和企业都会通过网络隔离的方式来保护内部的数据&#xff0c;网络隔离可以是物理隔离&#xff0c;也可以是逻辑隔离&#xff0c;如使用防火墙、VPN、DMZ等技术手段来实现&#xff0c;隔离之后还会去寻找文件摆渡方式&#xff0c;来保障日常的业务和经营需求。 进行网络隔…

数据库变更时,OceanBase如何自动生成回滚 SQL

背景 在开发中&#xff0c;数据的变更与维护工作一般较频繁。当我们执行数据库的DML操作时&#xff0c;必须谨慎考虑变更对数据可能产生的后果&#xff0c;以及变更是否能够顺利执行。若出现意外数据丢失、操作失误或语法错误等情况&#xff0c;我们必须迅速将数据库恢复到变更…