迪米特法则理解+感悟

初识

迪米特法则:一个类应该只和与它有直接关系的类通信,即只和直接朋友来往,并且对朋友了解的最少。

一、只和直接朋友来往

首先我们需要明确,什么是直接朋友(从依赖类的角度说明)
1、 类对象中引入的成员变量对象
2、 对象方法中作为参数传入的外部对象
3、 对象方法中作为返回值的类对象
4、 对象方法中声明的外部类对象
总结:一个类中用到的本类之外的所有外部类对象,都可以作为这个类的朋友。

那什么样的类可以作为直接朋友呢?(从被依赖类的角度说明)
举个例子,客户端想获得天气的温度,这里有一个气象局类还有一个温度计类,如下:
在这里插入图片描述

第一种方法是这样:我们先在client中获得station类,调用getThermometer()方法,拿到温度计,再调用温度计的getTemperature()方法拿到温度。这样操作的话,station类和thermometer类就都是client的朋友了,它需要维护与两个朋友的关系。如果以这样的形式,client还想获得空气湿度、风速等信息怎么办?
在这里插入图片描述

看到上面的图我们发现,client的朋友越来越多了,它需要维护的关系也越来越多了。如果哪天某些朋友做了变动或者修改,必须通知到client对象,这样client对象就显得任务繁琐了,这种设计使得类与类之间的耦合非常严重。

我们回到业务中想一下,温度、湿度、风速,这些对象都有一个共同的特征,他们都是属于气象类,气象类很多,client是否需要与这些气象类直接通讯呢?

我们看到station这个类,温度、湿度、风速这些对象也是station对象的朋友,而且station对象是client对象的朋友。那么我们是否可以更改一下,让client只与station通信,由station负责与其他的气象对象通信呢?
在这里插入图片描述
这样更改之后,使得client与其他类解耦出来,这样气象类内部怎么更改,client并不需要关心,他只和station对象进行通信就可以了。

所以,直接朋友的选择很重要,在应用迪米特法则设计时,我们应该尽量减少对象之间的交互,如果两个对象之间不必彼此直接通信,那么这两个对象就不应当发生任何的直接作用,如果其中一个对象需要另一个对象的某个方法的时候,我们可以通过第三者来转发这个调用。

二、对朋友了解的最少

上面的那种形式,做到了client与气象类之间的解耦,那么能不能再进一步,让client与station之间、station与气象类之间也能做到尽量的松耦合呢?

即使我们选对了直接的朋友,但是如果这个朋友是一个“大嘴巴”,即很多方法属性,外部都是可以直接访问的,如果外部调错了方法,或不小心更改了其他的方法属性,那么这两个类之间的耦合性还是相当高的。

在应用迪米特法则设计的时候,我们还要做到对朋友的了解最少,即降低类成员变量和成员方法的访问权限,这样就可以让类之间的耦合性降低。比如对于类属性,我们可以设置为私有的,提供get或set方法来供外部调用。

1、在类的划分上,应当尽量创建松耦合的类,类之间的耦合度越低,就越有利于复用,一个处在松耦合中的类一旦被修改,不会对关联的类造成太大波及;
2、在类的结构设计上,每一个类都应当尽量降低其成员变量和成员函数的访问权限;
3、在类的设计上,只要有可能,一个类型应当设计成不变类;
4、在对其他类的引用上,一个对象对其他对象的引用应当降到最低。

弊端

首先迪米特法则会造成系统的不同模块之间的通信效率降低,使系统的不同模块之间不容易协调等缺点。

因为迪米特法则要求类与类之间尽量不直接通信,如果类之间需要通信就通过第三方转发的方式,这就直接导致了系统中存在大量的中介类,大大增加了系统的复杂度。

由此我们在使用时还是需要进行业务的权衡,反复分析利弊。

应用——外观模式感悟

外观模式:隐藏系统的复杂性,向用户提供一个可以访问系统的接口。

定义很简单,但是不能想当然,因为有时候,自以为的知道了、明白了,只不过是表面上对自己的欺骗而已,更可怕的是,自己都不知道自己被自己骗了,当多问几个为什么的时候,就会发现,其实自己的知道了,也就是一个简简单单的“知道了”。

就以这个外观模式为例,为了让自己不被自己欺骗,我们需要去思考为什么,为什么会有这样一个接口?这个接口存在的意义是什么?出现这个接口后体现了那个设计原则?为什么会有这样的设计原则出现?所有原则出现的最本质是为了什么?多问自己几个为什么,去思考本质,思考初衷,万变不离其宗,当能够想到最初的本质的时候,或许就豁然开朗了很多,就会发现那些被千万人推崇的,奉若神明的原则思想,是那么的简单,又是那么的不简单。

接口的出现,在这里隐藏了复杂性,由原来的客户端与系统耦合,变成了外观类与系统耦合,客户端不需要知道系统到底有多复杂,你只需要一个“接待员”来接待我的请求就可以了。就像是你想获取天气温度,温度的测量需要温度计,温度计只有气象站有,难道你要跑到气象站,然后拿到温度计,再自己去测量吗?这里我们需要非常明确的知道一点,气象站就是提供天气温度的一个服务呀!他就是这样的一个对象,用来提供服务的,既然做了服务对象,为什么不做好服务,该他做的就让他做就好了,直接让气象站提供好温度,我们直接获取就好了。

这也就是说,这个接口是用来隐藏复杂性的,但是它的最终意义离不开我们的面向对象编程。当我们带着面向对象编程的思想再去看设计模式时,就会发现充分面向对象才是最伟大的原则。

**对于熟悉的东西,人们一般都喜欢面向过程去做,而对于不熟悉的东西,人们一般都喜欢面向对象去做。**比如早点摊卖煎饼果子的阿姨,他对于做煎饼已经非常非常的熟悉了,但是还是按照步骤和面、烙饼、加调料…,而买煎饼果子的顾客并不熟悉摊煎饼的过程,顾客只希望得到一个整体的煎饼对象而已,这时候就是由这个阿姨来将过程进行了封装,封装成对象,作为服务,交给顾客。但是如果哪天顾客反过来给阿姨一套自动化装置,自动化完成摊煎饼果子的过程,这个时候那个是面向过程的?那个是面向对象的呢?显然阿姨对这个装置是不熟悉的,所以她喜欢面向对象去做,让这个自动化装置去做事情,阿姨只需要一个结果就好了,而这个自动化装置就相当于原来的阿姨,去面向过程摊煎饼了。这个例子最终要明确的点是什么呢?我们无论是在编程还是在生活中,都要找准对象,找准服务,这个对象就是一个立体的东西,他有他的职责,我们最终从这个对象中拿到我们想要的服务就好了。

话再说回来,不要被自己骗了,做任何一件事情都要去思考为什么,思考本质是什么。当然,我们并不是圣人,有时候很容易把自己陷入一个怪圈出不来,这时候就需要寻求外界的帮助了,学会站在巨人的肩膀上思考,比如你的恩师、发达的互联网、可以思维碰撞的伙伴等等,利用好外界一切可以利用的东西来达到你最终想要的结果(道德法律的规范内)。除此之外,我们还必须保持一种谦卑的态度,跟着比你强的人去学习,因为这样的人,可能随便一个小细节都能发现他比你强,首先你不用花费时间去寻找你要学习的点(因为随随便便拎出来都是你要学习的),其次你的吸收量是惊人的,因为当你每时每刻都在触碰自己的盲区时,你就是在学习、在吸收,这样的成长速度是非常快的。

不要欺骗自己,多去问为什么,跟随强者的脚步,保持谦卑的态度,站在巨人的肩膀上,让自己做成自己。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值