本文将通过示例讨论 Java 开发如何实践 SOLID 原则。


SOLID 设计原则,Java实例讲解_Java


2000年,Robert C.Martin 在《设计原则和设计模式》论文中首次提出 SOLID 概念。Michael Feathers 对这些内容进行提炼并提出 SOLID 缩写。


《设计原则和设计模式》论文

fi.ort.edu.uy/innovaportal/file/2032/1/design_principles.pdf


SOLID 是什么?如何帮助我们编写更好的代码?简单地说,Martin 和 Feathers 提出的设计原则提倡构建可维护性更高、更容易理解和更灵活的软件。随着程序规模日益增长,设计原则有助于降低系统复杂性并减少后续开发中可能遇到的麻烦。

SOLID 原则包含下面五个概念:


  1. 单一职责原则(SRP)

  2. 开闭原则(OCP)

  3. 里式替换原则(LSP)

  4. 接口隔离原则(ISP)

  5. 依赖倒置原则(DIP)


让我们通过一个示例来理解 SOILD 原则。SOLID 原则中每一条都单独撰写了文章,通过 「」和「」设计对原则进行解释。


在实际开发中,设计 class 应牢记这五条 SOLID 原则。不仅如此,它们还是设计应用时需要遵循的最佳实践。


1.单一职责(SRP)


“一个类应该有且只赋予一个职责”


每个类都应该赋予单一职责,而且这个职责应该完全封装在类中。引起类变化的因素永远不要超出一个。单一职责表示 SOLID 五项原则中的 “S”,在面对象编程实践中意味着编写设计良好、可读性强、易于维护、易于升级和修改的代码。


实践总结


  • 如果无法给 class 指定一个有意义类名,那么可能该类被赋予的职责过多。

  • 每个 Web 应用中的对象都应赋予一个职责,所有对象 service 都应专注于该职责(SRP)。

  • 如果某个 Java 类提供了多个功能,那么两个功能之间可能会产生耦合。即使只更改一个功能,也可能破坏耦合的关联功能。因此需要额外测试,以免对生产环境造成损害。


参阅 《单一职责Java实例》 了解更多内容。


《单一职责Java实例》

javaguides.net/2018/02/single-responsibility-principle.html


2. 开闭原则(OCP)


这是应用程序设计应当牢记的第二个重要原则。开闭原则指出:


“软件应该对扩展开放,但对修改关闭”。


简单地说,类、模块和函数等软件实体应该对扩展开放,对修改关闭。开闭原则表示 SOLID 五项原则中的“O”,在面向对象编程实践中意味着编写设计良好、可读性强、易于维护、易于升级和修改的代码


实践总结


  • 对扩展开放:class 设计在应对新需求时可以方便地加入新功能。

  • 对修改关闭:除了修改 bug,否则不要改动已经设计好的类。

  • 加入新功能时,设计和编码应该尽可能避免修改已有代码,最好不修改。

  • 扩展已有功能时,应避免紧耦合:不要使用 if-else 或者 switch-case,请根据需要重构代码。

  • 实现技术:继承、多态、泛型。

  • 适用模式:策略模式、模板方法。


了解更多开闭原则相关内容,请参阅《开闭原则Java实例》中的类图、代码与最佳实践。


开闭原则Java实例

javaguides.net/2018/02/open-closed-principle.html


3. 里氏替换原则(LSP)


里式替换原则:


“派生类型必须可以完全替换其基类型。


里式替换原则表示 SOLID 五项原则中的 “L”,在面向对象编程实践中意味着编写设计良好、可读性强、易于维护、易于升级和修改的代码。


实践总结


  • 该原则适用于继承层次结构,是开闭原则的一种扩展。

  • 这意味着派生出的新类必须保证不会改变基类的行为。基本上,派生类提供的功能只会比基类多。

  • 如果派生类行为超出了基类客户端的预期,则违反了里氏替换原则。比如派生类抛出一个基类不会抛出的异常,或者派生类的功能有副作用。必须考虑客户端程序如何使用类继承结构。有时需要重构代码以纠正不符合里氏替换原则的部分。


了解更多里氏替换原则相关内容,请参阅《里氏替换原则Java实例》。


里氏替换原则Java实例

javaguides.net/2018/02/liskov-substitution-principle.html


4. 接口隔离原则(ISP)


该原则适用于接口,之前的单一职责原则适用于类。接口隔离原则:


“不应强迫客户实现对自身无用的方法”。


SOLID 五项原则中的“I”表示接口隔离原则,它意味着应将较大的接口拆分为较小的接口。这样可以确保接口的实现类只需要关心它们感兴趣的方法。


了解更多接口隔离原则相关内容,请参阅《接口隔离原则Java实例》。


接口隔离原则Java实例

javaguides.net/2018/02/liskov-substitution-principle.html


5. 依赖倒置原则(DIP)


依赖倒置原则: 


高层模块不应依赖于底层模块。两者都应依赖其抽象。抽象不应当依赖细节。细节应当依赖于抽象。


依赖倒置原则表示 SOLID 五项原则中的 “D”,在面向对象编程实践中意味着编写设计良好、可读性强、易于维护、易于升级和修改的代码。


实践总结


  • 契约式设计。

  • 设计中每个依赖项都应该是接口或抽象类。不应当依赖任何具体类。

  • 工厂类与抽象工厂可以用作依赖框架,也有像 Spring IOC(控制反转容器)这样的专门框架。


了解更多依赖倒置原则相关内容,请参阅《依赖倒置原则Java实例》。


依赖倒置原则Java实例

javaguides.net/2018/02/liskov-substitution-principle.html


总结


本文介绍了面向对象设计中的 SOLID 原则。每个 SOLID 原则的示例代码可以在 GitHub 上下载。