我对解耦的认识

      很多人可能都听说过,优秀的面向对象程序设计应当是高内聚,低耦合,那什么是耦合呢,我想用通俗的语言来解释一下,就是指两者关系密切,你改了,我也得跟着改。举一个我遇到的真实例子,首先,游戏引擎基本上都会提供打log的类,曾经在我做某个游戏项目的时候,我的主程写过类似下面的代码:

public void showLog(string log){
    engine.log(log);
}
他建了一个新的类,叫Log,然后提供了一个打log的方法,这个方法实际就是调用了一下引擎的log输出的接口,也许有的人根本不明白这样做的意义是什么,就像当初的我一样,觉得这是不是过度的封装啊,放着别人现成的接口不用,就是为了秀一下自己的面向对象编程思想?当时的我一直带着这个疑问,直到后来我遇到了一位自诩面向对象思想已经登峰造极的大神,(ps:用他自己的话说,程序上的事别的不敢说,但是玩面向对象设计思想,估计全北京超过他的也没几个),我就向他请教了一下这么做是为什么,当时他的答案只有两个字:解耦。
现在我们来仔细说说这个解耦,既然要解耦,那说明如果我们不这么写,我们就耦合了,也就是说关系紧密了,体现在哪里呢?当我们写游戏的或者做任何开发的时候,我们直接使用了引擎或者框架的log输出接口,可能项目里已经堆满了数不清有多少处调用了log的,可是log输出也是有开销的,有一天你想把这些log都屏蔽掉,你怎么做?一个一个找出来注释掉?又或者哪天你用的引擎升级了,其中有一个特性非常的吸引你,你要升级,但是引擎新版本的log的接口变了,人家不叫engine.log()了,人家现在叫engine.print()了,那你要改多少代码,(ps:当然不排除你可以用文本编辑器的正则表达式批量替换一下,但是想举一个改动量的例子,也要考虑无法批量替换的时候)。
所以针对以上两个可能出现的问题,我们单独写一个类,封装了log的调用就显得十分有必要,假如我想有一个开关,开关为true就显示log,否则不打log,那可以这样:

private bool isShowLog = true;
public void showLog(string log){
    if (isShowLog){
        engine.log(log);
    }
}
如此一来就解决了项目中随时打开和关闭log的需求,而不用挨个去注释原有的log了,再比如引擎即使更改了log接口,那我也只用改一行代码,就可以解决这个问题,所以这也正是我们在用面向对象语言写程序的时候需要注意的一点,尽量不要过于依赖引擎的接口,尤其是那种需要大面积使用的,我们在写程序的时候,多想想我们写的这个程序是要干嘛,解决什么?能不能将它封装起来,隐藏具体的实现,这样即使我们的实现方式改了,也不会影响到别人调用我们的逻辑,从而实现解耦,还是以log为例,我们应该这样思考,当我们写engine.log的时候我们是在干嘛?我们是在输出log,那我输出log的方式有很多,甚至可能还根据不同的情况,输出不一样的log,而对于外部,只关心,我们这里需要输出log,具体log以什么方式输出,没有关系,所以我们才应该将输出log的方式封装一个类来实现,不也正是我们所说的解耦么?所以我是这么来看解耦的,就是降低和其他类的关联,在编程时的思路应该是这样的:想一想我做的事情是要做什么,那我们就去调用“做什么”,而不是去直接实现“怎么做”,把“做什么”之间的关系理清楚了,最后再去解决怎么做。
以上就是我对解耦的一点理解~

fantasycoding.net 2016-2024 © All rights Reserved京ICP备2020039454号-1