架构师训练营 - 第二章 - 依赖倒置原则 & 接口隔离原则
面向对象的六大原则
1·单一职责原则
2·开闭原则
3·里氏替换原则
4·依赖倒置原则
5·接口隔离原则
6·最少知识原则(迪米特原则)
依赖倒置原则
依赖倒置原则要求业务程序要依赖抽象的接口,不能依赖具体的实现。
我们理解接口是一个契约规范,是稳定的,不会变化的。基于接口可以有很多的实现类,这些实现类都遵循接口的定义,实现类是多样的,代表经常变动的业务细节。
应用程序依赖于某个接口,只要实现了这个接口的类都可以被应用程序使用,这样的程序不会因为依赖的变更而需要对自己做调整。
依赖接口的程序,需要外界将具体实现类注入到程序中,而不是自己去实现,这就类似好莱坞的“don’t call me,i call you”。
开发框架中依赖导致原则的实践
目前大部分新的开发框架都实现了依赖注入组件,比如php的hyperf、laravel、thinkphp5+ ,或者java的springboot。
依赖注入组件的核心职责是,给程序提供依赖管理。程序所依赖的接口都通过组件统一注入,不需要业务程序自己去实现。
只需要在框架中统一声明接口的实现类,当程序中依赖该接口的地方,框架就会将该类统一注入。
框架举例
以我常用的hyperf举例。
如果我有一个接口A,目前的实现是类AImp。
那么我需要在框架的配置 ./config/autoload/dependencies.php 中声明接口对应的实现关系。
然后在需要接口的业务类中,就可以在构造函数的参数上声明接口依赖(利用注解也可以),框架会自动将对应的实现类注入到程序中。
接口隔离原则
接口隔离原则要求业务程序不要依赖自己不需要的接口。
这和迪米特原则有相似概念。通常情况下,我们认为一个高内聚、低耦合,且符合开闭原则的设计是一个好的设计,至少在面对程序变更时,能以最小的代价满足系统的变化。
接口设计的时候应该尽量的小,那么依赖该接口的类不会访问到不需要的逻辑,减少受变更影响的可能性。
接口隔离举例
案例:有一个Cache类,有get、put、delete、rebuild方法。
现在要求业务类在使用该类的时候只能访问get、put、delete方法,rebuild 的方法不能被业务类使用。
原始的做法是,直接在程序中实现一个Cache类,在需要用到Cache类的地方直接实例化Cache类。
但是这样是做不到隔离的,业务类中可以任意的访问reBuild方法,这不符合我们的要求,也不符合接口隔离原则和依赖导致原则。
我们将设计重新调整,声明一个Cache接口,包含get、put、delete方法,声明一个CacheRebuild 接口,包含reBuild方法。类Cache实现了Cache和CacheRebuild 两个接口。
业务类依赖Cache接口,而不是具体的Cache类,如下图。
调整完之后,业务类不再依赖具体的Cache实现,能更好的适应Cache具体实现的变化,同时也做到了接口隔离。
评论