关于依赖倒置,控制反转和依赖注入的趣谈

    昨天经过一朋友的SPACE,看到有关于控制反转的讨论,一时技痒,写下一段留言,完后由于比较长的时间没接触这几个单词,因此又去查了些资料,重新整理了一下,跟大家一起讨论。

   整理之前,首先要说说“依赖”,什么是依赖,依赖就是关联,UML中定义的“关联”是最泛泛的一种关系,表现为两个类图之间有根线就有关联,我个人理解成,在C/C++中,A include了另一个头文件B,JAVA/.Net中A using了另一个package或者unit B,则两者就有了关联,A依赖于B,因为假设没有依赖关系,A为啥要include B?肯定了发生了某种调用(B.Call())或者引用(如B做为某个类变量或者参数变量)。所以偶把这个理解成依赖。

   网上讨论的假设B发生变化那A也发生变化成为依赖,偶觉得可能会有一定的误导,因为假设变化的是B内部,接口不变,那A为什么要变?或者B增加一个接口A不调用,A也不用变,但是A依然依赖于B。

   这是关于依赖,接下来是关于标题三个名词,在这里不想一个个去解释,因为那可能有种就事论事的感觉,想跟大家讨论一些比较本质的东西。

   在面对一个复杂事务的时候,我们的处理办法是什么?毫无疑问是分解,想想那些日理万机的领导,凡事不论巨细都要过问的话那是不可能,因为个人的精力有限,而复杂度是随着规模的增大而呈数量级的变化的,所以领导怎么处理?分解,分成市场总监,财务总监,技术总监,行政总监等一个个角色,每个角色负责一块,到时候跟领导汇报各自的问题就OK了,领导来做决策。

      以软件来类比的话,这里的总监就是一个个模块,汇报就是OO中的接口(Interface),领导就是框架,把全部的模块串起来完成一个既定的大目标(如实现某个方案)。那工程师或者财务人员呢?毫无疑问就是一个个具体的CLASS了,是实现具体某个功能的执行体,如一项编程工作或者整理出某个报表。

    由此可见,每天在我们周围发生的这些事情,这些公司内部的一些行为都可以映射成整个软件构架。那么从公司的这种组织行为我们可以得到什么样的思考?首先有了分解我们可以降低一些的复杂度,但接下来呢,软件最复杂的在于什么?在于变化。公司也一样,外界要面临重重生存压力,内部可能会有一些公司层面的或者个人层面的问题,甚至人员跳槽也会带来一定的风险,那公司怎么处理? 隔离。把容易变化的跟不容易变化的相对稳定的隔离开来,这样就能做到控制影响到最小。那么隔离通过什么来实现?抽象。为什么?因为抽象是相对稳定的。

    这里举个比较好笑的例子:一个即将做领导的儿子问曾经做领导的父亲怎么才能平步青云,父亲说你不能说假话,因为老百姓会不答应,也不能说实话,因为领导会对你有意见,儿子思索良久问:那我该说什么? 父亲意味深长的说:空话

   笑话不但好笑,还能反映一定的道理,为啥空话这么有用,因为他是抽象的,而抽象不涉及到一些具体的数据或者事务,因此他是稳定的,是不容易变化的,同时基本上也是正确的。所以我们经常在公开场合听到类似的话“我们要团结同志,努力进取,提高工作效率,降低工作成本。。。”你能说这是错的吗,当然不能,所以既然是非常稳定的对的,所以这种依赖就很可靠啦。

   公司也一样,假设领导依赖于工程师的能力,成天问这个问那个,那如果有一天工程师跳槽了怎么办?领导处理的都是一些非常重要宏观的事务,不可能因为某个小小的工程师而产生什么大的影响,因此他不会直接依赖工程师,而是依赖于一个叫技术总监这样的一个抽象。如果工程师离职,那换个工程师继续替代他以前做的事情就行了,而且都实现的是技术总监规定好的接口,这样对领导就没什么影响了,也只有这样变化就被隔离开来了。

   再反过来想想软件,其实上面描述的都是一些对软件而言非常有意义的做法,OO中非常重要的一点就是模块之间依赖于抽象的接口,而不是具体的实现,为啥,因为抽象是相对稳定的。一个IO他必然就有READ/WRITE这两个抽象,至于具体是磁盘还是键盘,那是下面的实现不同了,通过这种构架,能保持软件的弹性与可维护性。

   由公司的行为还有一点容易受到启发的就是公司的组织构架,公司的层次可以映射成软件的分层,领导是框架层,下面通过一个个接口去管控一个个CLASS。我们设计软件的时候毫无疑问也应该这样。设计好框架设计接口,设计好接口再去调用一个个的API或者CLASS去实现某一个具体的实现比如数据库的读写或者SOCKET数据的收发。每个地方有自己相对对立的职责,各尽其职。如果上来就是一个个API,那相当于一大群工程师既做商务谈判,又去编码,那就杂乱无章啦。这样的结果感觉都是一样:混乱。

   最后言归正传,谈谈上面的三个名词,依赖倒置DIP(Dependency Inversion Principle)在马丁大叔的杰作《敏捷开发:原则,实践与模式》中描述的比较清楚,高层模块不应该依赖于底层模块,而应该两者都依赖于一个抽象,底层模块实现抽象。相信这点已经在上面讨论的比较清楚了,就好比尽管领导归根结底要依赖工程师来做事,但他不会直接依赖你,而是依赖于一个总监的抽象。这就是倒置,哪里倒了?这种依赖关系倒了,引入了一个新的中间层,一个抽象。以前传统的过程设计中是从上到下的一条依赖线,现在是平的一条领导到总监,然后是一条从下往上的工程师到总监的关联线。

  控制反转(Inversion of Control)其实有点类似,主要是OO中提出了框架的概念,什么是框架,按王氏兄弟的《道法自然》中的描述,主要是一个动态的环境体,可以处理一些比较复杂的事务或者逻辑,跟类库静态的行为不大一样,类库都是一个个等待别人调用的服务。 那么控制体现在什么地方?传统的做法,我们在自己的程序中调用一个个类库去完成一个个功能,类库是我们的执行体,但是逻辑算法等是自己实现的,这就是自己的控制,但框架不一样,逻辑算法都是它来实现,我们只要提供它几个需要的接口或者执行体就可。这就是反转,控制在框架这边了,主要是简化了一定的工作量,对于一些常见的业务场景不需要自己去重复实现罢了。那么控制反转主要应用的是模板方法等模式,个人觉得观察者模式是一个比较典型的控制发转的实例,因为论询observer是subject这边实现的一个逻辑,而observer 只要实现notify这样一个接口即可。所以其实也没什么。

   依赖注入(Dependency Injection)其实相比以上两者应该不是一个层次的概念,主要是表现为利用构造函数或者接口来完成具体的工作类的绑定而已,这么想好了,比如要完成一个开发工作,可以让总监自己去指定工程师甲来完成这个工作,但为了更大的弹性,可以让总监提供这么个接口

AssignJob(Engineer engineer) {engineer.do();}

这样总监可以默认让甲去完成这个工作,但如果某种原因例如甲请假,那么就可以通过这个接口去让乙去做这件事情,这样在发生变化的时候就有弹性了。顺便提一下,软件多数通过CONFIG来达到更大的灵活性,由于.NET/JAVA等引入了反射的概念,可以在RUNTIME期间动态的去创建类,这个功能就很强大了,参考如上的业务需求,我们就可以把类名放在CONFIG中,通过反射去加载不同的类从而完成不同的实现。这也是很多框架(如structs)的最基本的做法

    以上是一些个人看法,感觉一些OO的名词听起来玄乎,其实也就那么回事,只要掌握好OO的几个基本原则,其实基本上都可以推导出来。呵呵。个人愚见,希望跟大家交流

 

   附上王氏兄弟的更精彩精辟的讲解:http://www.contextfree.net/wangyw/source/dip_ioc.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
### 回答1: 网络协议是计算机网络中进行数据传输和通信的规则和约定。PDF(Portable Document Format)是一种由Adobe开发的文件格式,用于以可靠的方式呈现和交换电子文档。 在谈论网络协议的PDF下载时,我们可以探讨以下趣闻: 首先,网络协议的PDF下载可以帮助我们更好地理解和学习网络协议。网络协议本身是一种抽象的概念,有时候很难通过文字或图片来完全理解。但是,通过以PDF格式提供的文档,我们可以更直观地看到网络协议的结构、流程和细节,使得学习变得更加容易和有趣。 其次,网络协议的PDF下载还能帮助我们及时了解和跟进最新的协议标准。网络协议是一门不断发展的学科,新的协议版本和标准经常被提出和更新。通过及时下载最新的协议文档,我们可以了解最新的协议规范和改进,从而更好地应用它们于实际网络环境中。 此外,网络协议的PDF下载也给了我们方便地和他人共享学习资源的机会。通过将网络协议的文档以PDF格式发布在互联网上,任何人都能够自由下载和阅读,促进了知识的传播和共享。在学术和研究领域,这种方式也为学者们提供了方便的途径来分享最新的网络协议研究成果。 总之,网络协议的PDF下载不仅能够促进我们更好地理解和学习网络协议,还能帮助我们及时了解最新的协议标准,并且方便地与他人共享学习资源。无论是对于专业人员还是对于普通用户,网络协议的PDF下载都具有重要的意义和趣味性。 ### 回答2: 网络协议是计算机网络中的基础,它定义了数据在网络中传输的规则和方式。网络协议可以确保数据的可靠传输,有效地管理网络资源,并实现各种网络应用功能。 趣谈网络协议是一本介绍网络协议的有趣读物,可以以轻松、幽默的方式解释复杂的网络协议概念和原理。这本书通常以PDF格式提供下载,方便读者在任何设备上阅读。 下载这本书的PDF版本,可以享受以下好处: 首先,PDF格式具有跨平台和跨设备的特点。不论您使用的是电脑、平板还是手机,只要安装了合适的PDF阅读器软件,就可以轻松打开并阅读这本书。 其次,下载PDF可以实现离线阅读。无论您身处何地,只要下载好了PDF文件,即便没有网络连接,也可以随时随地阅读网络协议的趣谈故事。 此外,PDF格式使得阅读更加方便。您可以在PDF阅读器中进行文字搜索、加注释、划重点,甚至可以调整字号的大小,以适应不同的阅读环境。 最后,通过下载PDF,您还可以将这本书保存到自己的电脑或移动设备上,以备日后参考。您可以在需要的时候,随时翻阅这本书,方便复习和查找相关内容。 总之,趣谈网络协议PDF的下载为我们提供了方便、快捷、随时随地的阅读体验。无论是想了解网络协议,还是希望在计算机网络领域深入学习,这本书都会是一本有趣而又实用的读物。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xrbeck

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值