会修电脑不会修收音机?–依赖倒转原则

继上一篇“设计模式之开放-封闭原则”后,本文继续讲解《大话设计模式》第五章“会修电脑不会修收音机?--依赖倒转原则”。喜欢本书请到各大商城购买原书,支持正版。

1 MM请求修电脑

时间:3月12日 19点 地点:小菜大鸟住所的客厅 人物:小菜、大鸟、娇娇

小菜和大鸟吃完晚饭后,在一起聊天。

此时,突然声音响起。

“死了都要爱,不淋漓尽致不痛快,感情多深只有这样,才足够表白。死了都要爱……”

原来是小菜的手机铃声,大鸟吓了一跳,说道:“你小子,用这歌做铃声,吓唬人啊!这要是在公司开大会时响起,你要被领导淋漓尽致爱死! MD,还在唱,快接!”

小菜很是郁闷,拿起手机一看,一个美女来的电话,脸色由阴转晴,马上接通了手机:“喂!”

“小菜呀,我是娇娇,我电脑坏了,你快点帮帮我呀!”手机里传来急促的女孩声音。

“哈,是你呀,你现在好吗?最近怎么不和我聊天了?”小菜慢条斯理地说道。

“快点帮帮我呀,电脑不能用了啊!”娇娇略带哭腔地说。

“别急别急,怎么个坏法?”

“每次打开QQ,一玩游戏,机器就死了。出来蓝底白字的一堆莫名其妙的英文,过一会就重启了,再用QQ还是一样。怎么办呀?”

“哦,明白了,蓝屏死机吧,估计内存有问题,你的内存是多少兆的?”

“什么内存多少兆,我听不懂呀,你能过来帮我修一下吗?”

“啊,你在金山,我在宝山,虽说在上海这两地名都钱味儿十足,可两山相隔万重路呀!现在都晚上了,又是星期一,周六我去你那里帮你修吧!”小菜无奈地说。

“要等五天那不行,你说什么蓝屏?怎么个修法?”娇娇依然急不可待。

“蓝屏多半是内存坏了,你要不打开机箱看看,或许有两个内存,可以拔一根试试,如果只有一根内存,那就没戏了。”

“机箱怎么打开呢?”娇娇开始认真起来。

“这个,你找机箱后面,四个角应该都有螺丝,卸掉靠左侧边上两个应该就可以打开左边盖了。”小菜感觉有些费力,远程手机遥控修电脑,这是头一次。

“我好像看到了,要不先挂电话,我试试看,打开后再打给你。”

“哦,好的。”小菜正说着,只听娇娇边嘟囔着“老娘就不信收拾不了你这破电脑”边挂掉了电话。

“呵!”小菜长出一口气,“不懂内存为何物的美眉修电脑,强!”

“你小子,人家在困难时刻想得到你,说明心中有你,懂吗?这是机会!”大鸟说道。

“这倒也是,这小美眉长得蛮漂亮的,我看过照片。就是脾气大些,不知道有没有男朋友了。”

“切,你干吗不对她说,‘你可以找男友修呀’,真是没脑子,要是有男友,就算男友不会修也要男友找人搞定,用得着找你求助呀,笨笨!”大鸟嘲笑道,“你快把你那该死的手机铃声换掉——死了都要爱,死了还爱个屁!”

“噢!知道了。”

2 电话遥控修电脑

十分钟后。

“我在这儿等着你回来,等着你回来,看那桃花开。我在这儿等着你回来,等着你回来,把那花儿采……”小菜的手机铃声再次响起。

“菜花痴,你就不能找个好听的歌呀。”大鸟气着说道。

“好好好,我一会改,一会改。”小菜拿起手机,一副很听话的样子,嘴里却跟着哼“我在这儿等着你回来哎”,把手机放到耳边。

“小菜,我打开机箱了,快说下一步怎么走!”娇娇仍然着急着说。

“你试着找找内存条,大约是10公分长,2公分宽,上有多个小长方形集成电路块的长条,应该是竖插着的。”小菜努力把内存条的样子描述得容易理解。

“我看到一个风扇,没有呀,在哪里?”娇娇说道,“哦,我找到了,是不是很薄,很短的小长条?咦,怎么有两根?”

“啊,太好了,有两根估计就能解决问题了,你先试着拔一根,然后开机试试看,如果还是死机,再插上,拔另一根试,应该总有一根可以保证不蓝屏。”

“我怎么拨不下来呢?”

“旁边有卡子,你扳开再试。”

“嗯,这下好了,你别挂,我这就重启看看。”

五分钟后。

“哈,没有死机了啊,小菜,你太厉害了,我竟然可以修电脑了,要我怎么感谢你呢!”娇娇兴奋地说。

“做我女朋友吧,”小菜心里这么遐想着,口中却谦虚地说:“不客气,都是你聪明,敢自己独自打开机箱修电脑的女孩很少的。你把换下的内存去电脑城换掉,就可以了。”

“我不懂的,要不周六你帮我换?周六我请你吃饭吧!”

“这怎么好意思─—你说在什么时间在哪碰面?”小菜假客气着,却不愿意放弃机会。“

周六下午5点在徐家汇太平洋数码门口吧。”

“好的,没问题。”

“今天真的谢谢你,那就先Bye-Bye了!”

“嗯,拜拜!”

3 依赖倒转原则

“小菜走桃花运了哦,”大鸟有些羡慕道,“那铃声看来有些效果,不过还是换掉吧,俗!”

“嘿嘿,你说也怪,修电脑,这在以前根本不可能的事,怎么就可以通过电话就教会了,而且是真的修到可以用了呢。”

“你有没有想过这里的最大原因?”大鸟开始上课了。

“蓝屏通常是内存本身有问题或内存与主板不兼容,主板不容易换,但内存更换起来很容易。”

“如果是别的部件坏了,比如硬盘,显卡,光驱等,是否也只需要更换就可以了?”

“是呀,确实很方便,只需要懂一点点计算机知识,就可以试着修电脑了。”

“想想这和我们编程有什么联系?”

“你的意思又是——面向对象?”

“嗯,说说看,面向对象的四个好处?”

“这个我记得最牢了,就是活字印刷那个例子呗。是可维护、可扩展、可复用和灵活性好。哦,我知道了,可以把PC电脑理解成是大的软件系统,任何部件如CPU、内存、硬盘、显卡等都可以理解为程序中封装的类或程序集,由于PC 易插拔的方式,那么不管哪一个出问题,都可以在不影响别的部件的前提下进行修改或替换。”

“PC电脑里叫易插拔,面向对象里把这种关系叫什么?”

“应该是叫强内聚、松耦合吧。”

“对的,非常好,我们电脑里的CPU全世界也就是那么几家生产的,大家都在用,但却不知道Intel、AMD等公司是如何做出这个精密的小东西的。去年国内不是还出现了汉芯造假的新闻吗!这就说明CPU的强内聚的确是强。但它又独自成为了产品,在千千万万的电脑主板上插上就可以使用,这是什么原因?”大鸟又问。

“因为CPU的对外都是针脚式或触点式等标准的接口。啊,我明白了,这就是接口的最大好处。CPU只需要把接口定义好,内部再复杂我也不让外界知道,而主板只需要预留与CPU针脚的插槽就可以了。”

“很好,你已经在无意的谈话间提到了面向对象的几大设计原则,比如我们之前讲过的单一职责原则,就刚才修电脑的事,显然内存坏了,不应该成为更换CPU的理由,它们各自的职责是明确的。再比如开放-封闭原则,内存不够只要插槽足够就可以添加,硬盘不够可以用移动硬盘等,PC的接口是有限的,所以扩展有限,软件系统设计得好,却可以无限地扩展。这两个原则我们之前都已经提过了。这里需要重点讲讲一个新的原则,叫依赖倒转原则,也有翻译成依赖倒置原则的。”大鸟接着讲道,“依赖倒转原则,原话解释是抽象不应该依赖细节,细节应该依赖于抽象,这话绕口,说白了,就是要针对接口编程,不要对实现编程,无论主板、CPU、内存、硬盘都是在针对接口设计的,如果针对实现来设计,内存就要对应到具体的某个品牌的主板,那就会出现换内存需要把主板也换了的尴尬。你想在小MM面前表现也就不那么容易了。所以说,PC电脑硬件的发展,和面向对象思想发展是完全类似的。这也说明世间万物都是遵循某种类似的规律,谁先把握了这些规律,谁就最早成为了强者。”

依赖倒转原则

  • A.高层模块不应该依赖低层模块。两个都应该依赖抽象。
  • B.抽象不应该依赖细节。细节应该依赖抽象。

“为什么要叫倒转呢?”小菜问道。

“这里面是需要好好解释一下,面向过程的开发时,为了使得常用代码可以复用,一般都会把这些常用代码写成许许多多函数的程序库,这样我们在做新项目时,去调用这些低层的函数就可以了。比如我们做的项目大多要访问数据库,所以我们就把访问数据库的代码写成了函数,每次做新项目时就去调用这些函数。这也就叫做高层模块依赖低层模块。”

会修电脑不会修收音机?--依赖倒转原则

“嗯,是这样的,我以前都是这么做的。这有什么问题?”

“问题也就出在这里,我们要做新项目时,发现业务逻辑的高层模块都是一样的,但客户却希望使用不同的数据库或存储信息方式,这时就出现麻烦了。我们希望能再次利用这些高层模块,但高层模块都是与低层的访问数据库绑定在一起的,没办法复用这些高层模块,这就非常糟糕了。就像刚才说的,PC里如果CPU、内存、硬盘都需要依赖具体的主板,主板一坏,所有的部件就都没用了,这显然不合理。反过来,如果内存坏了,也不应该造成其他部件不能用才对。而如果不管高层模块还是低层模块,它们都依赖于抽象,具体一点就是接口或抽象类,只要接口是稳定的,那么任何一个的更改都不用担心其他受到影响,这就使得无论高层模块还是低层模块都可以很容易地被复用。这才是最好的办法。”

“为什么依赖了抽象的接口或抽象类,就不怕更改呢?”小菜依然疑惑,“不好意思,我有些钻牛角尖了。”

“没有,没有,在这里弄不懂是很正常的,原因是我少讲了一个设计原则,使得你产生了困惑,这个原则就是里氏代换原则。”

4 里氏代换原则

“里氏代换原则是Barbara Liskov女士在1988年发表的,具体的数学定义比较复杂,你可以查相关资料,它的白话翻译就是一个软件实体如果使用的是一个父类的话,那么一定适用于其子类,而且它察觉不出父类对象和子类对象的区别。也就是说,在软件里面,把父类都替换成它的子类,程序的行为没有变化,简单地说,子类型必须能够替换掉它们的父类型。”

里氏代换原则(LSP):子类型必须能够替换掉它们的父类型。

“这好像是学继承时就要理解的概念,子类继承了父类,所以子类可以以父类的身份出现。”

“是的,我问你个问题,如果在面向对象设计时,一个是鸟类,一个是企鹅类,如果鸟是可以飞的,企鹅不会飞,那么企鹅是鸟吗?企鹅可以继承鸟这个类吗”

“企鹅是一种特殊的鸟,尽管不能飞,但它也是鸟呀,当然可以继承。”

“哈,你上当了,我说的是在面向对象设计时,那就意味着什么呢?子类拥有父类所有非 private的行为和属性。鸟会飞,而企鹅不会飞。尽管在生物学分类上,企鹅是一种鸟,但在编程世界里,企鹅不能以父类——鸟的身份出现,因为前提说所有鸟都能飞,而企鹅飞不了,所以,企鹅不能继承鸟类。”

会修电脑不会修收音机?--依赖倒转原则

“哦,你的意思我明白了,我受了直觉的影响。小时候上课时老师一再强调,像鸵鸟、企鹅等不会飞的动物也是鸟类。”

“也正因为有了这个原则,使得继承复用成为了可能,只有当子类可以替换掉父类,软件单位的功能不受到影响时,父类才能真正被复用,而子类也能够在父类的基础上增加新的行为。比方说,猫是继承动物类的,以动物的身份拥有吃、喝、跑、叫等行为,可当某一天,我们需要狗、牛、羊也拥有类似的行为,由于它们都是继承于动物,所以除了更改实例化的地方,程序其他处不需要改变。”

会修电脑不会修收音机?--依赖倒转原则

“我的感觉,由于有里氏代换原则,才使得开放-封闭成为了可能。”小菜说。

“这样说是可以的,正是由于子类型的可替换性才使得使用父类类型的模块在无需修改的情况下就可以扩展。 不然还谈什么扩展开放,修改关闭呢。再回过头来看依赖倒转原则,高层模块不应该依赖低层模块,两个都应该依赖抽象,对这句话你就会有更深入的理解了。”

会修电脑不会修收音机?--依赖倒转原则

“哦,我明白了,依赖倒转其实就是谁也不要依靠谁,除了约定的接口,大家都可以灵活自如。还好,她没有问我如何修收音机,收音机里都是些电阻、三极管,电路板等等东东,全都焊接在一起,我可不会修的。”小菜庆幸道。

5 修收音机

“哈,小菜你这个比方打得好,”大鸟开心地说,“收音机就是典型的耦合过度,只要收音机出故障,不管是没有声音、不能调频,还是有杂音,反正都很难修理,不懂的人根本没法修,因为任何问题都可能涉及其他部件,各个部件相互依赖,难以维护。非常复杂的PC电脑可以修,反而相对简单的收音机不能修,这其实就说明了很大的问题。当然,电脑的所谓修也就是更换配件,CPU或内存要是坏了,老百姓是没法修的。现在在软件世界里,收音机式的强耦合开发还是太多了,比如前段时间某银行出问题,需要服务器停机大半天的排查修整,这要损失多少钱。如果完全面向对象的设计,或许问题的查找和修改就容易得多。依赖倒转其实可以说是面向对象设计的标志,用哪种语言来编写程序不重要,如果编写时考虑的都是如何针对抽象编程而不是针对细节编程,即程序中所有的依赖关系都是终止于抽象类或者接口,那就是面向对象的设计,反之那就是过程化的设计了。”

“是的是的,我听说很多银行目前还是纯C语言的面向过程开发,非常不灵活,维护成本是很高昂的。”

“那也是没办法的,银行系统哪是说换就换的,所以现在是大力鼓励年轻人学设计模式,直接面向对象的设计和编程,从大的方向上讲,这是国家大力发展生产力的很大保障呀。”

“大鸟真是高瞻远瞩呀,我对你的敬仰犹如滔滔江水,连绵不绝!”小菜怪笑道,“我去趟WC”。

“浪奔,浪流,万里江海点点星光耀,人间事,多纷扰,化作滚滚东逝波涛,有泪,有笑……”

“小菜,电话。小子,怎么又换成新上海滩的歌了,这歌好听。”大鸟笑道,“刚才是死了都要爱,现在是为爱复仇而死。你怎么找的歌都跟爱过不去呀。快点,电话,又是刚才那个叫娇娇的小MM的。”

“来了来了,尿都只尿了一半!”小菜心急地接起电话,“喂!”

“小菜呀,我家收音机坏了,你能不能教我修修呢!”

下一篇我们接着读“第6章 穿什么有这么重要?——装饰模式 ”,欢迎关注微信公众号【乐趣课堂】。

原文出处:微信公众号【乐趣课堂】

原文链接:

本文观点不代表Dotnet9立场,转载请联系原作者。

发表评论

登录后才能评论