Why Software Development Methodologies Suck
There’s a lot of dogma in the religious wars around software development practices and methodologies. Are phase-gate methodologies effective at managing the risk of software development, or just risk management kabuki? Does TDD really make for higher quality software? Is pair programming a superior replacement for code review or just a way to inflate consulting rates? I’m going to argue that while scientific evidence to decide these claims is lacking, there are two general principles which can help us choose good practices while at the same time improving the value of the software we deliver: reduce cycle time and increase feedback.
Michael Feathers makes the following observation:
I think that, in the end, we just have to accept that developer skill is a far more significant variable than language choice or methodological nuances1. Frankly, I think we all know that, but we seem to suffer from the delusion that they are the primary knobs to tweak. Maybe it’s an extension of the deeply held view that from an economic viewpoint, it would be ideal if people were interchangeable.
The problem is, how do we get skilled developers? Since the concept of individual productivity in IT has never been satisfactorily defined, this is a particularly hard problem to solve. Lines of code - still a popular measure - suffers from the devastating flaw that a line of code is a liability, not an asset as is often thought. Measuring number of hours worked encourages heroic behavior - but experience shows that the “heroes” are usually the same people that cause projects to become late through taking unacceptable risks early on, and working long hours makes people stupid and leads to poor quality software. There is still no generally accepted set of professional standards or chartering system for IT professionals, and recruiting good people is very much an art rather than a science.
Psychologists have at least addressed the problem of why it is so difficult to acquire and measure skill in IT. As Daniel Kahneman says in Thinking Fast and Slow, there are “two basic conditions for acquiring a skill: an environment that is sufficiently regular to be predictable; [and] an opportunity to learn these regularities through prolonged practice.”
But traditional software projects are the opposite of a regular, predictable environment. The only good measure of success of a project - did the end result create the expected value over its lifetime? - is so distant from the critical decisions that caused that success or failure that it’s rare for anybody from the original team even to be present to get the feedback. It’s practically impossible to determine which of those decisions led to success or failure (in artificial intelligence, this is known as the credit-assignment problem).
软件开发实践和方法论,
常见的软件开发过程方法有:瀑布模型、迭代增量开发、敏捷开发等。
迭代增量开发弥补了瀑布模型严格分级、缺少阶段间反馈的缺点。在迭代增量开发中,项目被分割成一系列时间较短的迭代,同时整个工程被分成了不同的小部分,每一次迭代后都比上一次增加一些功能。这些小迭代中都会包括需求分析、设计、实现、测试。通过这种方法,开发可在需求被完整定义前启动,并在每次迭代完成后,通过用户反馈来细化进一步需求,并开始新一轮迭代。迭代增量开发是基于瀑布模型的,但它不要求每一次迭代出来完美的结果,而是先把主要功能构建出来,通过反馈不断完善。
迭代增量开发仍然是一种过程模型,只是从瀑布模型的线性关系转变成迭代关系,因此它仍然十分强调文档的重要性
处。
阶段式(phase-gate)方法能够有效管理软件开发过程的风险,还是说只是风险管理中的花哨噱头?TDD真的能够促生出高品质软件?结对编程是代码评审的有效替代抑或只是增加了商议沟通代价?有两条常用的法则能够帮助我们选择好的实践,同时,提升我们所提供软件的价值:划小开发周期以及提升反馈效率。
我认为,我们还是得倚重开发者的能力,这才是个更重要的考量因素,而非选择哪门语言或纠结于方法论间的细微差别[1]。坦诚地说,我们都清楚这点,但我们看起来好像过度纠结于开发能力是关键因素这事儿上。或许这是个经济学里一个被广泛接受的观点的引申,但如果人是可以轻易轮换的(随便找个人都能顶上),那才是堪称理想的。
你可能会认为当我们决定怎样运作一个团队时,我们就陷入了被动。但细想一下为什么软件开发无章可循?为什么在这个环境里很难进行一些试验以及获取技能?什么实践和决定会导致成功或失败?其中的根原因就是:环境是无规律的,做出变更与理解变更带来的结果之间的反馈过程太长了。这里的“变更”一词是指广义上的需求变更、方法变更、开发实践变更、商业计划变更、代码或配置变更等等。