论软件设计中的哲学观

 

        所谓哲学,即透过事物的表面现象,通过客观理性的分析,找出更接近事物本质的通用解。从而以一种大宇宙的视角,来观察和解读这个世界的种种现象。如道家所谓的“一”,佛家所云的“众生平等”。
        软件设计中的哲学观,即以一种“一”的视角,来评价和反思我们的设计,来指导和改进我们的工作。从而达到一种虽手中无剑胸中却有剑的境界,当如庖丁解牛,游刃有余。
        第一次有人告诉我这个概念,是大约10年前,工作后的第一个导师,一个聪明偏执但让人敬佩的华工怪才。当然那时初生牛犊,没有什么概念,凭借与生俱来的一些小聪明和天生喜欢专研的精神,碰到再难的问题,脑海里总会闪出各种idea。还曾以大学期间就有数万行代码量而自大。因此多年在同学和同事中,也有一些还算过得去的小名声。
        那时候,我固执的认为,只要能圆满解决工程中遇到的问题,用怎样的方法根本不重要。所以总沉浸在有过多少多少代码量,解决过多少多少难题这样的表面成就里。
        后来渐渐有了些经历,就不得不开始对做过的一些事情加以总结和反思。虽然期间也做过一些自认为在业界都还算拿得出手的小创造,但似乎也总没能跳出那一亩三分地,技术上也很难再有所突破。
        后来就不断的追问自己,当初为什么选择这个行业,需要的究竟是什么?
        这个行业说来戏剧,养活着世界上大多数最聪明的人,拥有一个巨庞大巨勤奋同时“英年早逝”概率最高的群体,吸引着无数对“高工资”诱惑缺乏抵抗力的年轻人,无数女孩眼中“技术宅“典型形象。
        圈内人士却喜欢用“码农”自嘲,在这个物欲横流的时代,没有比“农民工”更伤自尊的措辞了。
        不经个中事不知其中味,有谁愿意每天晚上10点都不回家,有谁愿意节假日没有休息,更不会有人愿意凌晨3点被手机短信吵醒还不得不上线处理各种服务器宕机bug。
        想想当年诺基亚3年研发一款功能极简单的手机就可以畅销5年,现如今半年研发一款最多只能卖1年,功能还要强10倍,便知个中辛酸和无奈。
        这是一个极度浮躁的行业,为快不破是这个行业亘古不变的生存法则。中国人的可怕之处在于,没有信仰,所以不需要有道德底线。也因此敢想任何世人所不敢想,敢做任何世人所不敢做之事,只要能将对手打倒,可以不择手段。
        这个圈子永远都不缺少发明轮子的牛人,当然更不缺少愿意每天重复做着Ctrl+C和Ctrl+V来应对各种需求变更的“码农”。可那又有什么意义呢,当初前辈发明计算机的目的是解放人力,让机器去帮我们做那些重复繁琐的事,可如今我们却反过来让机器闲着,通过雇佣无数的“码农”来做着重复繁琐的体力活
        前段听老板讲了一个有意思的段子,说有团队想找他拉投资,一问只要300万想都没想就拒绝了,说敢开口要3000万的话没准还愉快的答应了。当然这个段子我等屌丝只当听了一个笑话就过了。但回过头来仔细想想,却反映出行业的一个怪相,由于技术日趋开放和成熟,使得行业准入门槛越来越低。3个刚毕业的大学生,15个月,就能成就《刀塔传奇》这样月流水过亿的传奇手游。在中国从来不缺有钱没处砸的土豪,相比当年投资端游5年耗资过亿,也未必能听见个响煤老板们,这等成功案例该是有怎样的诱惑力。
        最近老在为招人的事情烦恼,半月间各种面试不下20人,我要求不算高吧,能脚踏实地做事就给及格。可让我为这个行业的明天颇感担忧的是,计算机科班出生的小本,什么ACM,Unity3D,JavaScript,要什么会什么,可那些本该在学校打好软件基础呢?汇编语言没学过,数据结构不知道,什么内存管理,编译原理就更不用提了。
        我想说的是,这种急功近利的思潮已经蔓延到学校,当下流行什么技术就教什么,等明天这些技术淘汰了呢,难道让他们集体失业吗?
        诚然,随着C/C++逐渐淡出,也许内存管理噩梦会渐渐的从普通程序员的日常工作中消失。可知其然不知其所以然,没有练过马步基本功的武术家,打起来怎么都只能耍耍花架子。
        说了这么多,好像有点跑题了,言归正传,总之一句话,在不缺钱,不缺人,不缺设备,不缺新技术的今天,我们究竟还缺什么?缺少一种排除一切杂念,静心把软件本身做到极致的心境,缺少一种强迫自己慢下来的心态。
        应用软件开发商由于处于行业下游,为了争取尽可能多的受众群体,又不得不面临一些商业竞争带来的麻烦——要同时兼容各种平台,如Windows vs Linux,Android vs IOS,IE vs FireFox,VC vs  GCC等等等等。
        不光如此,业务逻辑本身的需求也是千奇百怪。人是一种超有想象力的动物,就连只有一个领口两个袖口的衣服,都能每天设计出几千种不重样的款式出来,就更别说已经深入全世界每个角落的软件需求了。
        不得不说,现代社会对软件的期许,已经远远超出了这个行业的承载能力。现代软件的复杂程度每天都在呈指数级增长,就连Iphone这样的神机都会隔三差五的罢工,难道是Apple的工程师天生无能,所以写不出一个没有bug的操作系统吗?所有的烂系统并不是生来就烂,多半是因为每天应对各种变态的需求变更被改烂掉的。
        终于回归主题了,软件设计中的哲学观,就是为解决这些问题而被提出来的。
        道家云,“道生一,一生二,二生三,三生万物”,看来我们真正需要的就是这个“道”。那么何谓计算机的“道”?
        当初前辈设计计算机的目的就是为了接替人类做那些重复繁琐的工作。所以在硬件结构不做重大变革的前提下,计算机最擅长的就是处理那些重复性的工作(即软件中常用的for),因为计算机是不知疲倦可以长时间不休息,并且不会像人那样偶尔打个小盹开个小差。
        在人工智能机器人技术没有实质性突破的前提下,计算机可以暂时认为是没有创造能力,不能通过学习和经验自己创造出解决新问题的方法,而只能机械的接受人们预先设定好的操作指令。因此可以认为,计算机最不擅长的恰恰是行为决策(即软件中常用的if-else/switch-case)。
        因此,所谓计算机的“道”,就是要在人的习惯和计算机的特性之间找到一个黄金分割点,让“愚笨”的机器能够秒懂“聪明的人类”发出的各种指令,即武术家常说的“人剑合一”,让人和机器之间达到0成本沟通的境界。
        纵观人类和计算机沟通的手段——编程语言的发展史,从机器码、汇编语言,到C、C++、Java、Python、Lua、Golang、Shell,可以说人和机器沟通的成本是越来越低,因为思维模式越来越接近人的正常思维模式。可是我们却渐渐的忽略了一个问题,由于人的惰性,总喜欢干自己擅长的事,却逐渐忽略了机器的感受。高级语言的表达能力一流,人们就习惯滥用脚本,去强迫机器每天做自己所不擅长的事。
        这里不得不提的是,1943年出生于美国新奥尔良,同时是Unix和C语言之父的Ken Thompson(肯·汤普森),40年如一日,2001年从贝尔实验室退休后,被大名鼎鼎的Google返聘,于2009年再次成为Golang之父之一。
        大师手笔,绝非浪得虚名,Golang大道至简的设计,可谓是大师们对“计算机哲学”的经典诠释。语言层级天生的并行特性,极简的语法,超强的表达能力,对OOP的经典表达,丰富的标准库,高效的编译和执行能力,无不让后辈惊叹。
        说完大师的经典作品,再看看“计算机哲学”对普通程序员的魔力。
        可还曾记得《数据结构》课程里那个关於单链表的经典实现吗? 大师们为写出干净清爽的代码,可谓煞费苦心。
//普通版本,m_pHead,m_pTail被初始化成NULL
void Slist:PushBack(Node* pNewNode){
        if(m_pTail != NULL){
                m_pTail->next = pNewNode; m_pTail = pNewNode;
         }else{ 
                m_pTail= pNewNode; 
        } 
}

//强化版本,m_pHead,m_pTail被初始化成DummyNode 。大师们为写出干净清爽的代码,可谓煞费苦心。
void Slist:PushBack(Node* pNewNode){
        m_pTail->next = pNewNode; m_pTail= pNewNode; 
}

        用软件设计中的哲学观,来指导和评价我们的设计,需要遵循哪些原则呢?
        1.解放人——让他们做自己最擅长的事。
        2.解放机器——让它们做自己最擅长的事。
        3.解放生产力——让人和机器0成本沟通。
        人在软件设计过程中所扮演的角色和承担的任务:读懂别人的代码,正确实现功能需求,长期维护功能代码以应对各种需求变更。
        人的特点是:情绪化动物,喜欢每天尝试新的东西,厌恶重复繁琐的工作,会经常开小差犯错误,每天都需要多人合作,人员流动常态化,最擅长的是为各种千奇百怪的实际问题提出解决方案。
        机器的特点是:最忠实的执行者,孜孜不倦最能胜任长时间不用休息的机械性重复劳动,没有思想,不能用已有的经验为新问题提出解决办法,没有决策能力,可以多机合作但也只是被动听从指挥,就算明知道是错误的指令也会坚决执行。
        所以,“计算机哲学”要解决的难题就是,让人和机器这两种性格迥异的参与者,愉快的合作,高效高质量完成千差万别的日常实际需求。
        那么,符合怎样条件的设计才能达到这样的目的呢?
        1.大道至简——KISS(Keep it simple and stupid)。
            软件产品最终是给机器去执行的,但更重要的还是,要给别人去读懂的。没有一个复杂的系统是能给所有人读懂的,也没有人愿意去维护一个极度复杂的系统。
            人是一种经常会开小差犯错误的动物,如何才能减少他们犯错误的机会呢,那就是代码量越少越好,修改起来越简单越好。
        2.高度模块化——高内聚低耦合。
            软件研发是要团队合作才能完成的作品,那么,团队的每个人最终都只能分到系统中的一个小功能。那么,怎样才能让每个人专心做好自己的工作,而不要停留在被别人打断和不断的打断别人这样的低效模式里面呢?答案就是高度模块化的设计,事先只需要由架构师约定要模块之间的必要依赖,具体的实现交由各模块独立实现,外部不做接口约定之外的任何约束。
        3.众生平等——线性扩展,跟if-else say goodbye。
            世界是五颜六色的,每个人眼中的世界也是万紫千红的。这种现实对于人来说也许还有一定吸引力,但对于只擅长做重复性工作的计算机来说简直就是个噩梦。计算机希望的世界原型是所有人都是两只眼睛一个鼻子,至于有的人大眼睛高鼻梁这种个性化元素是不希望去care的,而事实上这种个性化差异却是客观存在的,因此我们有了OOP,有了继承,有了多态。让计算机只看到所有人都是两只眼睛一个鼻子这样的“一”,而允许不同的人去具体描绘出大眼睛高鼻梁这样的“三”。从而从设计上达到“一”和“三”的和谐统一。
        4.三生万物——需求变更是每天都在发生的。
            所有软件的最终需求都不是一开始就完全定下来的,而是经过长期不停的变更改出来的。那么,在最初设计系统的时候,都还不知道这些千奇百怪的新需求的时候,我们又该如何应对呢?从哲学的角度讲,如果当初系统是在哲学原理框架下设计出来的,万变不离其中,猴子他再怎么能折腾,也是难跳出这五指山。
        侯捷老师曾戏称,在STL面前,99.99%的人写出来的数据结构算法都是三流水准。那么,在哲学原理视角下,我们每天写出来的产品,也多半算三流水准。软件设计中的哲学观,不能教会我们怎样去设计一个一流系统,却能指导我们如何设计出一个更合格的三流产品。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章