最近读了TopLanguage上关于编程风格的一些讨论,拜读了下云风老大的两篇佳作。 感触良多。 做为一个“码头工人”,每天都在coding,不由会想,我们的脑细胞和陪mm的时间都耗在了哪行代码上。诚然,在C++这样的语言中,我们大把的时间花 在了等待编译以及做一些繁杂而和coding无直接关联的事情。Toplanguage上有老大说,他的C++生涯25%在等待编译,5%在各种字符串中 转换,狂赞。只是对我而言,起码还有5%的时间耗费在了在.h和.cpp文件中添加和维护相同的代码上。对此,我们能做的除了等待各位委员会老大高抬贵手 外,只能选择放本书在电脑旁,编译和看书并发进行。
恩。抛开这种问题不提。个人觉得,做一个程序,主要的复杂度和耗时都来自于两个方面。一是算法逻辑,另一个是有平台和语言带来的细节性问题。关于算法逻 辑,我们学各式各样的算法,数据结构,我们偶尔灵光乍现把算法复杂度提上一个档次,这样的工作,本应该是程序最核心的内容,但往往在只占用我们花在工程上 的一小部分时间。对于很多项目而言,我们关心的是时刻在变化的算法逻辑。见佛杀佛,遇鬼杀鬼,只可惜,很多时候连我们自己都不知道我们面对的是什么。这世 界上,最复杂易变的东西就是人本身,最恐怖的是变化的需求。于是,我们又有了模式,它使得我们程序更容易适应某种类型的需求变化。我们抓住它,作为解决问 题的套路,方案,捷径。就像影响力里 面所描述的一样,我们找到了一个思维的高速公路,当我们提到xx模式的时候,就像“哔”的一下按了快门,“它适应于xx变化,可以解决xx类型的问题”之 类的内容,汹涌而出。但是,走多了夜路总会遇到鬼,走多了捷径,恩,我们需要重构。模式和重构,就像xx套和xx药(BS自己一下...越来越WS... ==!),事前事后帮助我们写出更符合需求的算法逻辑,或说算法的结构。这样的算法,解决的不只是当下的问题,还有未来可能的问题。
无论算法设计的难度有多大,变化的可能性有多高,对于程序员,我觉得,这是我们份内的事情。我们没有借口去拒绝或埋怨它。程序员的定义,理想上,应该是设 计算法和结构解决某个问题的人。当然我明白,在当前满足这个定义的人,已经不会再叫程序员了,而是xx师、xx家。对于大部分的程序员而言,我们的工作是 另一个方面,就是利用自己对语言和平台的熟悉度,去实现某个已设计好的方案。这个需求本身并不过分,就像你空有奇想却不会使用画笔的人,不能称为画家一 样。过分的是,很多时候,它让我们离一些创造性的内容越来越远,深深陷入了细节的泥沼,并沉醉其中。百万程序员堕落沦为码工的旷世惨案就这样发生了。
Sorry,又习惯性跑题了。言归正传。说另一个耗费我们头发的方面,语言和平台的复杂性。现实总是很残酷。我们想到了一个完美的算法解决方案,和遗憾, 这还远远不够。方案到实现,绝对不是汇编到机器码的复杂度。我们还需要关心大量的与算法本身无关的细节。比如,这个指针的对象何时归还,有人传了错误的参 数移走了我们需要的文件需要如何报错,平台的API和我们需要的不一样该如何使用。诸如此类。就是它,成为我们高效写程序的阻碍和绊脚石。在实验室中,每 周都有老大讲述老百姓自己的C++,倾诉着绕来绕去的语义,纷繁复杂的注意事项。我们能不听吗?不能,因为老大们有大把的例子说明,在我们的项目中,由于 对细节理解的不够BT,我们正在犯着各种各样的错误。对个人而言,了解更多的细节,机理是非常有益的,就像武侠小说中常出现的,服下xx大补丸内功暴涨 (只是请注意不要向东方不败一样走了火入了魔...)。但对于项目而言,从程序员的角度出发,来解决这个实现细节问题,过于的不现实。就像云风老大说的一 样,这是比window比unix更安全一样的笑话(转述的MS有点偏差...)。我们不能奢望程序员都是蝙蝠侠,在没有睡眠只有可乐的日子里像赵子龙一 样,在海量的细节面前屹立不倒(不要以为只有C++才有海量的细节,想handle任何一门语言的所有细节都绝对不是大众活)。我知道在大量的开源类库 中,大量的实践类书籍中,人们都是这么做的,用各种奇技淫巧解决细节问题。但是,那只是通用的方式,适合于任何情况任何场合。而对于特定的工程特定的场合 而言,我们需要做的是在架构和规范(此规范与101那样的通用规范不是一个概念...指的是在某个局部范围内简单的几条需要遵循的原则,比如在这些模块内 不能用引用,在这些模块内不能用指着之类的...)的层面上,事先将实现的复杂性控制在一定范围之内,扼杀在摇篮中。而不是放任各中各样复杂的实现细节蔓 延到程序的各个角落之后,在启用飞机大炮×××开始处理。云风老大在网易游戏引擎中的设计,从架构开始把所需要各个模块需要了解的实现细节规划的清清楚 楚。底层传值用POD、容器中用GC管理指针之类的。在一定范围内,你需要注意的实现细节只有一点点,完全处于人脑可控的范围内。同理, Toplanguage中各位老大对引用say no,也是这个道理。这里举这些例子,不是提供另一个捷径,触发流水般思维的快门。而只是一个单纯的例子,告诉你这样的方式是更好的解决之道。对于特定的 项目而言,我想,还是要具体问题具体分析,绝对不存在一成不变的规矩。在C++中提供了很多高阶的手段(相比存C...),它们能更容易在一定实现细节内 解决一些特定的问题。当你的工程中触及大量的这样的问题,而你却恰恰限制这样的使用的话,简约反而不简单了。多的自由,意味着多的麻烦。从根本上限制自 由,大大减少了麻烦。反之,限制如果加的不对,那反而是画蛇添足没事找事了。说的就是这个理。
但现实的残酷性有再次提上了议程。我的地盘我可以做主,但出了这一亩三分地,谁是老大就不一定了。在我的程序世界,总是充斥着大量的遗留代码,或者是必须 面对的接口需求。在这样的地方,你不再能为所欲为了,很多看似美好的方案都会化成一卷废纸。面对遗留代码,我们可以选择一起堕落,或力挽狂澜, 更多时候是划清楚界限(模块化,服务化,就是这个理...)。在接口受限的情况下也是一样。对外的接口已经确定,但我想提供更多的内容出去,所能做的就是 将该接口的表征能力挖到极限。在这种情况下,我想将细节复杂性确定在一个有限的范围内是比较可行的方案。一面是花花世界,一面是清静的世外桃源。中间,是 混沌的地域。带着你们最NB的老大,和所有的奇技淫巧,去往这个地狱,搞定它,这个世界就清净了。。。
恩。抛开这种问题不提。个人觉得,做一个程序,主要的复杂度和耗时都来自于两个方面。一是算法逻辑,另一个是有平台和语言带来的细节性问题。关于算法逻 辑,我们学各式各样的算法,数据结构,我们偶尔灵光乍现把算法复杂度提上一个档次,这样的工作,本应该是程序最核心的内容,但往往在只占用我们花在工程上 的一小部分时间。对于很多项目而言,我们关心的是时刻在变化的算法逻辑。见佛杀佛,遇鬼杀鬼,只可惜,很多时候连我们自己都不知道我们面对的是什么。这世 界上,最复杂易变的东西就是人本身,最恐怖的是变化的需求。于是,我们又有了模式,它使得我们程序更容易适应某种类型的需求变化。我们抓住它,作为解决问 题的套路,方案,捷径。就像影响力里 面所描述的一样,我们找到了一个思维的高速公路,当我们提到xx模式的时候,就像“哔”的一下按了快门,“它适应于xx变化,可以解决xx类型的问题”之 类的内容,汹涌而出。但是,走多了夜路总会遇到鬼,走多了捷径,恩,我们需要重构。模式和重构,就像xx套和xx药(BS自己一下...越来越WS... ==!),事前事后帮助我们写出更符合需求的算法逻辑,或说算法的结构。这样的算法,解决的不只是当下的问题,还有未来可能的问题。
无论算法设计的难度有多大,变化的可能性有多高,对于程序员,我觉得,这是我们份内的事情。我们没有借口去拒绝或埋怨它。程序员的定义,理想上,应该是设 计算法和结构解决某个问题的人。当然我明白,在当前满足这个定义的人,已经不会再叫程序员了,而是xx师、xx家。对于大部分的程序员而言,我们的工作是 另一个方面,就是利用自己对语言和平台的熟悉度,去实现某个已设计好的方案。这个需求本身并不过分,就像你空有奇想却不会使用画笔的人,不能称为画家一 样。过分的是,很多时候,它让我们离一些创造性的内容越来越远,深深陷入了细节的泥沼,并沉醉其中。百万程序员堕落沦为码工的旷世惨案就这样发生了。
Sorry,又习惯性跑题了。言归正传。说另一个耗费我们头发的方面,语言和平台的复杂性。现实总是很残酷。我们想到了一个完美的算法解决方案,和遗憾, 这还远远不够。方案到实现,绝对不是汇编到机器码的复杂度。我们还需要关心大量的与算法本身无关的细节。比如,这个指针的对象何时归还,有人传了错误的参 数移走了我们需要的文件需要如何报错,平台的API和我们需要的不一样该如何使用。诸如此类。就是它,成为我们高效写程序的阻碍和绊脚石。在实验室中,每 周都有老大讲述老百姓自己的C++,倾诉着绕来绕去的语义,纷繁复杂的注意事项。我们能不听吗?不能,因为老大们有大把的例子说明,在我们的项目中,由于 对细节理解的不够BT,我们正在犯着各种各样的错误。对个人而言,了解更多的细节,机理是非常有益的,就像武侠小说中常出现的,服下xx大补丸内功暴涨 (只是请注意不要向东方不败一样走了火入了魔...)。但对于项目而言,从程序员的角度出发,来解决这个实现细节问题,过于的不现实。就像云风老大说的一 样,这是比window比unix更安全一样的笑话(转述的MS有点偏差...)。我们不能奢望程序员都是蝙蝠侠,在没有睡眠只有可乐的日子里像赵子龙一 样,在海量的细节面前屹立不倒(不要以为只有C++才有海量的细节,想handle任何一门语言的所有细节都绝对不是大众活)。我知道在大量的开源类库 中,大量的实践类书籍中,人们都是这么做的,用各种奇技淫巧解决细节问题。但是,那只是通用的方式,适合于任何情况任何场合。而对于特定的工程特定的场合 而言,我们需要做的是在架构和规范(此规范与101那样的通用规范不是一个概念...指的是在某个局部范围内简单的几条需要遵循的原则,比如在这些模块内 不能用引用,在这些模块内不能用指着之类的...)的层面上,事先将实现的复杂性控制在一定范围之内,扼杀在摇篮中。而不是放任各中各样复杂的实现细节蔓 延到程序的各个角落之后,在启用飞机大炮×××开始处理。云风老大在网易游戏引擎中的设计,从架构开始把所需要各个模块需要了解的实现细节规划的清清楚 楚。底层传值用POD、容器中用GC管理指针之类的。在一定范围内,你需要注意的实现细节只有一点点,完全处于人脑可控的范围内。同理, Toplanguage中各位老大对引用say no,也是这个道理。这里举这些例子,不是提供另一个捷径,触发流水般思维的快门。而只是一个单纯的例子,告诉你这样的方式是更好的解决之道。对于特定的 项目而言,我想,还是要具体问题具体分析,绝对不存在一成不变的规矩。在C++中提供了很多高阶的手段(相比存C...),它们能更容易在一定实现细节内 解决一些特定的问题。当你的工程中触及大量的这样的问题,而你却恰恰限制这样的使用的话,简约反而不简单了。多的自由,意味着多的麻烦。从根本上限制自 由,大大减少了麻烦。反之,限制如果加的不对,那反而是画蛇添足没事找事了。说的就是这个理。
但现实的残酷性有再次提上了议程。我的地盘我可以做主,但出了这一亩三分地,谁是老大就不一定了。在我的程序世界,总是充斥着大量的遗留代码,或者是必须 面对的接口需求。在这样的地方,你不再能为所欲为了,很多看似美好的方案都会化成一卷废纸。面对遗留代码,我们可以选择一起堕落,或力挽狂澜, 更多时候是划清楚界限(模块化,服务化,就是这个理...)。在接口受限的情况下也是一样。对外的接口已经确定,但我想提供更多的内容出去,所能做的就是 将该接口的表征能力挖到极限。在这种情况下,我想将细节复杂性确定在一个有限的范围内是比较可行的方案。一面是花花世界,一面是清静的世外桃源。中间,是 混沌的地域。带着你们最NB的老大,和所有的奇技淫巧,去往这个地狱,搞定它,这个世界就清净了。。。
转载于:https://blog.51cto.com/duguguiyu/363386