复制和粘帖是封装的大敌

所属分类: 网页制作 / 应用技巧 阅读数: 433
收藏 0 赞 0 分享
在侃侃而谈OO,侃侃而谈设计模式,侃侃而谈面向对象的诸多原则之前,我们首先应该掌握一点:封装。掌握好封装的原则和技巧之后,就算使用的不是OO语言,也能构造出框架优美的程序。将这些原则用在程序之外,也能得到出奇的效果。《设计规则-模块化的力量》(http://www.douban.com/subject/1737636/)将封装与模块化放在神坛的高位,它们配得上这个位置。这是我们解决复杂性问题的最基本的方法(没有之一)。

程序是一种复杂性系统。“道生一,一生二,二生三,三生(四,四生…)万物”。若将复杂性的根源当作“道”的化,那么这个“一”必然是封装。不同的程序语言以及由这些程序语言衍生的方法,则处于“二”的地位,比如 OO 设计范式、FP(函数编程)范式、分层的原则等等。OO设计准则,什么里氏替换原则,什么组合优先于继承,这些处于“三”的地位,具体的设计模式什么之类的处于“三”之后“四”的地位。

本人愚笨,至今尚记不清那些原则,如里氏替换原则是什么,那些这个模式那个模式怎么实现。设计模式中,俺只对策略模式感兴趣,对其它模式兴趣索然。实质上这些模式也好、准则也好,只是给我们提供了一种方法、一种工具去更好的实现封装。

复制和粘帖是封装的大敌,是丑陋代码的最大的坏味道。复制一份,就相当于增加了至少一个可变点,复制两份就相当于增加了至少两个可变点。为什么说“ 至少”呢,因为模块之间存在关联关系,导致一个地方的变化会导致其它的多个地方也必须随之变化。如果假定S为系统本身,M为对系统本身的一个测量,C为系统S中模块的平均复制份数(C>1),则这个M与C的关系应该是一个指数的关系: M正比于C的N次方(N>1)。

指数关系已经很可怕了,更可怕的是,当系统中的模块出现变化时,如果该模块在系统中有多个副本,我们可能偷懒,只改变了其中的一个副本,而不是全部副本都进行修改,这样就导致模块的分裂,由一个模块分裂成几个类似而又不同的模块,大大的增加系统的复杂度,最终导致系统的腐烂。直觉上,一个设计很烂的系统,它的复杂度大致是模块数量的阶乘关系甚至是幂指关系,这是比指数关系更恐怖的关系。

所以,复制和粘帖是一种非常邪恶的编码方式。在编码时,需要千方百计的去想办法减少复制和粘帖。这是在编码时就应该注意的问题,而不是放在重构阶段去做的事情。至于使用什么方法,使用什么手段,使用什么模式则是细节问题。

坚持不复制和粘帖,坚持下来,收益会非常大,写出来的代码质量高、含金量高。看见别人的系统,能马上分辨出这个系统的优点是什么,缺点是什么。什么设计模式也好,接口的正交性也好,设计原则也好,也许你从没刻意的去学过,却最终发现殊途同归,冥冥之中与国外大牛有一种心意相通的感觉。会自发的去组合、去改良这些大牛们的思想和方法,甚至去创造新方法新手段。直接由一入手,一生二,二生三生四,而非教条的、顶礼膜拜的去学这个三,学这个四。或许那个时候,你已经忘记什么是对象了。

之所以发这些牢骚,是因为昨天至今天,正在重构一个模块。这个模块M1的核心部件是一个包装自RTF的layout规则编辑器。设计这个核心部件的哥们以RichTextBox为中心设计了一个控件A,然后将这个控件的部分规则逻辑抽出来放在类B和类C的静态方法之中,更神奇的是这个类B是在另一个模块M2之中,类C倒是在模块M1之中。这个控件在M1中被三个地方给用到:D、E、F,这D、E、F每个地方都要为这个空间A注册七八个事件,然后在事件的回调函数中调用模块M2中的类B的静态方法及模块M1中的类C的静态方法去实现一些逻辑。现在呢,我要写一个控件G,这个G也要用到控件A,在这种情况下,我必需为G注册一堆A的事件及回调函数,然后在回调函数中弄一堆逻辑,至少得200行代码。为了写这些回调函数,我必须得搞清这个A控件及类B,类 C的内部运行机制。也就是说,为了吃猪肉必须得亲自去杀猪。当然,也可以从D、E或F 中Copy代码过来改吧改吧来节省时间。

问题严重的地方在于,这个控件A本身存在逻辑错误,存在功能不完善的地方,需要对它动手术。因为到处复制,牵一发而动全身,给A动手术必须也要给 B、C、D、E、F五个类动手术。在给A动手术时,为了编译通过,我将B、C、D、E、F中与A相关的代码全给注释掉了,前后注释了1500行代码左右。实质上这1500行代码真正有价值的代码也就在200行左右,其它的代码全是复制、粘帖,然后改改变量名完成的。

为什么会出现这样的问题呢?因为复制和粘帖。复制和粘帖省事啊,Copy过去改几个词就能用了,不用花费心思的去想封装。而实际情况是,要引用那个控件A,得写200-300行代码,多引用几处,就得写1000多行代码,复制和粘帖的话倒不费事,但如果发现这个A存在错误,或者需要扩展,在改A的同时,同时也要动这1000多行代码,这1000多行代码中可能会牵扯到更多的代码,最终导致必须修改更多的代码,这便是代码的腐烂。

其实这个A是很好封装的,它不需要其它的类对它输入任何输入数据,其它的类只需要从A控件中获得一个最终的规则结果,一个List。封装的好的话,调用A,获得结果,两三句代码就可以实现。

之所以不封装是因为习惯了复制和粘帖,或者懒于去封装,或者头脑中根本没封装这根弦。

很多新程序员或者不新的程序员,尤其是Web开发程序员老抱怨工作的技术含量低,老是想学更多的东西。实质上,他们所作的工作是非常有技术含量的东西,就看怎么看待。

如果只将自己的工作看作简单的复制、粘帖、抄袭、改代码的话,自然技术含量低了。如果将自己的工作看作如何消除复制和粘帖、如何提高质量、进度,消除工作中的不必要事情,消除各种浪费,那么这个工作的技术含量是极其高的。不要膜拜大师,当你这么做的时候,你做的正是大师的工作。不要膜拜新技术,当你这么做的时候,你的工作可能正是新新一代技术的萌芽。一点一滴、一色一香,全在心中。青青翠竹、尽是法身,郁郁黄花、无非般若。
更多精彩内容其他人还在看

出色的美工/网页设计人员需要掌握的7项技能

在互联网这行也有几年经验了,作为程序开发,经常和前端开发打交道,从和他们合作的过程中,我对美工或者网页设计有些认识,如何成为一个出色的,出类拔萃的前端开发,我觉得应该要做到下面7点
收藏 0 赞 0 分享

网页设计师需要的知识体系有哪些

设计师需要哪些体系呢
收藏 0 赞 0 分享

从四个方面谈谈Web标准的价值所在 附思维导图

清清楚楚的明白Web标准的价值!Web标准的价值相信没人会不知道,不理睬。可是具体能做什么,能不能很好的作为一个规范或者指标去诊断网站存在的问题,能不能列出一张清单,清清楚楚地看到它的价值呢
收藏 0 赞 0 分享

为什么要少用Iframe的几个原因分析

iframes 提供了一个简单的方式把一个网站的内容嵌入到另一个网站中。但我们需要慎重的使用iframe。iframe的创建比其它包括scripts和css的 DOM 元素的创建慢了 1-2 个数量级
收藏 0 赞 0 分享

百度网盟环境下的广告投放技巧(图文教程)

百度的广告投放是有技巧的.我们来谈一下吧
收藏 0 赞 0 分享

10件优秀Web开发者提升开发能力必知的事

开发工作不仅仅只是写代码,这句话来自3EV网站的Dan Frost,他在一篇文章中阐述了开发过程中应该注意的一些事项
收藏 0 赞 0 分享

不是中国才有的特色:文化差异下的网页开发

这是一篇老外写的博客,详述了他眼中因文化差异导致的网页开发问题。“特色”并不是只有中国才有,或许作为中国的设计师,也需要考虑到印尼特色、新加坡特色……
收藏 0 赞 0 分享

负距离(换位思考)-相互影响的迭代过程

产品经理把握功能 功能-指事物或方法所发挥的有利作用 .比如实用性,操作性
收藏 0 赞 0 分享

谈谈设计中的用户体验背后的8个用户本能

用户体验背后有哪些用户本能呢
收藏 0 赞 0 分享

交互设计中关于是选择分页还是加载的问题讲解

一篇文章是分页还是全捕出来是一个问题
收藏 0 赞 0 分享
查看更多