金庸笔下的编程秘籍
发表于2016-07-21
今天与人闲谈中无意间提到了“倚天屠龙记”中的张无忌,这是一个普通的甚至性格有点软弱的主角,性格复杂,很多人读完小说以后觉得他一点都不像一个英雄人物,与乔峰乔大侠、郭靖郭大侠等相比,简直是差得太远了。回来之后细细回味思索一番,除了张教主是不是英雄这个问题外,我意外地发现他的学艺之路竟然颇有启发性,想来金庸大师也是哲学方面的高才啊。
下面让我们一起来回忆一下张教主的学艺之路,并结合金庸小说中的各种成名绝技,看是否有值得借鉴之处。
面向对象思想——任督二脉
打通任督二脉,是修习高等武术的基础和必经步骤,大家看过武侠小说的都知道,也基本都见识过了。之所以是基础,道理很简单,如果任督二脉不通,真气流转不流畅,当然就不能发挥自己体内最大的能量了。就好比一条非常细小的水渠,怎么能承受得了陡然暴发的洪水。
这一关通常看似简单,但是非常有难度,即使是主角兄弟们,也只是会“意外”通过,一般都是借助了外力,比如武功高强的师傅、能力超凡的道具、不可思议的奇遇,等等。对于张教主来说,这一关在说不得大师的乾坤布袋中顺带通过了,凶险万分但非常轻松。对于大部分普通人来说,这一关可能终生都无法逾越,所以武功怎么练也无法达到上层境界。
基本上,任何用过面向对象语言(如Java、C++、C#等)的同学们张口就能说出面向对象的三大特征:继承、封装、多态。但是又有几个人曾试图深层次地了解过这6 个字背后的含义呢?
面向对象思想是软件工程发展史上的伟大里程碑,它提供了软件设计与开发的新思路:那就是一切皆是对象。这种思想体现了人们对世界的重新认识。这种认识体现到实际的行动中,就是使用对象去表述世界发展的一切活动。为了生动描述事物之间特性的传承性,“继承”就诞生了;为了描述事物之间相同特性基础上表现出来的差异性,于是“多态”就被创造出来;为了描述事物的完整性和相对封闭性,“封装”就提上了日程,细节从此不需要再去关注。这是面向对象世界观的三大基本特征,也是面向对象设计的核心根基,只有深刻理解了它们,时时刻刻记住它们,把它们深深地融入到你的日常活动中去,你的神功才会一日千里。
面向对象设计原则——九阳神功
当你能做到任何时候、任何场合,眼中只有对象的时候,那么恭喜你,你的任督二脉已经打通!你可以学习任何一门高深的内功了。为什么先学习内功呢?这个大家也都非常熟悉,没有内功的配合,任何高深的招式都是浮云。所以要想天下无敌,必须要练就一身深厚的内功,比如九阳神功。
对象的三大特征全都有了,表明在你眼中一切都应该是对象了,你已经是面向对象了,但是并不是说这就是好的面向对象了。
如何评判一个系统是好的面向对象呢?
一般是参照“SOLID”标准。
单一职责原则(SRP):做一个专一的人
做好并且只做好一件事,这条原则其实不仅仅适用于对象,同样适用于函数、变量等一切编程元素。当然,在商业模式中,将一件事做到极致就是成功,小钱觉得也还是成立的。
开放封闭原则(OCP):改造世界大部分不是破坏原来的秩序;在对象世界中,添加新的功能一般意味着新的对象,一个好的设计也意味着这个新的修改不要大幅度波及现有的对象。这一条理解起来简单,实施起来却最是困难。无数的模式和解耦方法都是为了达到这个目的而诞生的。
里氏替换原则(LSP):长大后,我就成了你
父类使用的地方,子类也可以使用。这一条希望子类不要破坏父类的接口成员,一旦破坏了,就如同人与人之间破坏合同一样,有时候会很糟糕。
接口分离原则(ISP):不要一口吃成胖子
接口不要过于庞大,繁杂的东西是难以理解、难以扩展、难以修改的。这一条的目的与单一职责原则类似,不过是更加强调了接口的逻辑一致性和简易性。
依赖倒置原则(DIP):抽象的艺术才有生命力
高层与底层组件之间都应该依赖于抽象的组件。这一条深刻揭示了抽象的生命力,抽象的对象才是最有表达能力的对象,因为它通常是“无形”的,可以随时填充相关的细节。
除了这几个基本的设计原则外,还有一些衍生原则,掌握它们,你将能更好地面向对象。
迪米特法则:尽量不与无关的类发生关系。
对象之间联系越是简单,则越是容易管理。
好莱坞法则:不要调用我,让我调用你。
电影中常说,单线联系最安全,就是这样。
多使用组合,少使用继承
复用的手段除了继承这种强约束手段外,组合这种弱耦合的关系更加灵活,实现依赖于抽象,这一点一般也称为面向接口编程,保证了对象之间关系稳定。
修炼完这些原则,你已经神功初成了,那是不是活动活动手脚,就可以大干一场了呢?
模式——乾坤大挪移
当张无忌学会了九阳神功下山以后,他已经身负绝世内功了,但是不知大家发现了没有,他居然连最普通,只会些三脚猫功夫的毛贼都打不过,他只能依靠阿蛛的招式,来借力反击,只是这样谈何天下无敌呢。不过当他学会了乾坤大挪移以后,那真的是如同凤凰涅槃,瞬间完成了超级赛亚人变身。这个道理似乎也很简单,光有高深的内功,但是没有运转自如、充分发挥内功的招式,同样也是不成的。招式,那可是前辈们经验的总结,是精华啊。学会了这个,你才有决胜天下的资本。
世间原本没有模式,使用的人多了,才有了模式。模式是经验的总结,是“巨侠”们的心血。
大型模式如架构模式(分层、MVC、PAC、黑板、中间人、反射、管道、微核、REST 架构等),它们描述了系统大骨架的构建过程;
中等规模的模式如设计模式(GOF 23种模式、POSA 中的各种设计模式),它们描述了子系统中组件的构建过程;
小的模式如各种语言中的编程实践(C#中的IDispose模式、C++中的Counted Point)模式等,它们描述了解决语言中特定问题的实施方案。
这些模式合起来就是面向对象程序设计过程中针对特定问题的乾坤大挪移神功。
重构——太极拳
如果一定要评出金庸小说中的三大巅峰神功,那么太极拳必能入选。练习太极拳是需要超凡的悟性的,太极拳重在以意运转,不能有丝毫外在强加的约束,这一点看过原著的同学们都很清楚。自从太极拳问世后,人们才真正体会到了什么叫做“以柔克刚”!
重构是精心打磨、持续雕琢代码的过程,是任何资深码农的必备技能
重构不是无目的的,重构是一种在不改变代码行为的前提下,改善代码可读性、可扩展性的过程。
之所以需要重构,就是因为代码也是符合事物发展规律的,也有一个从出生到成长,从强壮到衰败,从衰败到腐烂的过程,而且是循序渐进的,不知不觉地就从好变烂了。毫无疑问,并不是所有的烂代码都是一次写成的,也许最初的代码设计是很好的,但是一旦被多个人修改过以后,就变坏了,很多人对此都深有体会。代码总是在所有人的共同“努力”下写烂的。
如果说上面提到的那些技术都有迹可循、规则性比较强的话,那么相对来说,重构的技术要相对柔和一点,没有那么强烈的约束条款,而且虽然也有像介绍“代码坏味道”的伟大著作(《重构》一书)诞生,但是,通常人们脑海中对于重构的冲动,从没有像使用模式那么强烈,根本不会想到重构会是那么的重要,就如同书中的那些高人们根本不会想到如此缓慢而且无固定招式的太极拳会是那么强悍一样。重构与太极拳一样,进行到多大程度和画多大多小的圈,都无法明确衡量,它们都是真正的“意识流”。
抽象与组合——独孤九剑
要说金庸小说中最厉害的武功,小钱认为既不是乾坤大挪移,也不是太极拳,更不是葵花宝典,而是独孤九剑。那是什么境界啊?九剑破遍天下任何拳脚、气功、暗器、十八般兵器,这才叫“无敌”。当然,这个武功不是随便是谁都能练得成的,也就是像令狐冲那样智慧超群,洒脱异常,具备一定内功(后期更辅助以吸星大法),武功又杂的小哥才能练;而且这个练习过程一般也比较长,据风清扬介绍,令狐老兄刻苦练习十几年后方能与东方不败一战。
我们再看看该神功原创者独孤大侠一辈子兵器的变迁:从利剑到重剑,到木剑,再到无剑。大家发现了没有,到了最后抛开一切招式、内功,融会贯通,水乳交融以后,才是真正的超凡入圣,这个时候也才发现原来一切又回到了起点:原来武功就是这么简单,就是锻炼与发挥人体的最大能量,随便地一挥一洒就有无与伦比的威力。返璞归真才是武者的终极、青铜门后面的永恒(出自盗墓笔记一书)。
不管是面向过程,还是面向对象,不管是面向组件,还是面向服务,归根结底只不过是人们对世界的抽象方式和抽象的粒度不同而已,把抽象出来的东西组合起来,形成一定的规范和流程,依靠这些去解决实际的需求,这就是编程。
抽象与组合,才是终极的艺术。