低扇出,高扇入

我承认,判断一段代码的好坏,有很多主观的因素,你大可以来批评我,『你看不惯别人的代码,别人还看不惯你的代码呢,既然如此,何不和和气气,多包容包容』。我的回答是『No,不好就是不好,我在批评的时候,除了主观因素,确实还有一些客观标准的,不信拉倒』。

今天,就来说说标题的这个,不知道哪个货翻译的,我故意这么写的,看不懂实属正常,一下子看懂的人,我才觉得莫名其妙。英文的原文是high fan in,low fan out。讲的是类(Class)的一个设计原则。具体是什么意思呢?就是说,一个类,尽可能不要去依赖别的类,就是所谓的low fan out,你写一个类,应该尽可能多地被别的类所依赖,这就是所谓的high fan in。

我经常还说另一个话『写代码就是一个选择的过程,你可能觉得同一段代码,写在哪里都是可以运行的』,放哪里,有时候真是个艰难抉择,那low fan out和 high fan in,就可以成为一个简单可依赖的判定原则。这个方法,是否有依赖别的外部类?有的话,能否剥离掉?(这样可以降低fan out),这个方法,需要用到的地方多么?和哪些方法放在一起,可以最大化类的复用性?(提高fan in)

这两个原则,也并非绝对的,因为当你构造了一个类体系后,会发现,总有些类会依赖别的类,各种对象交互协作才能形成系统,所以,总是要互相调用的。但是,这里仍然有一些简单原则可以遵循。在系统里,越底层的类,越应该遵循low fan out,越靠近顶层,可以适当提高fan out。举个具体点的例子来说,在一个Web应用里,到了Controller里,你就不得不操纵很多的Model和View去执行逻辑和渲染页面,无法避免地high fan out了。但是在Model层,则应该让一个Model尽可能少地去依赖,无论是依赖别的系统组件,还是依赖别的Model,都应该控制其范围。

这两个原则,也并非那么狭隘只能用于类的设计,系统架构中的模块设计,也可以参考这个原则。

很有趣的是,有些人甚至将这个标准做出了一些量化,比如fan out,被认为不应该超过7个,具体到类,就是一个类,调用的外部类,不应该超过7个,一个模块,调用的外部模块,不应该超过7个,理由是,人脑很难在同一时间处理超过7个不同事物【1】。

所以,当我们阅读一段代码的时候,评价系统实现得好坏,一个类实现得好坏,这个fan in和fan out就可以成为很重要的判定依据,这个东西是客观和可以量化的。

备注:
【1】 http://it.toolbox.com/blogs/enterprise-solutions/design-principles-fanin-vs-fanout-16088