乐趣区

关于java:面向对象设计原则和设计模式关系及如何实践

1. 概述

设计模式,面向对象准则,软件品质属性的关系如下图:

  1. 下层所作的一切都是为了最终能进步软件品质属性。
  2. 设计准则基于面向对象三大准则,这三大准则是下层的根底。
  3. 封装变动是面向接口编程的根底,如果没有变动就没有必要面向接口编程,因而封装变动尤为重要。
  4. 设计模式遵循了设计准则和面向对象三大准则,同时又是这些准则的落地实际参考。

以上各层相互关联,须要综合来看能力更好的落地实际,进步集体能力和软件品质。

2. 设计准则

这里并不会对设计准则做具体介绍,这方面的材料较多,能够参考其余材料一起着看,这里仅形容基本概念和一些领会。

2.2. 繁多职责

参考 Java 编程思维(八)如何做到繁多职责。

2.3. 开闭准则

2.3.1. 定义

对扩大凋谢,对批改关闭。能够了解为尽量对已有类 / 模块的批改关闭,能够减少新的类实现扩大。

2.3.2. 例子

算税依据不同的场景计算方法不同,须要动静获取算法,同时容许定制团队扩大税的算法。

  1. 这里税的算法是变动点,因而须要形象进去。
  2. 定制团队要能扩大税的算法,因而须要反对动静注册算法。

最终失去的类结构图如下:

这样当有新的税算法时:

  1. 实现新的税算法类
  2. 减少一个新的税类型和新算法类对应
  3. 通过 TaxCalculatorRegistry 类注册新的税算法类
  4. 通过 TaxCalculatorRegistry 获取对应的税算法类算税

2.4. 里氏替换

2.4.1. 定义

子类对象可能替换父类对象,并且保障原来程序的逻辑行为不变及正确性不被毁坏。

这个定义看起来很像面向接口编程,但理论两者不同,里氏替换准则满足面向接口编程,然而面向接口编程未必满足里氏替换准则,里氏替换准则还蕴含了束缚,强调程序的逻辑行为不变及正确性不被毁坏。

2.4.2. 例子

一个接口的子类原来性能差,替换了新的子类实现,接口不变,然而某个办法原来未抛异样,新的子类抛了运行时异样,这就扭转了原来的逻辑行为,会影响调用端的解决逻辑,严格讲不合乎里氏替换准则。

当代码被第三方调用时尤其要留神里氏替换准则,如果未告知抛异常情况下忽然抛了异样,很有可能重大影响调用端的解决逻辑。

2.5. 接口隔离

2.5.1. 定义

接口的设计要尽量繁多,不要让接口的实现类和调用者,依赖不须要的接口函数。

2.5.2. 例子

鸭子会叫,会游泳,会飞,但并非所有的鸭子都会游泳,会飞(例如塑料鸭 ),因而须要做接口隔离别离定义游泳和飞的接口。

如果不做接口隔离,那么塑料鸭子就要实现不必要的接口,但理论又不能有对应实现,只能抛出 UnSupportException 异样,有点多此一举,没有意义。

2.5.4. 例外

在理论工作中,有时会违反这样的准则,将所有的接口定义在一起,在不反对子类实现中抛出 UnSupportException,这种做法其实违反了接口隔离准则,但有时也是不得已为知,因为接口不是本人定义的,是开源框架或者业界规范接口定义,比方 JDBC 相干的接口,在和公司自行实现的数据库对接时,未必能反对所有办法,但又不得不通过 JDBC 接口做标准化。

因而,此准则应尽量恪守,也能够有例外。

2.6. 依赖倒置

2.6.1. 定义

高层模块不依赖低层模块,它们独特依赖同一个形象。形象不要依赖具体实现细节,具体实现细节依赖形象。

2.6.2. 例子

通常状况下,高层会依赖低层,但这样就没有了扩展性,会依赖低层的实现细节,依赖倒置通常呈现在业界的一些标准规范,框架等等,例如 JDBC 接口标准:

调用者只须要依赖 JDBC 接口,而不必关怀各个厂家的具体实现类。

相似的例子还有 servlet 标准,开发者只有实现 servlet 的接口就能在对应的 web 容器中被调用。

依赖倒置准则缩小了低层耦合,实用于框架,模块间,零碎间的调用。

2.7. 迪米特法令

2.7.1. 定义

迪米特法令(Law of Demeter)又叫作起码常识准则(The Least Knowledge Principle),一个类对于其余类晓得的越少越好,就是说一个对象该当对其余对象有尽可能少的理解, 只和敌人通信,不和陌生人谈话。英文简写为: LOD

2.7.2. 例子

设计模式的门面模式(Facade)和中介模式(Mediator),都是迪米特法令利用的例子。

3. 面向对象三大准则

3.1. 封装变动

封装变动的益处不言而喻,向上反对设计准则,向下保障了软件的多个品质属性。那么怎么能力进步封装变动的能力?

通常能够在设计阶段先做剖析,初步辨认哪些性能可能是变动点,画出大抵的类结构图,开始编码,但实际上设计阶段有的细节思考不到,另外也并不是每个人都会设计后行,因而还能够通过逆向的形式辨认变动点,过程如下:

  1. 编写代码时每个办法尽量不要超过 20 行,当你这么做当前,每个能够独立存在的办法都可能是一个变动点。(办法短小不仅仅能够用来辨认变动点,同时也能进步可维护性,好比一篇文章,为啥要有章节,没有章节目录的书如果内容又长,预计你都不想看,所以编写短小办法应该始终贯彻到底)
  2. 查看每个办法的实现是否可能发生变化,是否可提取成公共办法,如果答案为必定,就意味着你要提供接口,拆分类,应用工厂,策略等设计模式
  3. 进一步查看这个变动点是否容许第三方来扩大,如果答案为必定,意味着你可能要提供动静注册变动点的实现类的能力,或者是对外提供的办法容许通过接口注入具体的实现类。
  4. 进一步查看变动点是否须要独立为一个子包,或者是我的项目级的公共包

依照以上形式步骤一直重构就能够了。

注意事项:

  1. 每个可独立的办法不肯定就要做成 public,要依据理论须要决定是否要做成 public,办法独立最根本的作用是进步可维护性。
  2. 要充分考虑变动的可能性,如果可能性不大,就不要作为变动点解决,不要为了让代码看起来很高大尚就搞出接口,设计模式来,代码简略,稳固更重要。

《2020 最新 Java 根底精讲视频教程和学习路线!》

链接:https://juejin.cn/post/691865…

退出移动版