Java Solid 原则指南
在这篇文章中,我们将看到 Java 中的 5 个 SOLID 原则。
Robert C. Martin 提出了五项面向对象设计原则,并将其缩写为“SOLID”。该缩写中的每个字母都代表了Java中的原则。当您结合使用 SOLID 的所有原则时,开发易于管理的软件将变得更加容易。SOLID 的其他特性包括:
- 避免代码异味
- 快速折射器代码
- 可以进行自适应或敏捷软件开发
当您在编码中使用 SOLID 原则时,您就开始编写高效且有效的代码。
SOLID 的含义是什么?
如上所述,SOLID 代表 Java 的五项原则,即:
- S:单一职责原则
- O:开放封闭原则
- L:里氏替换原则
- 一:接口隔离原则
- D:依赖倒置原则
本文将深入探讨这些原则。我们将从第一个原则开始,即单一职责原则。
单一职责原则(SRP)
根据单一责任原则,一个类应该只有一个需要修改的原因。这意味着一个类应该只负责一项任务。这一原则通常被称为主观原则。
举个例子,可以更好地理解这个原理。假设有一个类执行以下操作。
- 连接到数据库
- 从数据库表中读取一些数据
- 最后将其写入文件。
你想象过这样的场景吗?这个类有多个需要修改的原因,其中很少一部分是修改文件输出,一部分是采用新的数据库。当我们谈论单一职责原则时,我们会说,这个类有太多需要修改的原因;因此,它并不符合单一职责原则。
开放封闭原则
根据开闭原则,实体或对象应该对扩展保持开放,但对修改保持封闭。确切地说,根据该原则,类的编写方式应使其能够完美地完成其功能,而不必假设将来有人会随意修改它。因此,类应该对修改保持封闭,但应该具有扩展的选项。扩展类的方式包括:
- 从类继承
- 覆盖类中所需的行为
- 扩展类的某些行为
借助浏览器,我们可以很好地理解开放封闭原则。你还记得在 Chrome 浏览器中安装扩展程序吗?
Chrome 浏览器的基本功能是浏览不同的网站。您在使用 Chrome 浏览器撰写电子邮件时,是否想检查语法?如果是,您可以使用 Grammarly 扩展程序,它能帮您检查内容的语法。
这种通过添加功能来增强浏览器功能的机制被称为扩展。因此,浏览器是一个开放扩展、关闭修改的功能的完美例子。简而言之,您可以通过在浏览器上添加/安装插件来增强功能,但无法构建任何新的东西。
再举一个例子。
您正在使用任何 Spring 函数功能。您显然不能更改其核心逻辑,但您可以扩展 Spring 框架类并创建自己的函数。
里氏替换原则
里氏替换原则假设 q(x) 是一个属性,对于属于类型 T 的 x 的实体而言是可证明的。现在,根据该原则,q(y) 应该对于属于类型 S 的对象 y 也是可证明的,而 S 实际上是 T 的子类型。你现在是不是有点困惑,不知道里氏替换原则到底是什么意思?它的定义可能有点复杂,但实际上相当简单。唯一的区别在于,每个子类或派生类都应该可以替换它们的父类或基类。
你可以说这是一条独特的面向对象原则。理解了这条原则,就可以进一步简化这条原则;一个特定父类型的子类型应该能够替代该父类型,而不会造成任何复杂化或破坏。这条原则与里氏替换原则密切相关。
接口隔离原则
根据接口隔离原则,无论如何,客户端都不应该被强迫实现它不使用的接口,或者客户端不应该被强迫依赖于他们不使用的任何方法。
因此基本上,接口隔离原则就像您喜欢的接口一样,它们很小但特定于客户端,而不是单一且更大的接口。
简而言之,强迫客户依赖他们不需要的某些东西是有害的。
现在让我们再举一个例子来理解这一点。
让我们举一个简单的例子。您正在用 Java 实现自己的 ArrayList 和 LinkedList。您创建一个名为 List 的接口,这两个类都将实现该接口。
package org.arpit.java2blog;
public interface List<T> {
public T get();
public void add(T t);
public T poll();
public T peek();
}
现在让我们创建 LinkedList 类。
包 org.arpit.java2blog; 公共类 LinkedList 实现 List{ @Override 公共整数获取(){ // 实现此方法 返回 null; } @Override 公共无效添加(整数t){ // 实现此方法 } @Override 公共整数轮询(){ // 实现此方法 返回 null; } @Override 公共整数 peek() { // 实现此方法 返回 null; } }
现在让我们创建 ArrayList 类。
包 org.arpit.java2blog; 公共类 ArrayList 实现 List{ @Override 公共整数获取(){ // 实现此方法 返回 null; } @Override 公共无效添加(整数t){ // 实现此方法 } @Override 公共整数轮询(){ // ArrayList 不需要此方法 返回 null; } @Override 公共整数 peek() { // ArrayList 不需要此方法 返回 null; } }
你发现问题了吗?即使你不需要 ArrayList 中的 poll 和 peek 方法,我们也实现了它们。
上述问题的正确解决方案是:
创建另一个名为 Deque 的接口,并使其包含 peek 和 poll 方法。
包 org.arpit.java2blog; 公共接口 Deque<T> { 公共T投票(); 公共 T peek(); }
并从列表界面中删除 peek 和 poll。
包 org.arpit.java2blog; 公共接口列表<T> { 公共 T 获取(); 公共无效添加(T t); }
现在让我们改变 LinkedList 类。
包 org.arpit.java2blog; 公共类 LinkedList 实现 List,双端队列 { @Override 公共整数获取(){ // 实现此方法 返回 null; } @Override 公共无效添加(整数t){ // 实现此方法 } @Override 公共整数轮询(){ // 实现此方法 返回 null; } @Override 公共整数 peek() { // 实现此方法 返回 null; } }
现在让我们改变 ArrayList 类。
包 org.arpit.java2blog; 公共类 ArrayList 实现 List{ @Override 公共整数获取(){ // 实现此方法 返回 null; } @Override 公共无效添加(整数t){ // 实现此方法 } }
如您所见,我们已经分离了两个接口来实现所需的功能。
依赖倒置原则
根据依赖倒置原则,实体应该只依赖于抽象,而不依赖于具体。根据该原则,高级模块绝不能依赖任何低级模块,而应该依赖于抽象。让我们通过另一个实际的例子来再次理解这一点。
你去当地一家商店买东西,决定用借记卡付款。所以,当你把卡交给店员付款时,店员不会费心去检查你给的是什么卡。即使你给了一张Visa卡,店员也不会拿出Visa刷卡机来刷你的卡。你用的是信用卡还是借记卡,这根本不重要;他们只会刷卡。所以,在这个例子中,你和店员都依赖于信用卡抽象,而你并不关心卡的具体细节。这就是依赖倒置原则。
包起来
我希望现在你了解了 SOLID 五个组成部分的基本定义,即单一职责原则、开放封闭原则、里氏替换原则、接口隔离原则和依赖倒置原则。所以,基本上,无论何时编写代码,你都必须牢记这些核心原则。实际上,说实话,你必须以这些原则为蓝本,才能编写出高效且有效的代码。
使用这些原则来管理代码也是一件很容易的事情。最初在编码中运用这些原则可能看起来有些奇怪,但你需要练习使用这些原则编写代码,逐渐地,它们就会成为你的一部分。这样,你编写的代码就可以根据你遇到的需求轻松地进行修改、扩展、重构或测试,而不会遇到任何问题。所以,尽可能地实践这些原则,让你的编码更优秀。
来源:Java 中的可靠原则
您可能还喜欢:
Java 中的 xms 和 xmx 参数
Java 解析时到达文件末尾
Java 中的 NumberFormatException
Java 中的 FileNotFoundException
检查 Java 中的数字是否为数字