整洁架构SOLID-依赖反转原则(DIP)

[复制链接]
发表于 2026-2-20 22:44:25 | 显示全部楼层 |阅读模式
界说

依赖反转原则(DIP)紧张想告诉我们的是:
   假如想要操持一个机动的体系,在源代码条理的依赖关系中就应该多引用抽象范例,而非具体实现。
  也就是说,在Java这类静态范例的编程语言中,在使用use、import、include这些语句时应该只引用那些包罗接口、抽象类大概其他抽象范例声明的源文件,不应该引用任何具体实现。
同样的,在Ruby、Python这类动态范例的编程语言中,我们也不应该在源代码条理上引用包罗具体实现的模块。固然,在这类语言中,究竟上很难清楚界定某个模块是否属于“具体实现”。
String类

显而易见,把这条操持原则当成金科玉律来加以严格实行是不现实的,由于软件体系在现实构造中不可制止地必要依赖到一些具体实现。比方,Java中的String类就是如许一个具体实现,我们将其逼迫转化为抽象类是不现实的,而在源代码条理上也无法制止对java.lang.String的依赖,而且也不应该实验去制止。
String类自己黑白常稳固的,由于这个类被修改的情况黑白常稀有的,而且可修改的内容也受到严格的控制,以是步调员和软件架构师完全不必担心String类上会发生经常性的或料想之外的修改。
同理,在应用DIP时,我们也不必思量稳固的操纵体系大概平台办法,由于这些体系接口很少会有变更。
我们紧张应该关注的是软件体系内部那些会经常变更的(volatile)具体实现模块,这些模块是不绝开发的,也就会经常出现变更。
稳固的抽象层

我们每次修改抽象接口的时间,肯定也会去修改对应的具体实现。但反过来,当我们修改具体实现时,却很少必要去修改相应的抽象接口。以是我们可以以为接口比实现更稳固。
精良的软件操持师和架构师会泯灭很大精力来操持接口,以淘汰未来对其举行改动。究竟夺取在不修改接口的情况下为软件增长新的功能是软件操持的底子知识。
也就是说,假如想要在软件架构操持上寻求稳固,就必须多使用稳固的抽象接口,少依赖多变的具体实现。下面,我们将该操持原则归结为以下几条具体的编码守则:


  • 应在代码中多使用抽象接口,只管制止使用那些多变的具体实现类。这条守则实用于全部编程语言,无论静态范例语言照旧动态范例语言。同时,对象的创建过程也应该受到严格限定,对此,我们通常会选择用抽象工厂(abstract factory)这个操持模式。
  • 不要在具体实现类上创建衍生类。在静态范例的编程语言中,继承关系是全部齐备源代码依赖关系中最强的、最难被修改的,以是我们对继承的使用应该格外警惕。纵然是在稍微便于修改的动态范例语言中,这条守则也应该被认真思量。
  • 不要覆盖(override)包罗具体实现的函数。调用包罗具体实现的函数通常就意味着引入了源代码级别的依赖。纵然覆盖了这些函数,我们也无法消除这此中的依赖——这些函数继承了那些依赖关系。在这里,控制依赖关系的唯一办法,就是创建一个抽象函数,然后再为该函数提供多种具体实现。
  • 应制止在代码中写入与任何具体实现相干的名字,大概是其他容易变更的事物的名字。这根本上是DIP原则的别的一个表达方式。
工厂模式

假如想要服从上述编码守则,我们就必须要对那些易变对象的创建过程做一些特殊处理处罚,如许的审慎是很有须要的,由于根本在全部的编程语言中,创建对象的操纵都免不了必要在源代码条理上依赖对象的具体实现。
在大部门面向对象编程语言中,人们都会选择用抽象工厂模式来办理这个源代码依赖的标题。
如下图,形貌该操持模式的结构。如你所见,Application类是通过Service接口来使用ConcreteImpl类的。然而,Application类照旧必须要构造ConcreteImpl类实例。于是,为了制止在源代码条理上引入对ConcreteImpl类具体实现的依赖,我们如今让Application类去调用ServiceFactory接口的makeSvc方法。这个方法就由ServiceFactoryImpl类来具体提供,它是ServiceFactory的一个衍生类。该方法的具体实现就是初始化一个ConcreteImpl类的实例,而且将其以Service范例返回。

上图中心的那条曲线代表了软件架构中的抽象层与具体实现层的界限。在这里,全部超过这条界限源代码级别的依赖关系都应该是单向的,即具体实现层依赖抽象层。
这条曲线将整个体系分别为两部门组件:抽象接口与其具体实现。


  • 抽象接口组件中包罗了应用的全部高阶业务规则。
  • 而具体实现组件中则包罗了全部这些业务规则所必要做的具体操纵及其相干的细节信息。
   这里的控制流超过架构界限的方向与源代码依赖关系超过该界限的方向恰好相反,源代码依赖方向永世是控制流方向的反转——这就是DIP被称为依赖反转原则的缘故因由
  具体实现组件

在抽象工厂操持图中具体实现组件的内部仅有一条依赖关系,这条关系实在是违背DIP的。这种情况很常见,我们在软件体系中并不大概完全消除违背DIP的情况。通常只必要把它们会合于少部门的具体实现组件中,将其与体系的其他部门隔离即可
绝大部门体系中都至少存在一个具体实现组件——我们一样寻常称之为main组件,由于它们通常是main函数所在之处。在抽象工厂操持图中,main函数应该负责创建ServiceFactoryImpl实例,并将其赋值给范例为ServiceFactory的全局变量,以便让Application类通过这个全局变量来举行相干调用。
小结

在体系架构图中,DIP通常是最显而易见的构造原则。抽象工厂操持图中的那条曲线称为架构界限,而超过界限的、朝向抽象层的单向依赖关系则会成为一个操持守则——依赖守则。
   参考内容泉源于:《架构整洁之道》

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!qidao123.com:ToB企服之家,中国第一个企服评测及软件市场,开放入驻,技术点评得现金

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表