内部状态
- 注意保护,类的私有成员变量。
- 私有成员,内部状态。
- 属性返回内部状态。
- 方法返回内部状态。
注入
- 构造注入
- 属性注入
- 方法参数注入
类
- 类,明确用途。
- 生命周期,何时创建。
- 状态变化。
- 何时销毁。
- 关联哪些资源,资源的状态变化。
- 很难找到修改点,修改就容易引入BUG。
- 过大的类,考虑重构。
- 考虑,在需求问题中寻找名词,将名词转换为对象。
- 对象的设计
- 对象间的关系设计
- 移动字段,移动方法,
- 移动方法非常重要,因为方法代表的就是职责。
- 字段,方法,移动到父类
- 父类字段,方法移动到具体子类
- 父类,子类合并在一起
- 组合取代继承
- 继承取代组合
- 相似类,提炼出一个父类
- 提取类,内联并移除类
- 用对象取代数值项。 简单的例子,一开始,你可以用简单的字符串表示电话号码。可是到后面,逻辑变多复杂,需要灵活维护扩展,你就需要新建电话号码类对象。
单一职责 SRP
- 分解长方法,移至短小方法。
- switch 单独一个方法。
- 对于循环內多行语句,多个职责,可以考虑提取方法,每个方法都进行循环,执行单个职责。
- 提取方法之后,重新命名方法內变量,参数的名字。
- 提取方法之后,观察方法內依赖的对象,方法的意图,思考方法是否仍然属于当前类的职责。
- 多数情况下,方法依赖什么对象,简单来说,方法的参数,是什么对象,那么方法就应该存在于那个对象所在的类中。
- 在将方法移动到依赖对象类中后,可能参数不再需要,方法名字继续变化,根据实际进行调整测试通过。
- switch 语句不要用在另一个对象的某个属性上,最好在属性自己所在对象上使用 switch。
- 方法再次移动到某个类后,可能需要原类属性作为传入参数调整。
- 始终记住,职责,意图,单一职责,单一意图。
- 单一职责,职责暂且就是指方法,职责有大小,职责有粒度,驾驶员开车是职责,开车的具体操作分很多细小的职责。
- 面对软件开发,初期可能就是从大的职责出发,面对小的职责,可能变化的职责,单独提取出来并封装,保证软件设计的灵活可维护性。
- 我们将方法都归位之后,通俗讲就是,方法足够小,并居住在他应该在的类中。
我们要开始考虑继承了。。。。
通常适合继承的是,类型,有多少种类型呢,换句话说,有多少个子类呢?
有了继承,子类的关系,我们就可以利用多态,替换掉 switch 判断。
多态,往往更能表达灵活清晰的条件逻辑,switch 判断,if else 判断。
重复代码
- 相同的程序结构。
- 同一个类中,两个方法有相同的代码逻辑。
- 两个类,兄弟子类,含有相同的类似代码逻辑,提取出来,放到父类。这时候,有多个选择,父类一个方法,父类一个默认实现,子类重写,父类做一个模板方法模式,子类重写等。
- 两个毫不相干的类,出现重复类似代码。提取出来,放在一个新类里面。
方法
方法主要用来,改变对象的状态,或者获取对象的状态。
- 要把,改变,获取,这两种行为分开。
方法是否是对象的职责
- 移动方法到正确的对象。
方法太长
- 类对象方法代码多,说明关注的东西多。
- 后续的需求变更,修改很麻烦且容易导致问题。
- 提取分隔更多小方法,我的原则是代码块存在复用,就提取为单独的方法。
- 方法內的相同功能逻辑块,if,switch,while 等,这些都是可以提取为更小方法的信号。
方法参数太多
- 方法的参数,原则上,大多数可以在其宿主类中获得。不能获得,考虑方法位置,职责是否符合实际。
- 参数实在太多,应该传递对象参数。
- 有个方法,过多的使用另外一个类数据,方法。此时应该把这个方法移动到那个类。
- 返回值有多个的方法,思考分隔为几个小方法,思考返回一个对象。
- 考虑,你取对象的属性作为一个方法的参数,对比直接传递这个对象?
- 考虑,调用一个方法获得返回值,然后把这返回值作为参数传给另一个方法,对比在另一个方法里直接调第一个方法?
- 考虑,有的方法参数总是一起传递,对比把一起传递的参数封装为一个对象?
- 函数返回值,尽量是确切类型,不要object,使用泛型很好。
- 关注,方法的输入
- 关注,方法內用到的对象字段
方法內局部变量太多
- 可以考虑,建立一个类,方法对象类。
- 局部变量,就变成类的私有字段。
- 原宿主类私有字段,通过原宿主对象传递。
- 再将原方法,进行提取为更多类的小方法。
方法不公开,就要私有
- 方法也是对象的成员,对象自己内部行为职责不必暴露,避免外部调用混乱。
通过功能分解分隔方法
- 功能分解是一种自然的处理复杂问题的方法,所谓大事化小,小事化了。
- 功能分解,大功能处理步骤,小功能处理步骤,小小功能处理步骤。
- 功能分解的问题,通常需要主程序控制子程序。
- 功能分解的问题,应对需求变化的无能为力。
代码发散式变化 代码散乱式变化
依恋情节
将数据和对数据的操作行为包装在一起。
数据泥团
a 字段,b 字段总是一起出现,a 参数,b 参数总是一起出现。 这种情况,就需要为 a,b 封装一个对象。
临时变量,不要重复赋值,重复赋值,说明变量的意图改变,当然除了在循环中。
不要给方法参数赋值。
忌过程耦合,忌封装性差。