接口设计原则有很多,这里总结出最主要的六种:
一、SRP 单一职责原则
定义:应该有且仅有一个原因引起类的变更。There should never be more than one reason for a class to change。
注意:
用职责或变化原因来衡量接口或类,但职责或变化原因都是不可度量的,因项目而异。
不能为了单一而单一,实现类就剧增了,或者使用聚合和组合,人为制造了系统的复杂性。
二、里氏替换原则
字义:只要父类能出现的地方子类都可以出现,而且替换为子类也不会产生任何错误或异常。
含义:1.子类必须完全实现父类的方法;
2.如果子类不能完整地实现父类的方法,或者父类的某些方法在子类中已经发生“畸变”,则建议断开父子继承关系,采用依赖,聚合或组合等关系代替继承。
3.覆盖或实现父类的方法时输入参数可以被放大。
4.覆盖或实现父类的方法时输出结果可以被缩小。
注意:尽量避免子类的“个性”。要知道什么时候弃用父子关系。
三、DIP依赖倒置原则
定义:高层模块不应该依赖底层模块,抽象不应该依赖细节,细节应该依赖抽象。High level modules should not depend upon low level modules.Both should depend upon abstractions.Abstractins should not depend upon details.Details should depend upon abstractions. 或者这样定义:OOP面向接口编程。DIP本质是通过抽象使各个类或模块彼此独立。
注意:
稳定性较高的设计,在周围环境频繁变化的时候,依然可以做到“我自岿然不动”。
使用DIP后,可以进行并行开发。可以TDD。
尽量不要覆写基类方法。
结合里氏替换原则。
该原则在小项目中很难体现。项目越大,需求变化的概率也越大。
如何做:
构造函数传递依赖对象,Setter方法传递依赖对象,接口声明依赖对象。
四、接口隔离原则
定义:客户端不应该依赖它不需要的接口。类间的依赖关系应该建立在最小的接口上。
注意:
建立单一接口,不要建立臃肿庞大的接口。即接口尽量细化,同时接口中的方法尽量少。
与单一职责审视角度不同。单一职责注重的是职责,是业务逻辑上的划分。首先要满足单一职责原则。
设计是有限度的,不能无限地考虑未来的变更情况,否则会陷入设计的泥潭。
尽量少公布public方法。要高内聚。
深入了解业务逻辑,最好的接口才能设计出来。
五、迪米特法则Least Knowledge Principle
定义:一个对象应该对其它对象有最少的了解。一个类应该只与朋友类交流。
六、OCP开闭原则
定义:对扩展开放,对修改封闭。Software entities like classes,modules and functions should be open for extension but closed for modifications.
地位:开闭原则是最基础的一个原则,是上面五个原则的精神领袖。因为那五个原则是开闭原则的具体形态。因为开闭原则对测试有影响,上线的代码经过层层把关,能不改的就不改,宁愿扩展一些新代码。这样测试工作量就少很多。再因为开闭原则可以提高可维护性。
注意:
开闭原则并不意味着不做任何修改,底层模块的变更,必然要有高层模块进行耦合。故高层模块可以因底层模块的扩展而稍作修改。
开闭原则只要是做oop的都应遵循。
如果做:
面向接口编程,抽象层要保持稳定性。
封闭变化:将相同的变化封闭到一个接口或抽象类中,不同的变化封闭到不同的接口或抽象类中。封装预计有变化或不稳定的需求点。
七、总结
软件设计最大的难题就是应对需求的变化。