Java 和SOLID原则

news/2025/2/9 1:01:05/文章来源:https://www.cnblogs.com/szz1/p/18705648

简介

SOLID原则是设计面向对象软件的重要原则集,它由Robert C. Martin提出,以帮助开发人员构建易于维护、扩展和理解的代码。在Java开发中,SOLID原则极大地推动了可维护性和代码质量的提升。SOLID是五个原则的首字母缩写:单一责任原则 (Single Responsibility Principle)、开放封闭原则 (Open/Closed Principle)、里氏替换原则 (Liskov Substitution Principle)、接口隔离原则 (Interface Segregation Principle) 和 依赖倒置原则 (Dependency Inversion Principle)。

目录

  1. 单一责任原则(SRP)
  2. 开放封闭原则(OCP)
  3. 里氏替换原则(LSP)
  4. 接口隔离原则(ISP)
  5. 依赖倒置原则(DIP)
  6. 总结
  7. 参考资料

单一责任原则

基础概念

单一责任原则规定,一个类应该只有一个引起变化的原因。换句话说,每个类都应该负责单一的功能或行为。

使用方法

当发现一个类负责多个功能时,我们应将这些功能分开,以避免将所有职责耦合在一起。这使得任何单一责任的变化不再影响其他职责。

常见实践

考虑如下示例,一个类同时承担了发送邮件和日志记录的职责:

public class EmailService {public void sendEmail(String message) {// 发送电子邮件的代码System.out.println("Sending email: " + message);// 记录日志的代码System.out.println("Log: Email sent with message - " + message);}
}

为了遵循SRP,我们应该将日志记录的责任分离出来:

public class EmailService {private LoggerService logger;public EmailService(LoggerService logger) {this.logger = logger;}public void sendEmail(String message) {// 发送电子邮件的代码System.out.println("Sending email: " + message);logger.log("Email sent with message - " + message);}
}public class LoggerService {public void log(String message) {System.out.println("Log: " + message);}
}

最佳实践

  • 确保每个类仅有一个明确的职责。
  • 当类的职责变得混乱时,考虑重构类结构。

开放封闭原则

基础概念

开放封闭原则指出,软件实体(类、模块、函数等)应该对扩展开放,但对修改封闭。这意味着,要通过新增代码来实现新的功能,而不是修改现有的代码。

使用方法

通过接口和抽象类来定义行为,然后通过继承和实现来提供这些行为的具体实现。

常见实践

一个简单的示例,通过继承来扩展现有类的功能:

public abstract class Shape {public abstract double calculateArea();
}public class Circle extends Shape {private double radius;public Circle(double radius) {this.radius = radius;}@Overridepublic double calculateArea() {return Math.PI * radius * radius;}
}public class Square extends Shape {private double side;public Square(double side) {this.side = side;}@Overridepublic double calculateArea() {return side * side;}
}

最佳实践

  • 使用抽象进行类设计,通过继承来扩展新的功能。
  • 避免直接更改现有代码,最大化使用继承和多态。

里氏替换原则

基础概念

里氏替换原则表明,程序中的对象应该可以使用其子类型(子类)的实例来替换,并且不会影响程序的正确性。

使用方法

确保子类能够完美替代父类实例,其功能与父类的期望一致。

常见实践

考虑以下示例,以说明子类和基类的兼容性:

public class Bird {public void fly() {System.out.println("Flying");}
}public class Sparrow extends Bird {// 继承而来,没有过多的改变
}

在上述例子中,Sparrow 可以替换 Bird,并且完整支持 fly 的功能。

最佳实践

  • 子类不应该重写父类中不必要的功能。
  • 使用合适的继承来保持行为一致性。

接口隔离原则

基础概念

接口隔离原则建议,客户端不应该被强迫依赖于它不使用的方法。也就是说,接口应该小而专注。

使用方法

将庞大的接口拆分为更小、特定功能的接口,使得实现类只需关心它感兴趣的接口。

常见实践

public interface Printer {void print();void scan();void fax();
}public class SimplePrinter implements Printer {public void print() {System.out.println("Printing");}public void scan() {// 不支持扫描功能}public void fax() {// 不支持传真功能}
}

应改为多个接口:

public interface Printer {void print();
}public interface Scanner {void scan();
}public class SimplePrinter implements Printer {public void print() {System.out.println("Printing");}
}

最佳实践

  • 保持接口简单而精确。
  • 如果接口变得庞大,考虑将其拆分。

依赖倒置原则

基础概念

依赖倒置原则指出,高层模块不应该依赖低层模块。二者都应该依赖于抽象(接口或抽象类)。

使用方法

通过依赖注入(Dependency Injection)或服务注入(Service Locator)来帮助实现依赖倒置原则。

常见实践

public class Light {public void turnOn() {System.out.println("Light is on");}
}public class Switch {private Light light;public Switch() {this.light = new Light();}public void operate() {light.turnOn();}
}

可改造为:

public interface Switchable {void turnOn();
}public class Light implements Switchable {@Overridepublic void turnOn() {System.out.println("Light is on");}
}public class Switch {private Switchable device;public Switch(Switchable device) {this.device = device;}public void operate() {device.turnOn();}
}

最佳实践

  • 高层模块应基于抽象以增加灵活性。
  • 使用依赖注入框架(如Spring)来实现依赖管理。

总结

SOLID原则在Java开发中提供了一套重要的设计指南。这些原则帮助开发人员编写更灵活、可维护和可扩展的代码。通过实践单一责任原则、开放封闭原则、里氏替换原则、接口隔离原则和依赖倒置原则,开发者能够显著提高代码质量。

参考资料

  1. Robert C. Martin, "Agile Software Development: Principles, Patterns, and Practices"
  2. SOLID Principles Wikipedia
  3. Clean Code: A Handbook of Agile Software Craftsmanship by Robert C. Martin

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

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

相关文章

宏定义

宏定义 # 和 ## #号(将符号转为字符串) 这条定义中,定义了一个 PRINT 的宏函数预处理器遇到这样的宏,会将 #a 替换成以字符串表示的参数 a 例如:##号(连接符:将2个表达式连接到一起)预处理器会将这2条宏扩展成下面的代码我们可以看到:这2条宏定义其实就是定义了2个成员…

《Operating System Concepts》阅读笔记:p2-p8

《Operating System Concepts》学习第 2 天,p2-p8 总结,总计 7 页。 一、技术总结 1.operating system An operating system is software that manages a computer’s hardware。 2.system bus data bus, address bus, control bus 统称为 system bus。 二、英语总结(生词:…

踩坑---中断中调用系统定时器延时卡死

踩坑---中断中调用系统定时器延时卡死 背景 ​ 配置外部中断作为按键输入时,调用了系统滴答定时器为基准的延时。然后每次一按按键,单片机就卡死。一开始怀疑时中断没有配置好。反复研究中断配置是否出现错误,最后debug出来,发现卡在了// 3. 等待计数值变为0,判断CTRL标志…

windows 10 安装 wsl

在 windows 上安装 Debian 版本的 wsl以管理员身份运行 cmd,执行 wsl --help 可查看 wsl 的帮助信息。执行 wsl --list --online 查看可供安装的 wsl子系统 版本。执行 wsl --install --distribution Debian 安装 debian 版本的 wsl有了计划记得推动,不要原地踏步。

开学作业13

学习使用了vue中watch知识 可以实时更新数据 也非常好用

开学作业14

前几天也是这样通过打电话合作 前后端分着写 已经完成大部分前后端的交并 预计明天写完

做开学作业10

使用的是element ui vue2 springboot技术

手把手教你如何用飞书实现betterGI消息推送

在平时,我们一般会使用betterGI的一条龙系统来完成体力的刷取,有的人可能需要知道啥时候刷完体力方便远程关闭电脑啥的,这里给大家如何通过飞书实现BetterGI消息推送的方法 1、支持的事件提醒 事件列表 notify.test : 测试通知 domain.reward : 自动秘境奖励 domain.start :…

2025【重庆联通】活动

2025年2月8日更新 扫码显示详情及办理 扫码显示详情及办理 套餐资费和活动内容均来源于重庆联通【10010人工客服可查,中国联通app官方客服可查】 这里是下面的54个活动的办理名称,请确认【点击也可直接跳转到相应位置】1.云创安全组合包10元(CQ)-立即生效 2.云创数字人名片权…

LLVM+CMAKE+VScode

在mac上使用vscode+CMAKE+LLVM 配置C++环境 仅供参考,请多谅解 原先的vscode官方推荐插件intellisense实在是太慢,以至于在很多大型项目(ns3,OS)等进行静态检查的速度奇慢无比,并且大量消耗资源。于是尝试在mac上使用llvm+clangd进行配置。由于采用的是homebrew安装clang…

FastAPI for Machine Learning: Live coding an ML web application

FastAPI for Machine Learning: Live coding an ML web application https://www.bilibili.com/video/BV1kC411b7Se/?spm_id_from=333.788.videopod.sections&vd_source=57e261300f39bf692de396b55bf8c41b翻译:FastAPI用于机器学习:现场编码一个ML Web应用程序。欢迎!加…

08_LaTeX之自定义LaTeX命令和功能

本章的内容将让你能编写可重复利用的模块——宏包和文档类,并在其中自己定义命令和环境。08_\(\LaTeX{}\) 之自定义\(\LaTeX{}\)命令和功能 目录08_\(\LaTeX{}\) 之自定义\(\LaTeX{}\)命令和功能自定义命令和环境定义新命令定义环境xparse 宏包简介编写自己的宏包和文档类编写…