注册 登录  
 加关注

网易博客网站关停、迁移的公告:

将从2018年11月30日00:00起正式停止网易博客运营
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

为着理想勇敢前进

 
 
 

日志

 
 

程序设计的“实质重于形式”原则  

2009-12-18 23:26:13|  分类: 默认分类 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

会计有一个实质重于形式原则,指企业应当按照交易或事项的经济实质进行会计核算,而不应当仅仅按照它们的法律形式作为会计核算的依据。我借用这个术语到程序设计领域,意思是:设计程序时,应当按照程序员使用时需要知道的知识(实质)来判断依赖关系及程度,而不应当按照机器编译或者执行代码时的引用关系(形式)

例如,程序员甲和乙各写了一坨代码,甲常常问乙乙的代码怎么用,而乙每天闷头些代码,既不去看甲写的代码,也不主动去找甲。那么,不论甲乙二人的代码分别用哪一种语言写的,也不论甲乙二人谁调用了谁的函数,我们一定可以肯定甲的代码实质上单向依赖于乙的代码。

注意,实质是指程序员需要知道的知识,而不代表确实知道的知识。尽管低耦合的模块关系意味着程序员只需要知道很少的知识就可以与另一模块一起工作,但不管怎么说,程序员对同事的代码都是越熟悉越好的。

《设计模式》中的一些模式,只需简单套用就能降低程序的形式耦合度。但是这和降低程序的实质耦合度是两个不同的问题,而后者并不是简单套用模式就能做到的。

例如:某个 Java 代码,原先是用 new XXX 来创建一个对象的,后来改用工厂模式,从 XML 配置文件中读取类名,再用反射来创建这个对象。虽然形式上创建对象的代码不依赖于 XXX 这个类,但实质是否依赖则不一定。假如 XML 配置文件的维护者和编写创建代码的人是同一人,并且仍然需要关注 XXX 的行为,那么实质的依赖就仍然存在。

然而,有可能在形式耦合不变的情况下降低实质耦合,比如,某项目在编写模块的测试用例以后,精简了模块的接口,降低了沟通成本,这就是在实质上降低了耦合。

实质重于形式并不意味着形式必须与实质一致。例如,有一个 C++ 项目,其中的模块 A 依赖于模块 B,但为了编译得更快,模块 A 中并不包含模块 B 的头文件,而采用某种字符串查找的方式访问 B 的功能。这种做法也无可厚非。

两个模块谁依赖于谁应该根据哪一模块变化更频繁来决定。变化频繁的模块依赖于变化不频繁的模块。如果变化频繁的模块是底层模块,那么这种模式被叫做“插件”。

使用接口的模块“实质”依赖于定义了接口的模块,不论使用什么语法。

所以,我们就知道CairngormDIPioC之类的东西只能降低形式耦合,而无助于降低实质耦合。绝大多数情况下,这样写程序都只是在绕圈子,徒增无用代码量而已。

此外,两个模块互不依赖而依赖于抽象接口在实践中往往还是相当于某种单向依赖。因为:

  1. 接口总是由开发某个模块的程序员定义的,所以事实上这个接口还是和那个模块绑在了一起。
  2. 接口两边都变化频繁而接口很稳定的情况在现实世界中非常罕见。

真正两个模块互不依赖而依赖于抽象接口很罕见,而且,也只有接口两边的模块都存在多个不同实现的时候,才有必要做成这样。


其实本文是几个月以前就写下来了的,但是我觉得写得太理论性了,就没有发出来。虽然我的本意是去批判某些不务实的东西,但写得太理论性了文章本身就显得不务实了。写得太理论性的另一个问题是难以理解,可能导致读者理解的意思不是我想要表达的意思。

  评论这张
 
阅读(1303)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018