He's Pirate.
软件工程
过度设计
八 10th
最近在调研一个product的API,Java版本的。毫无悬念的沿袭了Java框架大多数的通病,过度设计。
造成的结果就是API接口暴多,想完成一件小事就需要声明暴多的对象,调用暴多的参数。
所以在探讨如何调用的时候,我毫不犹豫的鼓吹采用JRuby来调用。因为如果用Java,总觉得人会情不自禁的掉入过度设计的陷阱。
继续思考,会感觉,语言本身的特性就会影响到设计的思路。比如Java Web框架那么多年也没出来个Rails Style的,而Ruby社区也没听说谁搞出个EJB类似的东西。
强类型的语言,存在的太多的约束。这些规则如果对于经验不足的程序员来说,是种保护。但是对于高水平的程序员,反而是种束缚。而我觉得程序员本来就都应该努力成为高水平的级别,那种写程序为了混饭的人压根就不应该有饭碗。
打完这段话我后悔了,因为我想到C/C++的fans一定会骂我,C/C++也是强类型的啊,但是就可以写的很灵活,并且高水平的C/C++程序员也很多,没听说谁觉得用C/++憋屈的慌。特别是牛逼的指针,用好了那叫一个帅。
所以问题到底在哪里呢?想象Java除了强类型还有哪些特点,噢。原来是OOP。是啊,Java里面一切都是对象。你想打印个hello world都得写个class,然后写个main方法。。。多傻啊
所以看来也许是严格的OOP造成了过度设计,造成了代码臃肿?
我想至少这话部分在理吧。毕竟一些特定场景是不适合OO的。特别是现在函数式语言的火爆让人嗅到一丝更清新的味道。是啊,我的地盘听我的,我就把函数当一等公民怎么了。我觉得舒服。或者我的业务就是流水,本来过程式语言就ok了。不需要加无所谓的对象,不需要处理对象和对象之间的关系,交互。
看看Java的框架吧,随便挑几个,都是大批大批的class,多到让人眼花缭乱的地步。可真正常用的就那么几个类。而且很多时候A类都是必须配合B类使用的。那么何必分成两个呢。
有人会说这叫解耦,可我想举个例子:如果生下来是连体婴,医生一定要想办法处理,如果本来就是个健康的小孩,医生还需要处理,卸他个胳膊腿么?
所以当大家都明白解耦的重要性时候,一定要回过头再看看不解耦的可行性。如果A类只跟B类交互,那么也许就要想想这个A类是否有单独存在的价值了。
所以我在某些时候特别反对Java,特别是Web开发。我做了3年的Java Web,2年的Rails开发。对比两种方式,感觉真的太强烈了。Java确实不够适合处理Web,所以最近几年基本没啥原生Java Web框架震撼登场了。反而Grails啊,Jruby on Rails啊等等滴开始发威。嗯,JVM毕竟是个好东西嘛,应该支持。至于Java,一些场景下还是选择个轻量级的更面对业务的语言吧。
过度设计其实我觉得有两个含义,一个是程序结构的设计过度了,一个是设计占用的时间过度了。两者有一定联系性,但我觉得还不是一码事。而且不管哪种,我都觉得是极大的浪费,脑力与实践都是宝贵的资源。我们应当学会珍惜,把刀用在刀刃上。说到底,最重要的还是实现业务,所以设计要追求简单,实用,要为业务服务。华而不实,好看不中用的玩意儿还是留给学院派自我吹捧玩吧。
回到话题最初,其实我觉得API的设计是最最需要谨防过度设计的地方了。因为一过度设计就容易暴露出过度的接口。而每增加一个接口肯定都回带来更多的维护成本。而API又是一个非常强调向下兼容的东西。所以反悔的余地很在很小。结论就是我觉得API千万不要过度设计,哪怕设计不足一点,只暴露粗粒度一点的接口。等确实需要了,再暴露更细粒度的接口,然后把粗粒度的接口用细粒度的接口组合起来实现。也比一开始就暴露一堆巨细无比但八成没用的接口要好很多。因为API的一个潜在意义就在于即便你觉得没人用也不许随便删滴,否则就不叫Interface了,而变成NoFace了^_^
呵呵,上一篇还强调设计,结果这么快又写了篇谨防过度设计。宁亚说我是不是可善变啊,嚎~~~
其实编程就是在走平衡木,你需要不断滴思考是往这边点,还是那边点。然后在不断地思考中得到进化,这样才能向前发展。因为如果你重心一直很平稳,停止了思考。那么你根本不可能迈出向前的步伐的。
多想少做
八 9th
刚才看自己的日志,看到上一篇中的第10条第一句。
开发人员应该多想多做
仔细琢磨了一下,觉得其实应该改为:
开发人员应该多想少做
其实并不是鼓励大伙偷懒,而且我觉得有时候真的少做比多做更能达到效果的。因为如果你向反方向奔跑,跑的越快只能加大你和终点的距离。
所以做事情前一定要多想,确实把需求理顺,架构设计合理了再去实现。而不要草率决定,草率编码。
因为编码也是一种成本,如果你为了一个不合理的需求盲目编码,只能制造垃圾。
而如果在没有合理架构的情况下草率编码,只能事倍功半,而代码最终也会变为垃圾。
所以,每写一行code的时候,务必问自己,这行code是不是必要的,是否非写不可,如果是,那么是否有更好的编写方式。
把思考融入在开发的每一个流程,从设计到实现到测试到维护。一定要不停的思考。
要做专业的工匠,不是专业的代码猴子……
项目开始前所要想清楚的13点
八 5th
1,选择适当的技术与工具。
2,在是否适当这个标准,有很重要的一项就是当前的团队成员是否都比较了解熟悉。如果不是,那就要小心了。
3,另外一项评判标准就是让将来真正需要用他的一些人员去决策,而不只是不相干的人轻率决定。
4,如果实在没办法,需求导致必须用新的领域的技术与工具来解决问题。那么技术调研非常重要。
5,技术调研的时候一定要把需求可能需要的功能尽量的都想到,然后探讨,并做出结论。这点无论做多少都不为过,因为最后总要你想不到的绊脚石。
6,派去技术调研的同事必须应该始终在这个团队工作并充当探路先锋的角色,不应该随便脱离团队。
7,新的工具与技术总会带来更多的未知与不确定性,所以做计划的时候,应该理性的清楚这点,不要不切实际的幻想,盲目追求速度。
8,在使用的第三方工具,得不到源代码,文档也不够详尽的时候。领导应该理解开发人员的苦衷,并积极应对,而不是责备。因为巧妇难为无米之炊。
9,领导者要有勇气去决策,带领团队良性发展。当犯错的时候应该坦诚面对。
10,开发人员应该多想多做,对于合理的需求并且容易实现的要做好,对于合理的需求但很难实现的要尽力,对于不合理的需求但容易实现的要讲明,对于不合理的需求并且很难实现的—必须要坚持自己的意见。一定要说服别人或者让别人说服自己。切莫听天由命,摆出不在乎的样子,否则害人害己。
11,总之,要用心,要真诚。迷茫的时候要先思考这对项目是好是坏,答案就很容易出来了。
12,团队合作,就想一把筷子,攥成一把才会更加坚韧,零星的散落布局,只会被各个击破,最后每个人都焦头烂额。所以,交流很重要。teamwork,应该有兄弟的感觉,荣辱与共的范儿。
13,以上是最近的一些思考,欢迎补充和不同意见。
说说项目中文档的那点事
三 12th
我觉得这篇写不长,因为其实关于文档的一些理念基本都是那种说着很简单,做着很难的。
文档多了好?
记得以前看CMM的时候,很强调文档的重要性。这是为什么咧?因为CMM是典型的软件工程理论嘛,而软件工程怎么来的咧?就是从建筑工程学来滴嘛。君不见,黄河之水天上来盖栋房子得有多少文档啊,来描述这个建筑的架构,每个房间的布局。这啊哪的,反正肯定很多就是了。都是设计师仔仔细细设计规划好弄好了,然后由俺们最可耐滴农民工一砖一瓦的,蹭蹭的,一栋building就出来了。所以CMM挺强调文档滴,整个软件周期,都要有这文档那文档的,堆积如山的。而实际效果呢?用猜的也知道肯定不怎么好了,不然现在人都表当自个Agile,而不说自个CMM了呢。
好吧,那你说这是为什么呢?我来告诉你。如果你建个大楼,建完之后你会没事拆着玩么?比如把18~20楼拆了,换个盖法。或者把楼里的钢筋全换一遍,换个回扣给的工作的牌子。你不会吧。所以你盖好之后,你那份文档描述的就是你的building,所以可以从下水道偷偷溜到你楼顶。所以这份文档是即使的反映了这个building的结构与状态的。
反过来,看软件开发。你能保证你写完之后的code有几天不被改?重写,重构,bug fix,需求变更。这些常见的活哪个不是要你改code。而你弄了那么多的文档,最后发现和code完全不一致了,那你说这效果能好么。文档说CLASS A是干这事的。结果一看code发现CLASS A根本就不是干那事的。当然,也可能你根本已经找不到CLASS A这么一个玩意儿了。
所以说文档足够多并不一定好,因为软件开发中,变化是从头到尾的。所以如果文档的变化跟不上项目的变化,太多的过时信息。最终非但不能帮助项目,却还会拖后腿,造成更多的怀疑,浪费经历。
少就是多?
爱扯Agile的肯定都说过这么一句话:代码即文档。
嗯,如果我没记错,好像这句应该是敏捷宣言中的?(刚查了下,原话和我记性不太一样,原话是:Working software over comprehensive documentation.)就是说如果你的代码写的足够好,本身就足够说明很多问题(比如通过起带有意义名字的变量,比如使用元数据编程,比如加恰当的注释)。那么就不需要和外在另外一个地方写场面大论来描述代码是怎么回事。
其实这方面我觉得很有代表性的就是javadoc和Xdoclet。javadoc也影响了很多后来的框架和语言啊。因为做的确实不错。通过在注视中加入一些符号,可以自动通过程序来抽象出注释,组成有意义的文档。这是多么automatic的事情。而且特别是你的注释和你的code在一起,就减少了很多两遍对不上,描述过时这类的事情。Xdoclet当然也是关于这方面的一个工具吧。
嗯,还有元数据以及DSL这种编程方式也在很大程度上为代码可读性做出了优秀的贡献。
比如Rails中,在Model之间声明关系用的belongs_to, has_many之类的关键字(当然,其实他们不算关键字,也是方法,只是表现形式cool了些)。是多么的简洁,有力,聪明,异动啊。
所以我基本上很赞成,因为大科学家爱因斯坦都说简洁性就是一种美。因为俺觉得懒惰的程序员才是好程序员。如果代码就够清楚的,或者通过代码就能生成出来很清楚的文档,那么鬼才写文档。当然,其实这观点是偏激的。因为我们确实需要文档。因为代码只能从微观角度看问题,即便你给我一个SDK文档,我还是很难看出你当初都是为什么这么设计,那么构造之类的。So,我们依然需要文档。但是要强调一定,我们需要的是高质量的文档,正确的文档。因为Diane说过:方向很重要(嗯,某次开大会说滴,很富哲理啊)。文档都是错了,就算你看个三天三夜,你也只能越看越错下去。所以,文档只有在正确的时候,才具有很大的重要性。如果只是过时的玩意儿,那么不如放到回收站吧。
The End
到现在,观念应该清楚了,文档其实还是需要的,但是我们如何去写文档呢?怎么使得文档是正确,有重大价值的呢?
嗯,我又发明了一个小所写KISSS原则。全称是:Keep it simple, stupid and synchoronous with your project. 嗯,别小看后半句噢,其实是一件非常难滴事情呢。因为锻炼你的写作技巧,尽量使得文档简洁又易懂,也许需要一些时间的锻炼,都能达到。但是synchoronous with your project需要的可是你长期的坚持啊。如果你的项目中某方面的改变牵扯到一些文档,会造成一些文档的过时,那么不要犹豫,立即更新它吧。真的不骗你,bad document的味道不比代码中bad smile造成的伤害小多少。
好吧,最后的结论就是,尽量写具备自描述能力的代码。如果某些时候,必须要写文档才能解决问题的时候,记得随时更新它。使它和你的项目保持同步。
随便聊聊-结对编程的三点看法
三 5th
眼睛一睁一闭,一天就过去了,嚎~~~~
嗯呐,一不小心,就又是好几天没更新blog。时间真的过的太快了。今天开了一上午的会,大伙聊了很多东西,搞的人比较high,这会离下班还有半个小时。任务也提前完成了。所以拿来写篇BLOG吧。
今天呢,就是同事给我们讲了一些Pair Programing的一些东西,算是Agile的一部分吧。当然,像我这种一贯喜欢否定的人总还是会提出很多自己的看法,毕竟,独立的思想与完整的人格我觉得是必须坚持滴。哇咔咔
好吧,不自夸了。今天要说的三点究竟是哪三点呢。请看大屏幕下面继续。
一,Pair Programing不一定就提高生产效率以及代码质量。记得我第一次看完《人月神话》之后,就坚信了一个观点:没有银弹。任何方法论或者所谓的最佳实践都有其自身的局限性,所以你要是给我说一个东西怎么都好,我直接心里就否定了。没有怎么都好的东西,包括现在这么hot,甚至都快过气的Agile这个big buzz word,当然也就有PP这个子集了。因为想起这些我就想起了CMM在很多年前的样子。诚然,Agile是有很多不错的理念,但千万要记得,没有银弹。PP也不可能面面俱到的。比如,性格不合的两个人去PP,互相谁也说服不了谁,结果一个变量的命名究竟是叫love_you还是LoveYou就争执了一上午,导致啥都没干。我主观不认为这会提高任何效率与质量。同样,俩人如果关系特好,互相默契很高,但如果很不专业,在一块躲在角落里偷偷的看《Prison Break》,然后每个小时看一集,再用剩下的不到20分钟时间里随便堆砌点垃圾去提交。这也是敷衍了事滴。再比如,如果你的上级给你们小组4个人每个人分了30个ticket。要求2天做完。这种根本是Mission Impossible的事情。你说这4个人会有心情PP么,会有心情考虑如何帮对方把代码写的优雅,把逻辑写的清楚不?反正我不信。还有,如果说我今天只不过是要修改一些页面上的typo或者是小样式,如果叫个人跟我Pair,他80%的时间里肯定觉得非常无聊。你觉得呢?上面举了好几坨例,有时候两个人会把事情搞的更糟,有的时候虽然不会搞的更糟,但是也会造成效率的浪费。想想Yahoo的衰败以及SINA的收购,过分的民主或者过分的股权分散,其实都是很不好的事情,会浪费很多机会,也会浪费很多时间去扯皮。在PP这里呢,就是PP不能确保提高效率以及质量。
二,一切方法论,包括Pair Programing其实最重要的因素都是人。嗯,确实是这样,从我上面举的例子应该看出来基本都是人造成的PP好用或不好用。其实这基本等于废话,计算机来说1+1等于2那就是定了。人喝多了那他可什么答案都敢说。人本身充满着不确定性,所以,把一切问题都归结到人肯定是放之四海而皆准的废话。可我还是喜欢强调这个,就是因为我发现虽然大家都知道人是问题的根源,但大家却不一定能重视这个认知。我把这个现象叫做‘认知回避’,是啊,谁没事愿意觉得自己这个物种是很不完善的呢。需要改进的呢。但回避也没用,反而后果更大。早点正视这个问题,正视你我包括所有人都有优缺点,都有不完善的地方,都会犯错误这个神一般存在滴事实,是很有益处的。只有你清楚的知道你的优缺点,你才知道如何去改掉缺点,或者如何避免你的缺点所造成的负面影响。好吧,说远了,回到PP,PP其实好处也是一大堆呢,具体的就google吧。可是如果想使PP发挥到如同那些大牛所说的魔力或威力的话,有一个很重要的条件,就是实施PP的人(之所以不说是第一重要的条件是因为第一条件肯定是得有台电脑-_-###)。你想想大牛说的那些魔力威力来自于PP,其实很大一部分也来自于那些人本身。因为他们本身就足够优秀,所以如果配上合适,科学的方法的话。那肯定做出来的成绩就更加的优秀了。所以,你如果想用PP也能收到同样的效果,那有很重要的一点就是除了按照大牛告诉你的最佳实践来实施PP本身,还一定要努力让自己向大牛看齐。包括你的人品,素质,性格,看待问题的角度,理解能力,沟通能力等等。这就好比乘法:PP比如说是5,如果你是2,那么得到的结果就是10,如果你是-2,那么得到的结果就是-10了。现在想明白了吧,PP重要的其实是你自身,流程啊,方法论,书上的探讨了,但是大部分PP的资料都不会讲关于提高你自身的方法,所以,速度补上这块短板吧。不然即便PP再好,你是个-2,那也没辙。
三,客观点,科学点。嗯,今天其实听同事讲PP这个topic,真的是听起来很美,但是最让我感到忐忑的就是没有数据。虽然developers都积极的表明PP提高了很多代码质量,可是从QA的角度就是还没有个数据。我觉得其实数据很重要。否则,空对空,很容易使大伙回到几十年前“赶英超美”那个疯狂的年代。所以,务实点,尽量脱离主观感觉,通过客观的数据来证明一件事物的属性,或者一件事情的好坏,或者一套方法论的可用性。这才是科学的态度啊。所以,我在会上也提了,希望可以量化PP带来的好处。看看PP对于我们的实际帮助到底是怎样的?不能莽撞认为我实施了PP,那PP资料里面所描述的那些个好处,我自然就得到了(想象曾经的EJB,真正让你得到了多少好处呢?)。科学的态度不是这样的,因为不要忘记了,想要发挥PP最大威力,你还得是那个2才行。(参见第二点)。
嗯,一不小心,就说了这么长,其实挺恨自个的,老喜欢跟人抬杠。但是吧,我爱科学啊。科学家最喜欢干的事儿就是怀疑与否定了。所以,对于这些看起来都很美的东西,一定不能让自己一下子就被带进去。不管是SOA, Agile还是最近的REST和SNS。因为真理往往掌握在少数人手里,也许你能多独立思考那么一晚上,你可能就能领悟到比别人更多的东西。同时也能训练着自个变得更加的客观。何乐而不为啊。
咳,老是一不小心就又扯的没边儿。好吧,准备就此搁笔吧。关于PP,其实我并没有深仇大恨,只不过赞扬的人太多了,我就想客观的说点别人没说或者没想的东西。
其实经历过这5,6年的软件开发,真的慢慢感觉出来一个道理:
成功的因素存在太多偶然性,而失败的因素中,很多原因确是具有必然性的,所以关注失败也许是为了迈向成功更好的一种途径。
所以,我现在很喜欢研究失败,研究最差实践,嗯,基本大伙管这个叫-教训。我想也许以后我会多聊聊关于失败,关于错误的事情?哈哈,看我时间吧。
PS:下一篇,准备简单聊下我对项目中各色各样的文档的看法。欢迎拍砖。
近期评论