java带走怪味道的代码 java一些有趣的代码( 三 )


子类对象(object of subtype/derived class)能够替换程序(program)中父类对象(object of base/parent class)出现的任何地方,并且保证原来程序的逻辑行为(behavior)不变及正确性不被破坏 。
子类可以扩展父类的功能 , 但不能改变父类原有的功能
调用方不应该依赖它不需要的接口;一个类对另一个类的依赖应该建立在最小的接口上 。接口隔离原则提供了一种判断接口的职责是否单一的标准:通过调用者如何使用接口来间接地判定 。如果调用者只使用部分接口或接口的部分功能,那接口的设计就不够职责单一 。
高层模块不应该依赖低层模块 , 二者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象 。
一个对象应该对其他对象保持最少的了解
尽量使用合成/聚合的方式,而不是使用继承 。
单一职责原则告诉我们实现类要职责单一;里氏替换原则告诉我们不要破坏继承体系;依赖倒置原则告诉我们要面向接口编程;接口隔离原则告诉我们在设计接口的时候要精简单一;迪米特法则告诉我们要降低耦合 。而开闭原则是总纲,告诉我们要对扩展开放,对修改关闭 。
image.png
模块结构说明
代码开发要遵守各层的规范,并注意层级之间的依赖关系 。
多个方法代码重复、方法中代码过长或者方法中的语句不在一个抽象层级 。
方法是代码复用的最小粒度,方法过长不利于复用,可读性低 , 提炼方法往往是重构工作的第一步 。
意图导向编程:把处理某件事的流程和具体做事的实现方式分开 。
将函数放进一个单独对象中,如此一来局部变量就变成了对象内的字段 。然后你可以在同一个对象中将这个大型函数分解为多个小型函数 。
方法参数比较多时,将参数封装为参数对象
任何有返回值的方法,都不应该有副作用
临时变量仅使用一次或者取值逻辑成本很低的情况下
将复杂表达式(或其中一部分)的结果放进一个临时变量,以此变量名称来解释表达式用途
把复杂的条件表达式拆分成多个条件表达式,减少嵌套 。嵌套了好几层的if - then-else语句,转换为多个if语句
当出现大量类型检查和判断时,if else(或switch)语句的体积会比较臃肿,这无疑降低了代码的可读性 。另外,if else(或switch)本身就是一个“变化点”,当需要扩展新的类型时,我们不得不追加if else(或switch)语句块 , 以及相应的逻辑,这无疑降低了程序的可扩展性 , 也违反了面向对象的开闭原则 。
非正常业务状态的处理,使用抛出异常的方式代替返回错误码
某一段代码需要对程序状态做出某种假设,以断言明确表现这种假设 。
当使用一个方法返回的对象时,而这个对象可能为空,这个时候需要对这个对象进行操作前,需要进行判空 , 否则就会报空指针 。当这种判断频繁的出现在各处代码之中 , 就会影响代码的美观程度和可读性,甚至增加Bug的几率 。
空引用的问题在Java中无法避免,但可以通过代码编程技巧(引入空对象)来改善这一问题 。
根据单一职责原则,一个类应该有明确的责任边界 。但在实际工作中,类会不断的扩展 。当给某个类添加一项新责任时 , 你会觉得不值得分离出一个单独的类 。于是,随着责任不断增加,这个类包含了大量的数据和函数,逻辑复杂不易理解 。
此时你需要考虑将哪些部分分离到一个单独的类中,可以依据高内聚低耦合的原则 。如果某些数据和方法总是一起出现,或者某些数据经常同时变化,这就表明它们应该放到一个类中 。另一种信号是类的子类化方式:如果你发现子类化只影响类的部分特性,或者类的特性需要以不同方式来子类化,这就意味着你需要分解原来的类 。

推荐阅读