软件开发方法的演化史绝对是一部寻找“银弹”的历史,即研究管理软件复杂度方法的历史。我个人的体会:开发复杂的软件系统的确,呃,复杂,由此带来不菲的时间和金钱的花费。下面我们看一下5种软件方法论的发展及应用。
软件方法论之结构化编程(Structured programming)
在结构化编程思想提出之前几年,我就已经开始了(始于1973)职业编程生涯。结构化编程涉及正确使用代码块,过程调用以及各种循环结构。还有一条黄金法则:go-to是有害的。
程序结构应该清晰、流程控制易于理解,这点在今天看来是毋庸质疑的。同时我也认为,结构化编程的想法已经融入后来所有的编程方法论之中。
软件方法论之面向对象编程(Object oriented programming)
面向对象编程(OOP)方法自然也是从结构化编程思想演化而来。OOP通过封装代码与代码使用的数据来管理软件复杂度。我们习惯于处理真实世界的物理对象,在OOP中,我们可以为真实世界的对象建模(如编写模拟程序,这也是OOP概念开始提出的地方),并对非具体概念如进程、信息组织方法等建立软件模型。
程序里“对象”维护自己的内部状态,这与结构化编程非常地不同。在结构化编程里面,代码是以一种结构化的、容易理解的方式组织,全局共享数据对于软件系统的各个部分都是可见的,包括那些并不需要访问或修改那些共享数据的部分。
软件方法论之设计模式(Design patterns)
睿智的人关注他们世界的各种模式。学生时候,我们可能会注意班上同学的良好学习习惯所形成的学习模式带给他们优异的成绩。我们学习烹饪时,可能注意到有经验的厨师做菜的模式,如烹饪前先备料,加调料的时候不断的尝一下等。
在软件开发领域,设计模式的使用是基于对某些项目失败而另外类似项目成功的观察(这些也可能是管理模式,计划模式,测试模式等等)。在软件设计过程中,模式的使用是基于对一些通用的设计方式在成功项目中的重复使用的进一步研究的结果。
软件方法论之极限编程(Extreme programming)
极限编程基于对客户需求的快速确认,快速开发与快速交付使用。极限程序员与客户交流过程中使用简单的设计,并以迭代方式优先开发软件最被需要的部分。
极限编程与传统开发方式背道而驰。传统开发方式是开发者与客户花费大量时间来试图事先将一切细节写入文档,这种开发方式占用相当长的时间。有经验的开发者知道,阶段性的完成编码对设计流程有正面影响。极限编程尤其适合那些需求复杂、或需求事先无法达成一致的情况。
在学习本书中的UML时候,我们会涉及个人如何使用软件系统的例子。极限编程有类似的概念,叫做"user stories"(这个词不知道应该如何正确翻译-by译者),即客户提供的他们感觉软件系统应该如何使用的信息。User stories会被用来估计开发时间,并帮助建立自动测试用例——用于开发测试和交付用户测试。
极限编程经常被描述为——对于我而言更加容易理解——测试驱动的编程,在编码前即编写测试代码!然后编写足够的能通过测试的代码即可。在所有单元测试通过之前,软件代码不允许改动。使用像JUnit 这样的工具来编写自动测试。
软件方法论之面向切面编程(Aspect oriented programming)
面向切面编程(AOP)后面的主要思想是对软件系统不同关注点的分离,开发者通过拦截方法调用并在方法调用前后添加辅助代码来实现。切面可以在对象里除了行为之外新定义特定的切面数据(aspect-specific data)。原理上,这种哲学允许系统开发更加模块化,这种模块化的实现通过程序员不同的关注点来驱动。对于Java程序员,我推荐看一下AspectJ项目(eclipse.org/aspectj). 下面是从AspectJ站点引用的:
”AspectJ 通过对以下关注点的横切达到简洁的模块化:错误检测和处理,同步,对上下文敏感的行为,性能优化,监控及日志,调试支持,多对象协议”
无论是免费的Eclipse还是商业的IntelliJ Java IDE都支持AspectJ. AspectJ 是Java语言的扩展,需要预处理。我在为开源web框架Jaffa做收费咨询的时候用过Java的切面。在使用动态语言像Ruby和Lisp时,切面更加有用。Ruby和Common Lisp允许在任何源文件为一个类增加方法,这种优势意味着特殊的目的以及特定应用的对库的扩展可以与库的源代码相分离。
一个简单的使用切面的例子如下:你有一个类库来处理收发邮件,然后来了一个商业方面的需求,按收信人和发信人分类,记录邮件的数目和大小。分离的切面就能让你通过代码注入的方式来实现对邮件的监测,而不需要改变原类库的代码。这会让类库作者更加容易地维护他们的代码,不用增加对邮件监测的代码。
本文来自metaphy的博客:《软件设计和开发的简史》
【编辑推荐】