设计思想之六大设计原则

六大设计原则

1.单一职责原则

定义:有且只有一个原因引起类的变更。

比如用户类中定义了用户属性和行为,应该把用户信息抽取成一个DO,行为抽象成Biz接口方法。

歧义点:有时为了适配单一职责原则,会将老接口一分为二,通过一个实现类去实现两个接口,可能会觉得实现类的引起变化原因有两个,

需要注意的是我们是面向接口编程,而不是面向实现类编程,对外暴露的是接口而不是实现类。

我的思考:生搬硬套单一职责会造成类的剧增,需要视情况而定,接口一定要做到单一原则,实现类与接口保持一直,一一对应比较好。

2.里氏替换原则

通俗的讲:只要父类能出现的地方子类就可以出现,而且替换为子类也不会产生任何错误或异常;反之,有子类出现的地方,父类未必就可以适应。

里氏替换原则为良好的继承定义了一个规范,包含了四层含义:

  1.子类必须完全实现父类的方法。在类中调用其他类时,务必使用父类或接口,如果不能使用父类或接口,则说明类的设计已经违背了LSP原则

  2.子类可以有自己的个性

  3.覆盖或者实现父类方法时输入参数要放大,否则会混淆。

  4.覆盖或实现父类方法时输出结果要缩小。

我的思考:接口内调用其他类时要使用父类,提高通用性,如果是子类,那么继承父类的其他子类无法使用,子类可以基于父类基础上,扩展自己的功能;3/4是1的保障。

3.依赖倒置原则

三层含义:

  1.高层模块不应该依赖底层模块,两者都应该依赖其抽象。(抽象即接口或抽象类)

  2.抽象不应该依赖细节。(细节即实现类)

  3.细节应该依赖抽象。

在java语言中的表现就是:

  1.模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系是通过接口或抽象类产生的。

  2.接口或抽象类不依赖于实现类。

  3.实现类依赖接口或抽象类。

我的思考:

  依赖正置:面向实现编程。

  依赖倒置:面向接口编程。

  举例:驾驶员驾驶汽车,如果只有一个奔驰汽车类,而不采取汽车类接口的方式,扩展性很差。

  1.业务开发时,对外暴露的功能一定尽可能具备接口或抽象类,这样才能实现测试开发等多端工作解耦。

  2.变量的表面类型尽量是接口或者抽象类。

  3.尽量不要从具体类中派生新的类,因为如果派生类可能会继承具体类中所有业务逻辑,一旦具体类需要修改,就需要同步测试旗下所有派生类。

4.接口隔离原则

  定义:类间的依赖关系应该建立在最小的接口上。

  我的思考

    1.接口尽量细化,面向业务开发,考虑通用性,比如定义了一个美女类接口,有面孔、身材、气质三个方法,但是随着审美的不同,可能气质并非定义美女的要素,那么继承美女类的接口就没必要实现气质方法,所以应该按照外貌和气质的维度拆分成两个接口,更加灵活。

    2.尽量保证接口的纯洁性,根据接口隔离原则拆分接口时,首先保障满足单一职责原则,否则会派生大量无用类。

    3.接口要高内聚,尽量减少public方法的透出,接口是对外的承诺,承诺越少,维护成本越低。

    4.一个接口只服务于一个子模块或业务逻辑。

5.迪米特法则

  即最少知识原则,一个对象应该对其他对象有最少的了解,通俗地讲,一个类应该对自己需要耦合或调用的类知道的最少,不需要关心被耦合的类的内部有多复杂的业务逻辑。

  我的思考:

    1.在系统设计时要进行反复衡量,是否还可以再减少public方法和属性,是否可以修改为private和package-private等访问权限,是否可以加上final关键字等。

    2.高内聚,低耦合

6.开闭原则

  一个软件实体如类,模块和函数应该对扩展开放,对修改关闭。  

  开闭原则对扩展开放,最修改关闭,并不意味着不做任何的修改,底层模块的变更,必然要有高层模块进行耦合,否则就是一个孤立无意义的代码片段。

  抽象约束:

    1.通过接口或抽象类约束扩展,对扩展进行边界限定,不允许出现接口或抽象类中不存在的public方法。

    2.引用对象尽量使用接口或抽象类,而不是实现类。

    3.抽象层尽量保持稳定,一旦确定不允许修改。

六大设计原则总结

  六大原则首字母联合起来是SOLID(稳定),建立稳定、灵活、健壮的系统设计,是我们每一个程序员的义务。

  接口设计层面:

    1.高内聚,低耦合,尽量减少public方法暴露。

    2.接口/抽象类是一种约定、一种契约,定义之后尽量不要进行修改。

    3.一个接口中的方法不要太多,在遵循单一职责原则基础上,按照接口隔离原则进行拆分,接口隔离是与业务相关的,比如要给外部运营商提供一个获取token的方法,但是这个方法所在的接口中还有其他十几个对运营商无意义的方法,如果运营商不小心实现了其中的方法并调用,会造成不必要的问题。

    4.接口设计尽量细化,不要把聚合太多的业务方法,虽然按照当前集团开发规则是一个接口对应一个实现类,但是如果遇到一个接口对应多个实现类,如果多个业务方法都聚合在一个接口中,就会违反接口隔离原则。

  方法内部设计层面:

    1.引用变量尽量使用抽象类/接口,遵循里氏替换原则。

    2.尽量内缩方法访问权限。

原文地址:https://www.cnblogs.com/insistence/p/12467157.html