简单聊聊代码封装

面向对象程序设计有三个特征:封装、继承、多态。
这三个特征即是语法也是手段,23种设计模板对这三种手段的灵活应用。

封装
基于框架开发的时代,开发只是往框架里“填充”业务代码。似乎不太需要考虑太多东西,这时我觉得“封装”就很重要了,“封装”就是开发层面的“微设计”。

1 认清关系

A调用B什么关系?调用和被调用的关系?No,No,No!
A为什么调用B?
因为A不调用B,就无法完成自己的工作,B能帮助完成工作。也就是说A依赖于B。
这个认识直接影响到代码的组织。

1.1 向下原则

依赖者之间的位置或者层次是什么样的?
答案是上下的,不是平行的。也就是B在A下层,为A提供服务,这个可以参照ISO七层模型来理解,也可以参考我们的框架,web层->service层->dao层。《代码整洁之道》里称之为向下原则。

案例:
假设有个方法有300行代码,里面有些东西可以封装子F来,你会怎么做?
我相信大部分人做的都还可以。
但有这么个做法,把方法拆成了三个方法,F1,F2,F3,F1调用F2,F2调用F3,每个方法体里面基本上是之前方法的一段代码,比如F1是1100行代码,F2是101200行,F3是201到300行,三个方法需要的参数几乎都是一样的,通过形参依次传递下去,而且返回值都是void类型,给方法的名字和注释也很尴尬,意思都很接近。

这个做法如何?从形式上不行,每个方法都是原来方法身体的一部分。
从逻辑上他们是平行的,可以认为它还是一个方法,他们之间不是依赖关系。这样封装代码仅仅是把代码挪了个地方,还不如不拆分,阅读者得自己脑补,把代码合并起来才能知道到底想干什么。
把一个方法比喻成一个人,那么如果这个方法需要重构,抽离出来的方法仍然必须是个人,是个五脏六腑俱全的mini小人,而不是这个人的手或者脚。

1.2 封装不是简简单单的挪动代码

F1调用F2,F2调用F3,或者F1调用F2、F3都可能是合理的.
关键看几个F封装的符不符合我们常见的原则,后续我们将均使用上面的例子,因为它很巧的违反了很多原则.
后面是具体原则

2 单一职责原则

单一职责,强调的是职责的分离,一个方法只干一件事情。
只为一个原因做修改。
很多代码之所以需要重构,因为有职责扩散。所谓职责扩散,就是因为某种原因,职责P被分化为粒度更细的职责P1和P2。

从微观上讲单一职责的方法一目了然,职责明确,利于维护。
从宏观上讲是设计的要求。单一职责原则可以看作是低耦合、高内聚在面向对象原则上的引申,将职责定义为引起变化的原因,职责过多,可能引起它变化的原因就越多,从而极大的损伤其内聚性和耦合度。

这个原则非常好理解,最常见的违反这个原则的例子就是写“大而全”的方法。
(一个方法干了太多事情)一个方法搞定各种逻辑,各种flag,各种分支判断,到最后代码看不出主逻辑是什么了。

如果单一职责原则做的好,代码都不会太长,随便翻开Apache的开源软件源码,大部分的方法都没超过100行,当然有些核心类、管理类等,长代码还是有的。

除了大而全的方法,想想上面的F1~F3的例子,有没有违反单一原则?
与大多数人职责过多相反,它是因没有职责而违反。
这里有个“诡辩”,只要不是空方法,只要方法里有代码、有逻辑就有职责,这一点我不太同意。这是个职责范围的认定问题,虽然职责的认定是仁者见仁智者见智的,但是我觉得有些基本的东西是确切的,比如职责必须很明确、完整。 上述F1~F3,每个方法都没有完整明确的职责,看代码的感受就是不知道这个方法想干什么,感觉每个方法的存在意义都不大,逻辑合并起开才勉强知道想干什么,所以我认为职责模糊的方法是违反单一原则的。
还有就是返回值,有返回值并且设置void的,也属于职责不明确。除非真的没有返回值可以用void,否都应该返回值。隐式返回容易让调用者遗忘哪些变量被改变了,进而引起编程bug。

3 最少知道原则

一个对象应该对其他对象保持最少的了解。
通俗的来讲,就是一个类对自己依赖的类知道的越少越好。也就是说,对于被依赖的类来说,无论逻辑多么复杂,都尽量地的将逻辑封装在类的内部,对外除了提供的public方法,不对外泄漏任何信息。

函数层次上也要遵循此原则,方法的开口尽可能的小,入参之间不要有依赖,一个极端的例子:一个方法有3个入参,但是第1个和第2个能计算出第3个,就是违反最少知道原则,第三个参数应该在方法体里计算出来。

入参过多很可能会违反最少知道原则,上面的F1,F2,F3的例子,形参个数多达10个。有些很复杂的场景,传递的参数如果真的必须很多的话,考虑用有意义的实体封装,这个封装其实是对入参“归类”,虽然需要的参数还是需要一一“拿到”然后放进实体里,但是归成一类逻辑上可以看成“一个”。很多公司的规范对形参个数都有要求。

4、考虑线程安全问题

线程安全问题平时很难测试到,需要特别注意,时时注意。
静态变量、单例的成员变量都是可能被多个线程访问的、资源的非原子操作(例如数据库一个值读取出来后,再update+1)等等,设计类时把考虑线程是否安全当成一个习惯。

5、好的代码是什么样的

好多人常说优雅,优雅是代码的最高境界。我们不说优雅,一般来说比较优秀的代码是什么样的?
根据之前的解释,以函数为单位,个人觉得好的代码是一颗树,一颗主干分支分明、错落有致的树。入口函数可以看成树的主干,调用的函数是分支,树是逐渐细化的。如果单独看一个分支的话,它还是一颗树。
试想一下,没有分支、只有主干的树是否美观?主干和分支一样粗的树是否美观?一个不平衡的树是否美观?

6 不要过度封装

过度封装,反而把简单事情复杂化。
一旦过度封装, 直接的危害往往是写了无数行代码, 封装了N多个类, 就是看不出一个完整的功能, 因为分裂起来收不住. 即使最终把功能实现了, 代码维护性也让人不忍直视.

  • 如何判断是否过度封装? 如何避免过度封装?
    "直观优先"原则

前微软C#编辑器的开发主管Jay Bazuzi列出的一些有助于找到正确方向的问题;
他觉得前同事们应该用这些问题来问自己;实际上不管在哪里工作的开发者们都应该经常问问自己这些问题:
◆“要保证这个问题不会再出现,我该怎么做?”
◆“要想少出些Bug,我该怎么做?”
◆“要保证Bug容易被修复,我该怎么做?”
◆“要保持对变化的快速响应,我该怎么做?”
◆“要保证我的软件的运行速度,我该怎么做?”
如果大多数团队都能不时问一下自己,必定会从中得益,因为这些都是真正强而有力的问题。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,826评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,968评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,234评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,562评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,611评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,482评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,271评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,166评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,608评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,814评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,926评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,644评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,249评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,866评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,991评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,063评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,871评论 2 354

推荐阅读更多精彩内容