ZucchinY

Single responsibility principle 单一职责原则

原理

一个类应该仅仅只有一个被修改的理由,也就是一个类只有一个职责;而不是一种功能。

缺点

  1. 因为不同原因修改类的时候,也可能因为不相关的修改导致功能间的相互影响。
  2. 单个类承担的职责越多,意味着类的复杂度也就越高,维护成功也就越高。

如何解决

  1. 拆分大类为多个小类
  2. 将一些功能抽取为公共的函数

Open-closed principle 开放-关闭原则

原理

类应该对扩展开放,对修改封闭;应该可以在不修改某个类的前提下,扩展它的行为。

改造方法

使用类继承来改造代码

找到你类中会变动的部分,将其抽象成新的方法或者属性,最终允许新的子类来重写它以改变类似的行为。

使用组合与信赖注入来改造代码

将需要变化的内容,抽象为类,并将不同的原则实现不同的类,在调用主类进行操作的时间,不同的继承结果会让类有不同的变化,但是这种方案,并不会修改主类,因为接受的类型为变化的类的祖先,也就是保证的类的不变,但是传入的内容变化却是变的。

使用数据驱动思想来改造代码

数据驱动也就是将经常变化的东西完全以数据的方式抽离出来,当需求变动时,只改动数据,代码逻辑保持不变。

三种方案的区别

类继承与依赖注入方式的区别

两个原则都运用了继承来优化代码,第一个方案重点在于扩展类的行为,但是又保证父类的行为不变;第二种方案是将扩展行为的变量抽象出来,类本身的行为一直没有变化,主要都是接受抽象出来的类进行变化,保证可变量才能变。这种明显比第一种方案更为优越。但是理解和拆分也更有难度。

依赖注入与数据驱动方式的区别

依赖注入和数据驱动的两种改造方案非常相似,主要方案就是将变的内容抽离到类的外部,区别主要在于依赖注入主要是抽离类,通过类的变化来控制行为变化,而数据驱动抽离的是数据内容。

数据驱动的特点

与继承和依赖注入方式相比,数据驱动更简洁,不需地定义额外的类,但是同样也不缺点,也就是数据都是既定的内容,如果是传入的内容本身就是一种形态,数据的方案也就不可靠了。在使用中可以认为,如果是既定内容,可以简单的使用数据驱动来做,如果是某种类型,使用扩展类(依赖注入、类继承)的方式更好用。

Liskov Substitution Principle 里氏替换原则

特点

  1. 继承、多态与封装,属于面向对象编程的几大核心特征。里氏替换原则对继承有指导意义。
  2. 使用继承时,子类对象应该可以在程序中替代父类对象使用,而不破坏程序原本的功能。
  3. 尽量将可变的行为做为类的一个属性(可变),并提供方法可以修改这个行为。
  4. 需要让子类方法和父类方法返回同一类型的结果,支持同样的操作。或者更进一步,返回支持更多种操作的子类型结果也是可以授受的。
  5. 子类方法参数应该和父类方法同名方法完全一致,或者更为宽松。

Interface Segregation Principle 接口隔离原则

什么是接口

接口是模块间相互交流的抽象协议。

遵守的原则

  1. 客户(client)应该不依赖于它不使用的方法。
  2. 一个接口所提供的方法,应该就是使用方所需要的方法。而更多的接口方法意味着更高的实现成本,给实现方带来更多的出错机率。
  3. 让客户(调用方)来驱动协议设计。在有多余的依赖时,找出最小类,然后依据不同的依赖关系,继承出更小的类。

Dependency Inversion Principle 依赖倒置原则

特征

  1. 高层模块不应该依赖于低层模块,二者都应该依赖于抽象。
  2. 通过编写测试反向推动设计改进。
  3. 抽象解耦了高层模块和低层模块间的依赖关系,让代码更灵活。但抽象同时也带来了额外的编程与理解成本。而只有对代码中现在或者未来会发生变化的东西进行抽象,才能获得最大的利益。