面向对象的范式是思考程序设计时一种新的而且全然不同的方式许多人最开始都会在如何构造一个项目上皱起了眉头事实上我们可以作出一个好的设计它能充分利用OOP提供的所有优点 有关OOP分析与设计的书籍大多数都不尽如人意其中的大多数书都充斥着莫名其妙的话语笨拙的笔调以及许多听起来似乎很重要的声明(见注释)我认为这种书最好压缩到一章左右的空间至多写成一本非常薄的书具有讽剌意味的是那些特别专注于复杂事物管理的人往往在写一些浅显明白的书上面大费周章!如果不能说得简单和直接一定没多少人喜欢看这方面的内容毕竟OOP的全部宗旨就是让软件开发的过程变得更加容易尽管这可能影响了那些喜欢解决复杂问题的人的生计但为什么不从一开始就把事情弄得简单些呢?因此希望我能从开始就为大家打下一个良好的基础尽可能用几个段落来说清楚分析与设计的问题 [注释]最好的入门书仍然是Grady Booch的《ObjectOriented Design withApplications第版本》Wiely & Sons于年出版这本书讲得很有深度而且通俗易懂尽管他的记号方法对大多数设计来说都显得不必要地复杂 不要迷失 在整个开发过程中最重要的事情就是不要将自己迷失!但事实上这种事情很容易发生大多数方法都设计用来解决最大范围内的问题当然也存在一些特别困难的项目需要作者付出更为艰辛的努力或者付出更大的代价但是大多数项目都是比较常规的所以一般都能作出成功的分析与设计而且只需用到推荐的一小部分方法但无论多么有限某些形式的处理总是有益的这可使整个项目的开发更加容易总比直接了当开始编码好! 也就是说假如你正在考察一种特殊的方法其中包含了大量细节并推荐了许多步骤和文档那么仍然很难正确判断自己该在何时停止时刻提醒自己注意以下几个问题 () 对象是什么?(怎样将自己的项目分割成一系列单独的组件?) () 它们的接口是什么?(需要将什么消息发给每一个对象?) 在确定了对象和它们的接口后便可着手编写一个程序出于对多方面原因的考虑可能还需要比这更多的说明及文档但要求掌握的资料绝对不能比这还少 整个过程可划分为四个阶段阶段刚刚开始采用某些形式的结构 阶段拟出一个计划 第一步是决定在后面的过程中采取哪些步骤这听起来似乎很简单(事实上我们这儿说的一切都似乎很简单)但很常见的一种情况是有些人甚至没有进入阶段便忙忙慌慌地开始编写代码如果你的计划本来就是直接开始开始编码那样做当然也无可非议(若对自己要解决的问题已有很透彻的理解便可考虑那样做)但最低程度也应同意自己该有个计划 在这个阶段可能要决定一些必要的附加处理结构但非常不幸有些程序员写程序时喜欢随心所欲他们认为该完成的时候自然会完成这样做刚开始可能不会有什么问题但我觉得假如能在整个过程中设置几个标志或者路标将更有益于你集中注意力这恐怕比单纯地为了完成工作而工作好得多至少在达到了一个又一个的目标经过了一个接一个的路标以后可对自己的进度有清晰的把握干劲也会相应地提高不会产生路遥漫漫无期的感觉 座我刚开始学习故事结构起(我想有一天能写本小说出来)就一直坚持这种做法感觉就象简单地让文字流到纸上在我写与计算机有关的东西时发现结构要比小说简单得多所以不需要考虑太多这方面的问题但我仍然制订了整个写作的结构使自己对要写什么做到心中有数因此即使你的计划就是直接开始写程序仍然需要经历以下的阶段同时向自己提出一些特定的问题 阶段要制作什么? 在上一代程序设计中(即过程化或程序化设计)这个阶段称为建立需求分析和系统规格当然那些操作今天已经不再需要了或者至少改换了形式大量令人头痛的文档资料已成为历史但当时的初衷是好的需求分析的意思是建立一系列规则根据它判断任务什么时候完成以及客户怎样才能满意系统规格则表示这里是一些具体的说明让你知道程序需要做什么(而不是怎样做)才能满足要求需求分析实际就是你和客户之间的一份合约(即使客户就在本公司内部工作或者是其他对象及系统)系统规格是对所面临问题的最高级别的一种揭示我们依据它判断任务是否完成以及需要花多长的时间由于这些都需要取得参与者的一致同意所以我建议尽可能地简化它们——最好采用列表和基本图表的形式——以节省时间可能还会面临另一些限制需要把它们扩充成为更大的文档 我们特别要注意将重点放在这一阶段的核心问题上不要纠缠于细枝末节这个核心问题就是决定采用什么系统对这个问题最有价值的工具就是一个名为使用条件的集合对那些采用假如……系统该怎样做?形式的问题这便是最有说服力的回答例如假如客户需要提取一张现金支票但当时又没有这么多的现金储备那么自动取款机该怎样反应?对这个问题使用条件可以指示自动取款机在那种条件下的正确操作 应尽可能总结出自己系统的一套完整的使用条件或者应用场合一旦完成这个工作就相当于摸清了想让系统完成的核心任务由于将重点放在使用条件上一个很好的效果就是它们总能让你放精力放在最关键的东西上并防止自己分心于对完成任务关系不大的其他事情上面也就是说只要掌握了一套完整的使用条件就可以对自己的系统作出清晰的描述并转移到下一个阶段在这一阶段也有可能无法完全掌握系统日后的各种应用场合但这也没有关系只要肯花时间所有问题都会自然而然暴露出来不要过份在意系统规格的完美否则也容易产生挫败感和焦燥情绪 在这一阶段最好用几个简单的段落对自己的系统作出描述然后围绕它们再进行扩充添加一些名词和动词名词自然成为对象而动词自然成为要整合到对象接口中的方法只要亲自试着做一做就会发现这是多么有用的一个工具有些时候它能帮助你完成绝大多数的工作 尽管仍处在初级阶段但这时的一些日程安排也可能会非常管用我们现在对自己要构建的东西应该有了一个较全面的认识所以可能已经感觉到了它大概会花多长的时间来完成此时要考虑多方面的因素如果估计出一个较长的日程那么公司也许决定不再继续下去或者一名主管已经估算出了这个项目要花多长的时间并会试着影响你的估计但无论如何最好从一开始就草拟出一份诚实的时间表以后再进行一些暂时难以作出的决策目前有许多技术可帮助我们计算出准确的日程安排(就象那些预测股票市场起落的技术)但通常最好的方法还是依赖自己的经验和直觉(不要忘记直觉也要建立在经验上)感觉一下大概需要花多长的时间然后将这个时间加倍再加上%你的感觉可能是正确的也许能在那个时间里完成但加倍使那个时间更加充裕%的时间则用于进行最后的推敲和深化但同时也要对此向上级主管作出适当的解释无论对方有什么抱怨和修改只要明确地告诉他们这样的一个日程安排只是我的一个估计! 阶段如何构建? 在这一阶段必须拿出一套设计方案并解释其中包含的各类对象在外观上是什么样子以及相互间是如何沟通的此时可考虑采用一种特殊的图表工具统一建模语言(UML)请到去下载一份UML规格书作为第阶段中的描述工具UML也是很有帮助的此外还可用它在第阶段中处理一些图表(如流程图)当然并非一定要使用UML但它对你会很有帮助特别是在希望描绘一张详尽的图表让许多人在一起研究的时候除UML外还可选择对对象以及它们的接口进行文字化描述(就象我在《Thinking in C++》里说的那样但这种方法非常原始发挥的作用亦较有限 我曾有一次非常成功的咨询经历那时涉及到一小组人的初始设计他们以前还没有构建过OOP(面向对象程序设计)项目将对象画在白板上面我们谈到各对象相互间该如何沟通(通信)并删除了其中的一部分以及替换了另一部分对象这个小组(他们知道这个项目的目的是什么)实际上已经制订出了设计方案他们自己拥有了设计而不是让设计自然而然地显露出来我在那里做的事情就是对设计进行指导提出一些适当的问题尝试作出一些假设并从小组中得到反馈以便修改那些假设这个过程中最美妙的事情就是整个小组并不是通过学习一些抽象的例子来进行面向对象的设计而是通过实践一个真正的设计来掌握OOP的窍门而那个设计正是他们当时手上的工作! 作出了对对象以及它们的接口的说明后就完成了第阶段的工作当然这些工作可能并不完全有些工作可能要等到进入阶段才能得知但这已经足够了我们真正需要关心的是最终找出所有的对象能早些发现当然好但OOP提供了足够完美的结构以后再找出它们也不迟 阶段开始创建 你可能是程序员现在进入的正是你可能最感兴趣的阶段由于手头上有一个计划——无论它有多么简要而且在正式编码前掌握了正确的设计结构所以会发现接下去的工作比一开始就埋头写程序要简单得多而这正是我们想达到的目的让代码做到我们想做的事情这是所有程序项目最终的目标但切不要急功冒进否则只有得不偿失根据我的经验最后先拿出一套较为全面的方案使其尽可能设想周全能满足尽可能多的要求给我的感觉编程更象一门艺术不能只是作为技术活来看待所有付出最终都会得到回报作为真正的程序员这并非可有可无的一种素质全面的 |