最近在看两本书,一本是敏捷软件开发,另外一本是微软团队的成功之路。两本书都是还没有看完一半,但是都有了不少的体会,觉得自己的思路开阔了不少。
以前总以为做架构师,或者做项目经理一类型的职业,都需要有非常深入的技术知识。后来发现不是这么一回事,这种高级位置上面的职业需要有一种总体的把握能力。正确的讲,并不是不需要深厚的技术知识作为基础,相反,技术知识非常重要,但是处于不同的层面,就有不同的东西需要关注。在架构层面,或者项目层面上,需要关注的实际上并不是技术,而是诸如组织团队、分配资源、管理项目等等。
在这两本书里面我们都可以或多或少的看到背后所关注的“人”的问题,怎么样让人发挥最大的创造力,使团队成功的关键之一。当然大家的创造力必须统一到一个大方向上面,这就是领导者的职责所在。有时候我们会有这么一些经历:上司不赋予你和你的团队以明确的权利和责任,整个项目不关注与用户的沟通,项目进度和想象当中的差别很大,以及团队内部不良情绪在蔓延。
如果你和你领导的团队没有明确的权利与责任,那就比较容易做事缩手缩脚,对于一些明显会出问题的地方没有人愿意指出或者不知道该向谁指出,当真正出现问题的时候没有人能够承担,即使有人承担了,那也会有一种替罪羊的感觉。在这么一种环境里面,每个人都会觉得什么时候倒霉的事情就会落到我的头上了。
如果拥有了明确的权利和责任,还需要用合适的方式去分配。其实自己最清楚自己的实力,如果让大家坐下来进行商讨,也许会得到更满意的结果。每一个人能做什么不能做什么,不应该决定于他所在的位置或者在公司呆得时间的长短,而应该是专业方面的知识水平。如果你把一些其实你没有能力控制好的事情把握在自己的手上,最后有可能倒霉的是自己。
项目最终是否成功,是看你对设计是否满意呢,还是看用户对需求的实现是否满意?明显是后者。你的产品赚不赚钱,看你的用户满不满意,用户则只关心他想要的东西你有没有给他,至于里面的技术细节则是一点都没有兴趣关心,因此开发的时候一定要立足于满足需求这一点。然而过去的软件工程方法,在这方面我看是有缺陷的。里面虽然有需求分析,但是这里的分析一共只进行一次,并且期待着尽量在整个开发阶段封闭需求。之前我的一个Post也说到了,除了需求随着时代的变化会变化之外,客户看到了一个发布之后就可能对以前的需求有了新的了解,也会产生变化。从这个方面来说,封闭需求就是不明智的一件事情。然而封闭需求还会导致一件非常不好的事情,它会让我们轻易的陷入从一开始就把各个细节设计清楚。事实证明,很多时候不要说客户,连我们这些开发人员对于整个东西是什么,而我们却总是对自己的思考能力过于高估,而对想象能力过于低估。最后我们想出来很多很多的功能,但是有好一部分却不不符合需求,此外还会有很多没有用的东西出现。开发的过程需要尽快发布新的原型,让用户去进行实际体验,看看有什么不符合的。其实传统的软件工程学里面也说到,项目越是进行到后面的阶段,修改编码尤其是修改需求变化方面的代码代价就越大,这一句话确实是对的。然而过去的很多方法比如瀑布模型,却企图把需求封闭在一个特定的阶段(需求分析阶段,顶多是到设计阶段),一旦到了编码就不允许对需求甚至设计进行修改。这是一个愚蠢的方法,除非你确实是这一个方面的专家,有着丰富的经验,并且引领着行业的潮流,你说了就算。不幸的是很多时候不是你说了算,而是客户说了算,就算你说你的设计多名优秀,客户说不要那就是不要。封闭需求、设计之后,一旦用户对最终产品不满意,那么实际上还是需要回到需求分析阶段,这个时候代价就非常的大了。所谓的敏捷开发的其中一个目的就是希望让需求变化来的越早越好,减少在开发后期才出现的需求变化。不停地进行迭代,尽量缩短每次发布的周期。在每一次迭代完成之后,让用户去亲身感受一下,可以让你知道这一阶段的设计是否就是客户想要的东西。因此一个项目要成功,和用户进行沟通实际上是很重要的,这种沟通越频密越好。
有人就会说了,我的用户在十万八千里以外,不可能经常来我们这里进行体验。如果说请求对方指派代表是不可行的,那么也需要考虑在项目团队内部设立一个专门进行模拟客户的角色,这个人必须熟悉这一个市场。如果没有人熟悉,那么就专门找一个人来熟悉这方面的工作。这一个角色总得由人来担任,就像编码人这个角色总得由人来担任一样。
如果我们能够真正的从客户这个角度来考虑问题,我们就会发现我们以前的很多设计方法是有问题的。比如说我们会产生一大堆的文档,从细小到如何对数据进行排序的函数开始设计代码,在设计里面为以后可能出现的需求变化留下“钩子”。为什么说这样做有问题?
我们首先看看文档,难道用户需要的是文档吗?需要看看你的FooStory是派生还是引用JokeImplement的设计文档吗?还是TempleteMethod/MVC/Decorate之类的词语在某个文档中出现会让他升官发财?统统都不是!他要的是能够正确运行并且提供他所需要的功能的软件。软件才是中心,不是吗?有人也许会说,UML之类的东西是为了让我们的设计更加清晰。可是这些UML图最终还是要转化为代码的,如果你的代码设计的充分好,就会有比较好的自解释能力,就算什么地方有不太容易理解的地方,在代码里面添加简单的注释基本上都能够解决问题。反过来说,当你的程序因为Bug或者其他原因需要进行调试和修改,你觉得你首先要读的是UML图还是代码呢?代码永远都只有一种解释,但是文档则难免会有二义性存在。思考完这些问题,我得出一个结论:我们应该围着代码转,然后产生文档,而不是围着文档转,然后产生代码。
接下来看看设计的方向。因为我们错误的从一开始就把整个需求确定下来,甚至到了毛细血管的程度,所以我们会不自觉地首先实现最为底层的东西。这个惯性很好解释,因为我们需要编译通过。如果class a里面使用了class b的实例,如果首先写class a,肯定无法立即编译通过。如果我们要一次过完成一个可编译的版本,那么从上面开始写,三天三夜不眠不休都不可能完成。所以我们就从class b开始我们的工作。但是这样却需要等你将整个系统的所有部分(至少是主要部分)都完成了之后,才可能发布一个可以给用户演示的版本,需要的时间通常会非常漫长。如果我们反过来从顶层开始往下写,只要我们设法保证每天都能够产生一个可用版本,那么随时都可以拿出来给用户演示。实际上一些很细节的功能用户一开始并不会很清楚,所以我们也不可能很清楚,一些东西也许并不会出现,另外一些东西也许没有考虑进去,还有一些则并不是你原来想象的那样。如果一开始就埋头做哪些细节的功能,很可能最后会发现,有很多东西其实就是在浪费你的青春。至于怎么进行自上往下的设计,留着以后再讲。
另一个我们比较容易犯的错误,就是留“钩子”。这个错误我也一直在犯,并且总是忍不住会犯。很简单,你的经验告诉你,需求是会变化的,因此需要考虑为以后的需求变化预先进行设计。这是一个非常愚蠢的想法,当我明白这一点之后我简直是无地自容。前面我们已经看到了,在整个开发的过程中,需求就会不断地变化。这种变化就像一串随机序列,根本就无法把握。你以为它会是那样的,甚至可能客户一开始也那样以为,接下来没几天客户就说不是那样的。如果你能够在一开始就能预测这种变化的方向,你就有能力应用瀑布模型,你就可以封闭需求,你就可以简单的面对客户今天说要这个明天说不要那个的情况。事实上明显不是这样的,需求的更改不可能按照你的设想去进行的。如果说今天你要设计的软件的需求,你都不可能预见,那么你凭什么那么自信的认为你知道明天的需求要变成什么?“即使最后发现需求确实不是向着你想的方向发展,那这些代码顶多是没有用,难道还会有害么?”我认为是有害的,因为它影响了你的重构。很多时候我们解决某一类特定的问题可能会有好多的方法,比如我们可以Templete或者Strategy等等,每一种解决方法都有它的侧重点和副作用。假设我们把Templete用在了这些地方,到最后也许我们的需求变化要求我们使用Strategy,那么要从整个设计里面拔除已有的Templete相关的代码将会是痛苦的。实际上问题可能还会更严重,假如你这个Templete是在一个组件里面,拔除这个Templete很可能会对另外一个使用这个组建的系统产生影响,最后你不得不修改另外几个系统,重新deploy。当然,这个也许是极端的情况,但无论如何它肯定会对你未来的修改或者重构造成障碍。
好了,今天只是一个粗略的笔记,详细的内容日后再写,来日方长嘛。本来还想画一些图,让页面更加rich一点,但是已经霸占JGTM的19'一天了,不好意思霸占下去。回到另外一台17'的显示器,就完全没有了画图的激情与欲望了。还是看看书算了……
打印 | 张贴于 2004-09-08 00:08:00 | Tag:Design & Architecture

留言反馈
长期在博客堂潜水,读到精彩之处不由得抓耳挠腮,恨不得拉住作者手舞足蹈一番,呵呵。
好多文章称系列的真希望有个人专门整理一下,个人写个人的有时候不太好搜集。
非常感谢你的信息!其实Steve McConnell的这几本著作(包括更为著名的Code Complete,以及已经出版的2nd Edition的draft,还有Successful Software Development等等)我都多少读过,应该说从中获得了不少的启发。
我感觉,项目开发和产品开发主要差异就是在需求设定环节。前者是强调收缩需求以降低成本提高利润,而后者则是要扩张需求以获得更大的市场机会。由此带来的对开发迭代、客户合作关系等的影响也就多少有些差异了。
等我再研究研究MSF Agile吧,回头还要老兄多多指教。谢谢!:)
关于书,偶也推荐一本:
Rapid Development, by Steve McConnell (Microsoft Press),Jolt Awards , 1996
Average Customer Review:5 star. Based on 95 reviews.
Amazon.com Sales Rank: 2,792
摘一段比较有意思的评论供参考:“I'm a big fan of eXtreme Programming (XP) so I was particularly interested in reading this book to see if I could pick up some ideas and concepts different from that of XP. I was quite suprised to see many of the concepts and best practices McConnell presents in this book are very consistent with XP's practices. ”
关于msf,偶认为MSF没有针对产品开发或者项目开发,不能从字面上来理解。从msf team model上面来看,设立了product manager,可以表明msf是以微软产品开发经验为基础总结出来的东西。
MSF Agile刚刚大概看了看,基本的principle还是来自msf。在流程部分强调了iteration,在设计阶段强调了架构师的作用并以建立qos需求的方法来帮助明确功能需求加入非功能性需求,在开发部分引入了流行的测试驱动的元素,在测试和发布方面和msf好像差不多。
总体看来设计过程被简化了,设计职责主要落在了ba身上,而这个角色是以前msf团队模型里面没有的。msf过程中的设计会在functional spec的基础上由开发人员来做。开发过程由于使用了iteration加上测试驱动,也变灵活了。只是不知道ms内部会不会广泛使用这种方法来做开发,还是仅仅是跟跟敏捷的风。
To 乱发吹风:
感觉你们就更需要使用这种方式了,因为他们的需求更不明确,更需要你们的引导。
我要求sumtec及所有开发人员研读的就是Robert C. Martin荣获2003年度JOLT大奖的Agile Software Development: Principles, Patterns, and Practices。另一本Alistair Cockburn写的Agile Software Development(12届JOLT大奖)也是我很喜欢的一本读物。而下一本我要大家研究的读物则是本年度JOLT大奖得主Test-Driven Development: A Practical Guide。
另外关于显示器:Dell P991 (Sony OEM)
行频103.9KHz(最大分辨率1600x1200x85Hz)
Sony纯平特丽珑
@ymail:
请关注我近期即将问世的系列文章Thinking in PPP——这叫兵马未动,粮草先行!;)
@rIPPER:
MSF是微软为解决solution开发而提出的过程方法,它不完全适用于产品开发。另外,在MSF 4.0里面也出现了所谓MSF Agile(相对于MSF Formal)的轻量级敏捷方法框架,然而它得针对目标仍然是项目开发。
我们只是吸收其中的精华,然后结合我们团队自身的特征发展适合自己团队和项目的过程方法。谢谢你的建议!:)
@program:
你的风格还是没变啊!呵呵。:)
@开心就好:
别瞎起哄!你,你,先请客再说!:P
BTW: 小强和雷达是我们团队开发实践过程中的真实案例,就目前的进展来看成果还是比较显著的(已经用光三瓶雷达了)……
Practice是实践中来的有用的技巧,
Pattern又比Pratice更抽象,一个Pattern在运用于不同的场合需要做不同的调整,这就涉及Pattern运用中的Practice问题,若干相近的Practice进一步概括提升就成为某个Pattern.
而Principle比Pattern更概括更抽象,Pattern本身就是为满足一定的Principle设计出来的,Pattern是Principle在设计中的体现.
当我们学习软件开发时,我们首先学习Principle,因为以后的内容都是由它们所规定的.然后我们学习Pattern,掌握一些Principle运用的定势.最后我们学习Practice,知道如何灵活应用这些Patterns.
论内容的数量,Principle少于Pattern少于Practice
在软件开发过程中用到的Principle并不限于软件世界中,同样重要的是人类世界中的Principle,团队组织,需求分析这些都是人类世界中的问题.
先从从大框架起,自上而下调整需求,
而自上而下的方法就是尽快产生可用版本,让软件说话。让客户发现问题。
(顺便问一句,你看得是那本《敏捷软件开发》)
还是最后一句最有意思,呵呵。
2、项目是否成功 当然是最终用户需求的满足,但做为架构师,你关心的还是以技术为主
3、敏捷软件开发并没有给我“震撼”,我推崇快速原型,但我同样对很多敏捷软件开发中提供的“最佳实践”不感冒
4、“客户角色”参与项目开发,这是我们都希望的,可是实际上要做到又谈何容易
再多说一点,敏捷开发方式本身己也不否认前期设计的重要性的,“唯一不变的就是变化”不是否定前期设计的借口,不同的系统开发应该不同对待。架构比框架重要,而设计模式不过是实现的一种手段罢了,单独地去谈DP没有多大的意思。
"DesignPattern相对(诸如TTD)来说就是一种技术工具,而不太像解决问题的方法论",确实精辟,可称经典!
By the way, 你们另外的那个程序员要写的稿子写出来了吗?:)我可等了得有将近一个月了?
我看中国软件靠政府采购是发展不起来的!
Exactly! Great point!!
就像我今天说有个朋友想让我培训23种设计模式,我是怎么说的?他以为这23种设计模式是做菜的必要原料了,还缺一不可。难道你会把厨房的全部家当一股脑的放进锅里面乱炖吗(好像东北有这种做法的说……)?一道精品菜肴肯定是根据口味需求、营养需求、观感需求等等结合你手中的原料优选组合精心调制出来的。不了解烹饪的基本原理而滥用原料,只会做出难以下咽的垃圾。
BTW: 用小强和雷达来举例确实略微BT了一些!呵呵……
是啊,我已经发现我想得太细致了,尤其对一个问题我现在还是从底下往上构建,这是一个错误的方向,至少不是满足需求所需要的方向。如果一开始就首先去满足最终要的那些需求,也许会更好。其实我想思考得更加全面,在有经验的情况下,并不完全是坏事。当然了,必须得满足从上面往下走,必须满足职责单一,必须满足简单有效,必须满足不产生多余功能,必须满足互相隔离等等的要求。
其实我想系统在分析设计的阶段里面,到底要达到一个什么样的粒度,这个取决于多方面,没有可能给出一个任何人任何团队都使用的、具体量化的标准。比如说这个系统本身有多复杂,这个团队的技术能力有多高,经验方面如何,初始状态下所能够完全确定的需求有哪些等等,都影响着能够一次实现的细节程度。
当然,我市完全赞同首先从抽象开始考虑问题,从基本需求开始考虑问题。实际上测试驱动开发给了我很大的启发,我想我已经知道我的一些问题所在了。不过我也认为很多东西都是相辅相成的,如果光有这样的考虑方法而没有具体的技术支撑,那也会有问题的,所以才会有DesignPattern。我甚至就认为DesignPattern相对(诸如TTD)来说就是一种技术工具,而不太像解决问题的方法论。也许这么说有点过分,不过你知道我是什么意思。
这次不结合实际了,因为暂时也还没有把头绪都理清楚。还没有理清楚之前也可以写写粗略的东西,就像软件开发上面的第一次碟带,关键是要动手写,写出来了之后哪怕不准确,但是能看那就已经成功了。写出来了就会有众多的客户有反馈,有了反馈我就知道小强在哪里,知道小强在哪里我就可以拿着雷达追着喷,我不要闷头想了半天最后写出来的东西是错的,就算最后发现是对的那也会有另外一个糟糕的结果:就像打太极一样,等我明白过来之后通常就比较难写出来了。
1、Working software is always the first of all! 功能可以不够多,但是随时是可以运行的软件。
2、YAGNI,KISS!尤其是对于像你sumtec这样编码能力超强的人来说,更是要强迫你放下那些永无休止的技术蔓延。
3、最后,我要求大家在OOAD方面深造再深造,以保证我们随时有能力将已经能够工作的软件改善为拥有良好的结构以满足非本质的那些需求,比如说灵活性、可扩展性等等。
当然,作为企业架构师,要考虑和决策的事情还有很多很多,但是一样的道理,只有越早的满足你能看得见的需求,才可能把那些看不见的需求挖掘出来。