1.12 分析和设计
1.12 分析和设计
面向对象的范式是思考程序设计时一种新的、而且全然不同的方式,许多人最开始都会在如何构造一个项目上皱起了眉头。事实上,我们可以作出一个“好”的设计,它能充分利用
有关
⑨:最好的入门书仍然是
在整个开发过程中,最重要的事情就是:不要将自己迷失!但事实上这种事情很容易发生。大多数方法都设计用来解决最大范围内的问题。当然,也存在一些特别困难的项目,需要作者付出更为艰辛的努力,或者付出更大的代价。但是,大多数项目都是比较“常规”的,所以一般都能作出成功的分析与设计,而且只需用到推荐的一小部分方法。但无论多么有限,某些形式的处理总是有益的,这可使整个项目的开发更加容易,总比直接了当开始编码好!
也就是说,假如你正在考察一种特殊的方法,其中包含了大量细节,并推荐了许多步骤和文档,那么仍然很难正确判断自己该在何时停止。时刻提醒自己注意以下几个问题:
在确定了对象和它们的接口后,便可着手编写一个程序。出于对多方面原因的考虑,可能还需要比这更多的说明及文档,但要求掌握的资料绝对不能比这还少。
整个过程可划分为四个阶段,阶段
第一步是决定在后面的过程中采取哪些步骤。这听起来似乎很简单(事实上,我们这儿说的一切都似乎很简单
在这个阶段,可能要决定一些必要的附加处理结构。但非常不幸,有些程序员写程序时喜欢随心所欲,他们认为“该完成的时候自然会完成”。这样做刚开始可能不会有什么问题,但我觉得假如能在整个过程中设置几个标志,或者“路标”,将更有益于你集中注意力。这恐怕比单纯地为了“完成工作”而工作好得多。至少,在达到了一个又一个的目标,经过了一个接一个的路标以后,可对自己的进度有清晰的把握,干劲也会相应地提高,不会产生“路遥漫漫无期”的感觉。
从我刚开始学习故事结构起(我想有一天能写本小说出来
我们特别要注意将重点放在这一阶段的核心问题上,不要纠缠于细枝末节。这个核心问题就是:决定采用什么系统。对这个问题,最有价值的工具就是一个名为“使用条件”的集合。对那些采用“假如……,系统该怎样做
应尽可能总结出自己系统的一套完整的“使用条件”或者“应用场合”。一旦完成这个工作,就相当于摸清了想让系统完成的核心任务。由于将重点放在“使用条件”上,一个很好的效果就是它们总能让你放精力放在最关键的东西上,并防止自己分心于对完成任务关系不大的其他事情上面。也就是说,只要掌握了一套完整的“使用条件”,就可以对自己的系统作出清晰的描述,并转移到下一个阶段。在这一阶段,也有可能无法完全掌握系统日后的各种应用场合,但这也没有关系。只要肯花时间,所有问题都会自然而然暴露出来。不要过份在意系统规格的“完美”,否则也容易产生挫败感和焦燥情绪。
在这一阶段,最好用几个简单的段落对自己的系统作出描述,然后围绕它们再进行扩充,添加一些“名词”和“动词”
尽管仍处在初级阶段,但这时的一些日程安排也可能会非常管用。我们现在对自己要构建的东西应该有了一个较全面的认识,所以可能已经感觉到了它大概会花多长的时间来完成。此时要考虑多方面的因素:如果估计出一个较长的日程,那么公司也许决定不再继续下去;或者一名主管已经估算出了这个项目要花多长的时间,并会试着影响你的估计。但无论如何,最好从一开始就草拟出一份“诚实”的时间表,以后再进行一些暂时难以作出的决策。目前有许多技术可帮助我们计算出准确的日程安排(就象那些预测股票市场起落的技术
在这一阶段,必须拿出一套设计方案,并解释其中包含的各类对象在外观上是什么样子,以及相互间是如何沟通的。此时可考虑采用一种特殊的图表工具
我曾有一次非常成功的咨询经历,那时涉及到一小组人的初始设计。他们以前还没有构建过
作出了对对象以及它们的接口的说明后,就完成了第
读这本书的可能是程序员,现在进入的正是你可能最感兴趣的阶段。由于手头上有一个计划——无论它有多么简要,而且在正式编码前掌握了正确的设计结构,所以会发现接下去的工作比一开始就埋头写程序要简单得多。而这正是我们想达到的目的。让代码做到我们想做的事情,这是所有程序项目最终的目标。但切不要急功冒进,否则只有得不偿失。根据我的经验,最后先拿出一套较为全面的方案,使其尽可能设想周全,能满足尽可能多的要求。给我的感觉,编程更象一门艺术,不能只是作为技术活来看待。所有付出最终都会得到回报。作为真正的程序员,这并非可有可无的一种素质。全面的思考、周密的准备、良好的构造不仅使程序更易构建与调试,也使其更易理解和维护,而那正是一套软件赢利的必要条件。 构建好系统,并令其运行起来后,必须进行实际检验,以前做的那些需求分析和系统规格便可派上用场了。全面地考察自己的程序,确定提出的所有要求均已满足。现在一切似乎都该结束了?是吗?
事实上,整个开发周期还没有结束,现在进入的是传统意义上称为“维护”的一个阶段
这个词便是“校订”。换言之
什么时候才叫“达到理想的状态”呢?这并不仅仅意味着程序必须按要求的那样工作,并能适应各种指定的“使用条件”,它也意味着代码的内部结构应当尽善尽美。至少,我们应能感觉出整个结构都能良好地协调运作。没有笨拙的语法,没有臃肿的对象,也没有一些华而不实的东西。除此以外,必须保证程序结构有很强的生命力。由于多方面的原因,以后对程序的改动是必不可少。但必须确定改动能够方便和清楚地进行。这里没有花巧可言。不仅需要理解自己构建的是什么,也要理解程序如何不断地进化。幸运的是,面向对象的程序设计语言特别适合进行这类连续作出的修改——由对象建立起来的边界可有效保证结构的整体性,并能防范对无关对象进行的无谓干扰、破坏。也可以对自己的程序作一些看似激烈的大变动,同时不会破坏程序的整体性,不会波及到其他代码。事实上,对“校订”的支持是
通过校订,可创建出至少接近自己设想的东西。然后从整体上观察自己的作品,把它与自己的要求比较,看看还短缺什么。然后就可以从容地回过头去,对程序中不恰当的部分进行重新设计和重新实现(注释 ⑩
构建一套系统时
反复的“校订”同“递增开发”有关密不可分的关系。递增开发意味着先从系统的核心入手,将其作为一个框架实现,以后要在这个框架的基础上逐渐建立起系统剩余的部分。随后,将准备提供的各种功能(特性)一个接一个地加入其中。这里最考验技巧的是架设起一个能方便扩充所有目标特性的一个框架(对这个问题,大家可参考第
⑩:这有点类似“快速造型”。此时应着眼于建立一个简单、明了的版本,使自己能对系统有个清楚的把握。再把这个原型扔掉,并正式地构建一个。快速造型最麻烦的一种情况就是人们不将原型扔掉,而是直接在它的基础上建造。如果再加上程序化设计中“结构”的缺乏,就会导致一个混乱的系统,致使维护成本增加。
如果没有仔细拟定的设计图,当然不可能建起一所房子。如建立的是一所狗舍,尽管设计图可以不必那么详尽,但仍然需要一些草图,以做到心中有数。软件开发则完全不同,它的“设计图”(计划)必须详尽而完备。在很长的一段时间里,人们在他们的开发过程中并没有太多的结构,但那些大型项目很容易就会遭致失败。通过不断的摸索,人们掌握了数量众多的结构和详细资料。但它们的使用却使人提心吊胆在意——似乎需要把自己的大多数时间花在编写文档上,而没有多少时间来编程(经常如此