敏捷建模的价值观
敏捷建模(Agile Modeling,AM)的价值观包括了XP的四个价值观:
沟通、
简单 、
反馈 、
勇气 ,此外,还扩展了第五个价值观:谦逊。 建模不但能够促进你团队内部的开发人员之间沟通、还能够促进你的团队和你的project stakeholder之间的沟通。 画一两张图表来代替几十甚至几百行的
代码 ,通过这种方法,建模成为简化软件和软件(开发)过程的关键。这一点对开发人员而言非常重要-它简单,容易发现出新的想法,随着你(对
软件 )的理解的加深,也能够很容易的改进。 Kent Beck在Extreme Programming Explained中有句话讲得非常好:“乐观是编程的职业病,反馈则是其处方。”通过图表来交流你的想法,你可以快速获得反馈,并能够按照建议行事。 勇气非常重要,当你的决策证明是不合适的时候,你就需要做出重大的决策,放弃或
重构 (refactor)你的工作,修正你的方向。 最优秀的开发人员都拥有谦逊的美德,他们总能认识到自己并不是无所不知的。事实上,无论是开发人员还是客户,甚至所有的 project stakeholder,都有他们自己的专业领域,都能够为项目做出贡献。一个有效的做法是假设参与项目的每一个人都有相同的价值,都应该被尊重。
原则
敏捷建模(AM)定义了一系列的核心原则和辅助原则,它们为
软件开发 项目中的建模实践奠定了基石。其中一些原则是从XP中借鉴而来,在Extreme Programming Explained中有它们的详细描述。而XP中的一些原则又是源于众所周知的软件工程学。复用的思想随处可见!基本上,本文中对这些原则的阐述主要侧重于它们是如何影响着建模工作;这样,对于这些借鉴于XP的原则,我们可以从另一个角度来看待。 ◆主张简单 当从事开发工作时,你应当主张最简单的解决方案就是最好的解决方案。不要过分构建
(overbuild)你的软件。用AM的说法就是,如果你现在并不需要这项额外功能,那就不要在模型中增加它。要有这样的勇气:你现在不必要对这个系统进行过分的
建模 (over-model),只要基于现有的需求进行建模,日后需求有变更时,再来重构这个系统。尽可能的保持模型的简单。 ◆拥抱变化 需求时刻在变,人们对于需求的理解也时刻在变。项目进行中,Project stakeholder可能变化,会有新人加入,也会有旧人离开。Project stakeholder的观点也可能变化,你努力的目标和成功标准也有可能发生变化。这就意味着随着项目的进行,项目环境也在不停的变化,因此你的开发方法必须要能够反映这种现实。 ◆你的第二个目标是可持续性 即便你的团队已经把一个能够运转的系统交付给用户,你的项目也还可能是失败的--实现Project stakeholder的需求,其中就包括你的系统应该要有足够的
鲁棒性 (robust ),能够适应日后的扩展。就像Alistair Cockburn常说的,当你在进行软件开发的竞赛时,你的第二个目标就是准备下一场比赛。可持续性可能指的是系统的下一个主要发布版,或是你正在构建的系统的运转和支持。要做到这一点,你不仅仅要构建高质量的软件,还要创建足够的文档和支持材料,保证下一场比赛能有效的进行。你要考虑很多的因素,包括你现有的团队是不是还能够参加下一场的比赛,下一场比赛的环境,下一场比赛对你的组织的重要程度。简单的说,你在开发的时候,你要能想象到未来。 ◆递增的变化 和建模相关的一个重要概念是你不用在一开始就准备好一切。实际上,你就算想这么做也不太可能。而且,你不用在模型中包容所有的细节,你只要足够的细节就够了。没有必要试图在一开始就建立一个囊括一切的模型,你只要开发一个小的模型,或是概要模型,打下一个基础,然后慢慢的改进模型,或是在不在需要的时候丢弃这个模型。这就是递增的思想。 ◆令Stakeholder投资最大化 你的project stakeholder为了开发出满足自己需要的软件,需要投入时间、金钱、设备等各种资源。stakeholder应该可以选取最好的方式投资,也可以要求你的团队不浪费资源。并且,他们还有最后的发言权,决定要投入多少的资源。如果是这些资源是你自己的,你希望你的资源被误用吗。 ◆有目的的建模 对于自己的artifact,例如模型、
源代码 、文档,很多开发人员不是担心它们是否够详细,就是担心它们是否太过详细,或担心它们是否足够正确。你不应该毫无意义的建模,应该先问问,为什么要建立这个artifact,为谁建立它。和建模有关,也许你应该更多的了解软件的某个方面,也许为了保证项目的顺利进行,你需要和高级经理交流你的方法,也许你需要创建描述系统的文档,使其他人能够操作、维护、改进系统。如果你连为什么建模,为谁建模都不清楚,你又何必继续烦恼下去呢?首先,你要确定建模的目的以及模型的受众,在此基础上,再保证模型足够正确和足够详细。一旦一个模型实现了目标,你就可以结束目前的工作,把精力转移到其它的工作上去,例如编写代码以检验模型的运作。该项原则也可适用于改变现有模型:如果你要做一些改变,也许是一个熟知的模式,你应该有做出变化的正确理由(可能是为了支持一项新的需求,或是为了重构以保证简洁)。关于该项原则的一个重要暗示是你应该要了解你的受众,即便受众是你自己也一样。例如,如果你是为维护人员建立模型,他们到底需要些什么?是厚达500页的详细文档才够呢,还是10页的工作总览就够了?你不清楚?去和他们谈谈,找出你想要的。 ◆多种模型 开发软件需要使用多种模型,因为每种模型只能描述软件的单个方面,“要开发现今的商业应
用,我们该需要什么样的模型?”考虑到现今的软件的复杂性,你的建模
工具箱 应该要包容大量有用的技术(关于artifact的清单,可以参阅AM的建模artifact)。有一点很重要,你没有必要为一个系统开发所有的模型,而应该针对系统的具体情况,挑选一部分的模型。不同的系统使用不同部分的模型。比如,和家里的修理工作一样,每种工作不是要求你用遍工具箱里的每一个工具,而是一次使用某一件工具。又比如,你可能会比较喜欢某些工具,同样,你可会偏爱某一种模型。有多少的建模 artifact可供使用呢,如果你想要了解这方面的更多细节,我在Be Realistic About the UML中列出了
UML 的相关部分,如果你希望做进一步的了解,可以参阅
白皮书 The Object Primer -- An Introduction to Techniques for Agile Modeling。 ◆高质量的工作 没有人喜欢烂糟糟的工作。做这项工作的人不喜欢,是因为没有成就感;日后负责重构这项工作(因为某些原因)的人不喜欢,是因为它难以理解,难以更新;最终用户不喜欢,是因为它太脆弱,容易出错,也不符合他们的期望。 ◆快速反馈 从开始采取行动,到获得行动的反馈,二者之间的时间至关紧要。和其他人一共开发模型,你的想法可以立刻获得反馈,特别是你的工作采用了共享建模技术的时候,例如白板、CRC卡片或即时贴之类的基本建模材料。和你的客户紧密工作,去了解他们的的需求,去分析这些需求,或是去开发满足他们需求的用户界面,这样,你就提供了快速反馈的机会。 ◆软件是你的主要目标 软件开发的主要目标是以有效的方式,制造出满足project stakeholder需要的软件,而不是制造无关的文档,无关的用于管理的artifact,甚至无关的模型。任何一项活动(activity ),如果不符合这项原则,不能有助于目标实现的,都应该受到审核,甚至取消。 ◆轻装前进 你建立一个artifact,然后决定要保留它,随着时间的流逝,这些artifact都需要维护。如果你决定保留7个模型,不论何时,一旦有变化发生(新需求的提出,原需求的更新,团队接受了一种新方法,采纳了一项新技术...),你就需要考虑变化对这7个模型产生的影响并采取相应的措施。而如果你想要保留的仅是3个模型,很明显,你实现同样的改变要花费的功夫就少多了,你的灵活性就增强了,因为你是在轻装前进。类似的,你的模型越复杂,越详细,发生的改变极可能就越难实现(每个模型都更“沉重”了些,因此维护的负担也就大了)。每次你要决定保留一个模型时,你就要权衡模型载有的信息对团队有多大的好处(所以才需要加强团队之间,团队和project stakeholder之间的沟通)。千万不要小看权衡的严重性。一个人要想过沙漠,他一定会携带地图,帽子,质地优良的鞋子,水壶。如果他带了几百加仑的水,能够想象的到的所有求生工具,一大堆有关沙漠的书籍,他还能过得去沙漠吗?同样的道理,一个开发团队决定要开发并维护一份详细的需求文档,一组详细的分析模型,再加上一组详细的架构模型,以及一组详细的设计模型,那他们很快就会发现,他们大部分的时间不是花在写源代码上,而是花在了更新文档上。 ◆内容比表示更重要 一个模型有很多种的表示方法。例如,可以通过在一张纸上放置即时贴的方法来建立一个用户界面规格(基本/低精度原型)。它的表现方式可以是纸上或白板上的草图,可以是使用原型工具或编程工具建立和传统的原型,也可以是包括可视界面和文本描述的正式文档。有一点很有意思,一个模型并不一定就是文档。它们通常作为其它artifact的输入,例如源代码,但不必把它们处理为正式的文档,即使是使用CASE工具建立的复杂的图表,也是一样。要认识到一点,要利用建模的优点,而不要把精力花费在创建和维护文档上。 ◆
三人行必有我师 你不可能完全精通某项技术,你总是有机会学习新的知识,拓展知识领域。把握住这个机会,和他人一同工作,向他人学习,试试做事的新方式,思考什么该做,什么不该做。技术的变化非常的快,现有的技术(例如
Java )以难以置信的速度在改进,新的技术(例如
C# 和
.NET )也在有规律的产生。现存开发技术的改进相对会慢一些,但也在持续的改进中--计算机产业属于工业,我们已经掌握了其中的试验基本原理,但我们还在不断的研究,不断的实践,不断的改进我们对它的了解。我们工作在一个变化是家常便饭的产业中,我们必须通过训练、教育、思考、阅读、以及和他人合作,抓住每一个机会学习新的处事之道。 ◆了解你的模型 因为你要使用多种模型,你需要了解它们的优缺点,这样才能够有效的使用它们。 ◆了解你的工具 软件(例如作图工具、建模工具)有各种各样的特点。如果你打算使用一种建模工具,你就应当了解什么时候适合用它,什么时候不适合用它。 ◆局部调整 你的
软件开发方法 要能够反映你的环境,这个环境包括组织特征,project stakeholder的特征,项目自身的特征。有可能受其影响的问题包括:你使用的建模技术(也许你的用户坚持要看到一个细节的用户界面,而不是初始草图或基本原型);你使用的工具(可能你没有数字照相机的预算,或是你已经拥有某个CASE工具的license);你遵循的
软件过程 (你的组织采用XP的开发过程,或是RUP,或是自己的过程)。因此你会调整你的方法,这种调整可能是针对项目的,也可能是针对个人的。例如,有些开发人员倾向于使用某一类工具,有些则不用。有些人在编码上花大力气,基本不做建模,有些则宁可在建模上多投入一些时间。 ◆开放诚实的沟通 人们需要能够自由的提出建议,而且人们还应该能够感受到他们是自由的。建议可能是和模型有关的想法:也许是某些人提出某部分新的设计方法,或是某个需求的新的理解;建议还可能是一些坏消息,例如进度延误;或仅仅是简单的工作状况报告。开放诚实的沟通是人们能够更好的决策,因为作为决策基础的信息会更加准确。 ◆利用好人的直觉 有时你会感觉到有什么地方出问题了,或是感觉什么地方有不一致的情况,或是某些东西感觉不是很对。其实,这种感觉很有可能就是事实。随着你的软件开发的经验的增加,你的直觉也会变得更敏锐,你的直觉下意识之间告诉你的,很可能就是你工作的关键之处。如果你的直觉告诉你一项需求是没有意义的,那你就不用投入大量的精力和用户讨论这方面的问题了。如果你的直觉告诉你有部分的架构不能满足你的需要,那就需要建立一个快速技术原型来验证你的理论。如果你的直觉告诉设计方法A要比设计方法B好,而且并没有强有力的理由支持你选择某一个方法,那就尽管选择方法A。勇气的价值就已经告诉你,如果未来证实你的直觉是错的,你也有能力来挽救这种情况。你应该有这种自信,这很重要。
敏捷建模的实践
敏捷建模(AM)在AM原则的基础上定义了一组核心实践(practice)和补充实践,其中的某些实践已经是极限编程(XP)中采用了的,并在 Extreme Programming Explained一书中有详细的论述,和AM的原则一样,我们在描述这组实践时,将会注重于建模的过程,这样你可以从另外一个角度来观察这些已或XP采用的素材。 ◆Stakeholder的积极参与 我们对XP的现场客户(On-Site Customer)的概念做了一个扩充:开发人员需
要和用户保持现场的接触;现场的用户要有足够的权限和能力,提供目前建构中的系统相关的信息;及时、中肯的做出和需求相关的决策;并决定它们的优先级。AM把XP的“现场客户”实践扩展为“使project stakeholder积极参与项目”,这个project stakeholder的概念包括了直接用户、他们的经理、高级经理、操作人员、支持人员。这种参与包括:高级经理及时的资源安排决策,高级经理的对项目的公开和私下的支持,需求开发阶段操作人员和支持人员的积极参与,以及他们在各自领域的相关模型。 ◆正确使用artifact 每个artifact都有它们各自的适用之处。例如,一个UML的活动图(activity diagram)适合用于描述一个业务流程,反之,你
数据库 的静态结构,最好能够使用物理数据(physical data)或数据模型(persistence model)来表示。在很多时候,一张图表比源代码更能发挥作用,一图胜千言,同样,一个模型也比1K的源代码有用的多,前提是使用得当(这里借用了 Karl Wieger的Software Requirements中的词汇)。因为你在研究设计方案时,你可和同伴们和在白板上画一些图表来讨论,也可以自己坐下来开发一些代码样例,而前一种方法要有效的多。这意味着什么?你需要了解每一种artifact的长处和短处,当你有众多的模型可供选择的时候,要做到这一点可没有那么容易。 ◆集体所有制 只要有需要,所有人都可以使用、修改项目中的任何模型、任何artifact。 ◆测试性思维 当你在建立模型的时候,你就要不断的问自己,“我该如何测试它?”如果你没办法测试正在开发的软件,你根本就不应该开发它。在现代的各种软件过程中,测试和质保(quality assurance)活动都贯穿于整个
项目生命周期 ,一些过程更是提出了“在编写软件之前先编写测试”的概念(这是XP的一项实践:“测试优先”)。 ◆并行创建模型 由于每种模型都有其长处和短处,没有一个模型能够完全满足建模的需要。例如你在收集需求时,你需要开发一些基本用例或用户素材,一个基本用户界面原型,和一些业务规则。再结合实践切换到另外的Artifact,,敏捷建模者会发现在任何时候,同时进行多个模型的开发工作,要比单纯集中于一个模型要有效率的多。 ◆创建简单的内容 你应该尽可能的使你的模型(需求、分析、架构、设计)保持简单,但前提是能够满足你的project stakeholder的需要。这就意味着,除非有充分的理由,你不应该随便在模型上画蛇添足--如果你手头上没有
系统认证 的功能,你就不应该给你的模型增加这么一个功能。要有这样的勇气,一旦被要求添加这项功能,自己就能够马上做到。这和XP的实践“简单设计”的思想是一样的。 ◆简单地建模 当你考虑所有你能够使用的图表(UML图、
用户界面 图、数据模型等)时,你很快会发现,大部分时候你只需要这些图表符号的一部分。一个简单的模型能够展示你想要了解的主要功能,例如,一个类图,只要能够显示类的主要责任和类之间的关系就已经足够了。不错,编码的标准告诉你需要在模型中加入框架代码,比如所有的get和set操作,这没有错,但是这能提供多少价值呢?恐怕很少。 ◆公开展示模型 你应当公开的展示你的模型,模型的载体被称为“建模之墙”(modeling wall)或“奇迹之墙(wall of wonder)”。这种做法可以在你的团队之间、你和你的project stakeholder之间营造出开放诚实的沟通氛围,因为当前所有的模型对他们都是举手可得的,你没有向他们隐藏什么。你把你的模型贴到建模之墙上,所有的开发人员和project stakeholder都可以看建模之墙上的模型,建模之墙可能是客观存在的,也许是一块为你的架构图指定的白板,或是物理数据模型的一份打印输出,建模之墙也可能是虚拟的,例如一个存放扫描好的图片的internet网页。如果你想要多了解一些相关的资料,你可以看看Ellen Gottesdiener的Specifying Requirements With a Wall of Wonder。 ◆切换到另外的Artifact 当你在开发一个artifact(例如用例、CRC卡片、顺序图、甚至源码),你会发现你卡壳了,这时候你应当考虑暂时切换到另一个artifact。每一个artifact都有自己的长处和短处,每一个artifact都适合某一类型的工作。无论何时你发现你在某个artifact上卡壳了,没办法再继续了,这就表示你应该切换到另一个artifact上去。举个例子,如果你正在制作基本用例,但是在描述业务规则时遇到了困难,你就该试着把你的注意力转移到别的artifact上去,可能是基本用户界面原型、CRC模型,可能是业务规则、系统用例、或变化案例。切换到另一个artifact上去之后,你可能就立刻不再卡壳了,因为你能够在另一个artifact上继续工作。而且,通过改变你的视角,你往往会发现原先使你卡壳的原因。 ◆小增量建模 采用增量开发的方式,你可以把大的工作量分成能够发布的小块,每次的增量控制在几个星期或一两个月的时间内,促使你更快的把软件交付给你的用户,增加了你的敏捷性。 ◆和他人一起建模 当你有目的建模时你会发现,你建模可能是为了了解某事,可能是为了同他人交流你的想法,或是为了在你的项目中建立起共同的愿景。这是一个团体活动,一个需要大家有效的共同工作才能完成的活动。你发现你的开发团队必须共同协作,才能建立一组核心模型,这对你的项目是至关重要的。例如,为了建立系统的映像和架构,你需要和同组成员一起建立所有人都赞同的解决方案,同时还要尽可能的保持它的简单性。大多数时候,最好的方法是和另一些人讨论这个问题。 ◆用代码验证 模型是一种抽象,一种能够正确反映你正在构建的系统的某个方面的抽象。但它是否能运行呢?要知道结果,你就应该用代码来验证你的模型。你已经用一些HTML页面建立了接受付款地址信息的草图了吗?编码实现它,给你的用户展示最终的用户界面,并获取反馈。你已经做好了表示一个复杂业务规则逻辑的UML顺序图了吗?写出测试代码,业务代码,运行测试以保证你做的是对的。永远也别忘了用迭代的方法开发软件(这是大多数项目的标准做法),也别忘了建模只是众多任务中的一个。做一会儿建模、做一会儿编码、做一会儿测试(在其它的活动之中进行)。 ◆使用最简单的工具 大多数的模型都可以画在白板上,纸上,甚至纸巾的背面。如果你想要保存这些图标,你可以用数码相机把它们拍下来,或只是简单的把他们转录到纸上。这样做是因为大多数的图表都是可以扔掉的,它们只有在你画出模型并思考一个问题的时候才有价值,一旦这个问题被解决了它们就不再有意义了。这样,白板和标签往往成为你建模工具的最佳选择:使用画图工具来创建图表,给你重要的project stakeholder看。只有建模工具能够给我们的编程工作提供价值(例如代码自动生成)时才使用建模工具。你可以这样想:如果你正在创建简单的模型,这些模型都是可以抛弃的。你建模的目的就是为了理解,一旦你理解了问题,模型就没有存在的必要了,因此模型都是可以丢弃的,这样,你根本就不必要使用一个复杂的建模工具。 ◆使用建模标准 这项实践是从XP的编码标准改名而来,基本的概念是在一个软件项目中开发人员应该同意并遵守一套共同的建模标准。遵守共同的编码惯例能够产生价值:遵守你选择的编码指南能够写出干净的代码,易于理解,这要比不这么做产生出来的代码好得多。同样,遵守共同的建模标准也有类似的价值。目前可供选择的建模标准有很多,包括对象管理组织(OMG)制定的
统一建模语言 (UML),它给通用的
面向对象 模型定义了符号和语义。UML开了一个好头,但并不充分-就像你在Be Realistic About The UML中看到的,UML并没有囊括所有可能的的建模artifact。而且,在关于建立清楚可看的图表方面,它没有提供任何建模风格指南。那么,风格指南和标准之间的差别在何处呢。对源代码来说,一项标准可能是规定属性名必须以attributeName的格式,而风格指南可能实说在一个单元中的一段控制结构(一个if语句,一段循环)的代码缩进。对模型来说,一项标准可能是使用一个长方形对类建模,一项风格指南可能是图中子类需要放在父类的下方。 ◆逐渐应用模式 高效的建模者会学习通用的架构模式、设计模式和分析模式,并适当的把它们应用在模型
之中。然而,就像Martin Fowler在Is Design Dead中指出的那样,开发人员应当轻松的使用模式,逐渐的应用模式。这反映了简单的价值观。换言之,如果你猜测一个模式可能适用,你应当以这样的方式建模:先实现目前你需要的最小的范围,但你要为日后的重构留下伏笔。这样,你就以一种可能的
最简单的方式 实现了一个
羽翼丰满 的模式了。就是说,不要超出你的模型。举一个例子,在你的设计中,你发现有个地方适合使用GoF的Strategy模式,但这时候你只有两个算法要实现。最简单的方法莫过于把算法封装为单独的类,并建立操作,能够选择相应的算法,以及为算法传递相关的输入。这是Strategy模式的部分实现,但你埋下了伏笔,日后如有更多的算法要实现,你就可以重构你的设计。并没有必要因为Strategy模式需要,就建立所有的框架。这种方法使你能够轻松的使用模式。 ◆丢弃临时模型 你创建的大部分的模型都是临时使用的模型--设计草图,低精度原型,索引卡片,可能架构/设计方案等等--在它们完成了它们的目的之后就再不能提供更多的价值了。模型很快就变得无法和代码同步,这是正常的。你需要做出决定:如果“同步更新模型”的做法能够给你的项目增添价值的话,那就同步更新模型;或者,如果更新它们的投入将抵消它们能够提供的所有价值(即负收益),那就丢弃它们。 ◆合同模型要正式 在你的系统需要的信息资源为外部组织所控制的时候,例如数据库,旧有系统和信息服务,你就需要合同模型。一个合同模型需要双方都能同意,根据时间,根据需要相互改变。合同模型的例子有API的细节文档,存储形式描述,XML DTD或是描述共享数据库的物理数据模型。作为法律合同,合同模型通常都需要你投入重要资源来开发和维护,以确保它的正确、详细。你的目标是尽量使你系统的合同模型最少,这和XP的原则traveling light是一致的。注意你几乎总是需要电子工具来建立合同模型,因为这个模型是随时需要维护的。 ◆为交流建模 建模的次要原因是为了和团队之外的人交流或建立合同模型。因为有些模型是给团队之外的客户的,你需要投入时间,使用诸如文字处理器,画图工具包,甚至是那些“被广告吹得天花乱坠”的CASE工具来美化模型。 ◆为理解建模 建模的最重要的应用就是探索问题空间,以识别和分析系统的需求,或是比较和对照可能的设计选择方法,以识别可能满足需求的、最简单的解决方案。根据这项实践,你通产需要针对软件的某个方面建立小的、简单的图表,例如类的生命周期图,或屏幕顺序,这些图表通常在你完成目的(理解)之后就被丢弃。 ◆重用现有的资源 这是敏捷建模者能够利用的信息财富。例如,也许一些分析和设计模式适合应用到系统上去,也许你能够从现有的模型中获利,例如企业需求模型,业务过程模型,物理数据模型,甚至是描述你用户团体中的系统如何部署的模型。但是,尽管你常常搜索一些比较正确的模型,可事实是,在大多数组织中,这些模型要么就不存在,要么就已经过期了。 ◆非到万不得已不更新 你应当在你确实需要时才更新模型,就是说,当不更新模型造成的代价超出了更新模型所付出的代价的时候。使用这种方法,你会发现你更新模型的数量比以前少多了,因为事实就是,并不是那么完美的模型才能提供价值的。我家乡的街道图已经使用了5年了,5年来我自己街道并没有改变位置,因此这张地图对我来说还是有用的。不错,我可以买一张新地图,地图是每年出一次的,但为什么要这么麻烦呢?缺少一些街道并没有让我痛苦到不得不投资买一份新地图。简单的说,当地图还管用的时候,每年花钱买新地图是没有任何意义的。为了保持模型、文档和源代码之间的同步,已经浪费了太多太多的时间和金钱了,而同步是不太可能做到的。时间和金钱投资到新的软件上不是更好吗? 确实不错的主意 以下的实践虽然没有包括在AM中,但是可以做为AM的一份补充: ◆重构 这是一项编码实践。重构,就是通过小的变化,使你的代码支持新的功能,或使你的设计尽可能的简单。从AM的观点来看,这项实践可以保证你在编码时,你的设计干净、清楚。重构是XP的一个重要部分。 ◆测试优先设计 这是一项开发实践。在你开始编写你的业务代码之前,你要先考虑、编写你的测试案例。从AM的观点来看,这项实践强制要求你在写代码之前先通盘考虑你的设计,所以你不再需要细节设 计建模了。测试优先设计是XP的一个重要部分。
名词详解
AM是一种态度,而不是一个说明性的过程。AM是敏捷建模者们坚持的价值观、敏捷建模者们相信的原则、敏捷建模者们应用的实践组成的集合。AM描述了一种建模的风格。当它应用于敏捷的环境中时,能够提高开发的质量和速度,同时能够避免过度简化和不切实际的期望。AM可不是开发的“食谱”,如果你寻觅的是一些细节的指导,如建立UML顺序图或是画出用户界面流图,你可以看看在建模Artifacts中列出的许多建模书籍,我特别推荐我的书The Object Primer 2/e(尽管这有失公允)。 AM是对已有方法的补充,而不是一个完整的方法论。AM的主要焦点是在建模上,其次是文档。也就是说,AM技术在你的团队采用敏捷方法(例如eXtreme Programming,Dynamic Systems Development Method (DSDM),Crystal Clear)的基础上能够提高建模的效果。AM同样也可以用于那些传统过程(例如Unified Process),尽管这种过程较低的敏捷性会使得AM不会那么成功。 AM是一种有效的共同工作的方法,能够满足Project Stakeholder的需要。敏捷开发者们和Project Stakeholder进行团队协作,他们轮流在系统开发中扮演着直接、主动的角色。在“敏捷”的字典中没有“我”这个单词。 AM是有效的,而且也已开始有效。当你学习到更多的AM知识时,有件事对你来说可能不好接受,AM近乎无情的注重有效性。AM告诉你:要使你的 Project Stakeholder的投资最大化;当有清晰的目的以及需要解了受众的需要时要建立模型或文档;运用合适的工件来记录手头的情形;不论何时都尽可能创建简单的模型。 AM不是灵丹妙药。敏捷建模是改进众多专家软件开发成果的有效技术,充其量也就是这样了。它并不是什么了不得的灵丹妙药,能够解决你开发中的所有问题。如果你努力的工作;如果你专注其上;如果打心眼儿里接受它的价值观、它的原则、它的实践;你就可以改进你做为一个开发人员的效果。 AM是面向一般的开发人员的,但并不是要排斥有能力的人。AM的价值观、原则和实践都简单易懂,其中的很多内容,可能你都已经采用或期待多年了。应用AM技术并不是要你去练水上飘,但你需要有一些基本的软件开发技能。AM最难的就是它逼着你去学习更广泛的建模技术,这是个长期的、持续性的活动。学习建模在一开始可能很难,但你可以试着一次学习一样技术来完成你的学习。 AM并不是要反对文档。文档的创建和维护都会增大项目涉众的投资。敏捷文档尽可能的简单,尽可能的小,目的只集中在和目前开发的系统有直接关系的事情上,充分了解受众的需要。 AM也不是要反对CASE工具。敏捷建模者使用那些能够帮助开发人员提高效果,提升价值的工具。而且,他们还尽力使用那些能够胜任工作的最简单的工具。 何时是敏捷的? 要想了解AM,你需要了解模型和敏捷模型之间的区别。模型是一个抽象的概念,它描述了一个的问题的一个或多个方面,或是处理这个问题可能的解决方案。传统意义上,模型被认为是图表加上相应的文档。然而那不够直观的artifact,也可以被视为模型,例如CRC卡片集,单条或多条业务规则的文字描述,或是业务流程的一段结构化英文描述。一个敏捷模型就是一个刚刚足够好的模型。但是你怎么知道什么时候模型才是刚刚足够好呢?当敏捷模型显现出如下的特性时,它就是刚刚足够好的: 敏捷模型实现了它们的目的。有时你为沟通而建模,或许你需要把你工作的范围告诉高级经理;有时你为理解而建模,或许你需要确定一个设计策略,实现一组Java类。一个敏捷模型是否足够好,要看它是不是满足了创建它时的初衷。 敏捷模型是可理解的。敏捷模型要能为其预期听众所理解。使用用户能够理解的业务语言来描述需求模型,反之,技术架构模型则需要使用开发人员熟悉的技术术语。你所使用的建模符号会影响易懂性--如果你的用户不了解UML用例图中的符号的含义,那用例图对用户就没有任何价值。这样的话,要么使用另一种方法,要么教授用户学习建模技术。风格问题同样也会影响易懂性,例如避免交叉线。杂乱的图表比清晰的图表难懂。模型的细节程度(见下文),也会影响易懂性,因为相较一个不那么详细的模型来说,一个过于详细的模型要难于理解。简单(见下文)同样是影响易懂性的一个因素。 敏捷开发 敏捷模型是足够正确的。模型通常都不需要100%正确,只要足够正确就行了。举个例子,如果一张街道地图漏画了一条街道,或是它标示某条街道是通行的,但你发现它已经关闭维修了,那你会不会扔掉你的地图开始在城里飙车犯罪呢?不太可能。你会考虑更新你的地图,你可能会拿出笔来自己做修改或是去当地的商店买一张最新版的地图(你原来的那张过期了)。也许你还是会接受那张虽不完美仍可使用的地图,因为它对你来说已经足够好了。你还是可以用这张地图四处转转,因为它还是个正确的模型,标记出了大部分街道的位置。你在发现这张地图不正确的时候,你没有立刻扔掉它,原因是你根本不在乎它是否完美。类似的,当你在需求模型、数据模型中发现错误的时候,你也会选择更新或是接受--虽不完美但已经足够好了。有些项目成员能够容忍这种不正确而有些则不能:这取决于项目的特性,每个团队成员的特性,组织的特性。充分正确性既和模型的听众有关,也和你要处理的问题有关。 敏捷模型是足够一致的。一个敏捷模型并不需要和自己(或其它有用的artifact)保持完全的一致。如果一个用例在它的一个步骤中显式的调用了另一个用例,那么相应的用例图需要用UML的 <> 版型来标记这两个用例之间的关系。然而,你看了看图表,发现它们并没有这样做,天哪!用例和图之间不一致!危险!太危险了!红色警报!快逃命呀!等一下,你的用例模型是有不一致的地方,但也没到世界末日啊。是的,理想情况下,你的所有artifact最好是能够完全一致,但这通常是不可能的。当我开发一个简单的商用系统时,我通常都可以容忍部分的不一致。但有时我是不能容忍这种不一致的。最有力的佐证就是1999年 NASA发射火星太空探测器时采用了精密的
测量系统 。要树立一个观点,敏捷模型只要足够一致就行了,你通常不需要使用那么完美的模型。 关于正确性和一致性,很明显要考虑权衡问题。如果你要维护一个artifact(我们称之为“保管”),随着时间的流逝,你需要投入资源来更新它。否则它很会就会过期,对你就没用了。例如,我可以容忍一张地图标错了一两条街道,但是我绝对无法容忍一张地图中四分之三的街道都标错了。这就需要权衡了,进行足够的努力,保证artifact足够正确。过多不必要的努力反而会减缓项目的进度,而投入不足就没有办法保证artifact的有效性。 敏捷模型有足够的细节。一张路线图并不需要标记出每条街道上的每栋房子。那会有太多的细节,使得地图难以使用。然而,在修路的时候,我想施工人员一定会有这条街道的详细地图,包括每幢建筑、
下水道、电线盒等足够的细节,这样的地图才是有用的。但是这张地图并不用标记出每个院子和通向它们的路线。因为这样又太繁琐了。足够的细节和听众有关,也和他们使用模型的目的有关--司机需要的是显示道路的地图,施工人员需要的是显示土木工程细节的地图。 考虑一个架构模型,可能一组画在白板上的图表就足够了--项目的进行中再对它们更新,也许你需要用CASE 工具来生成一些图表,也许这些图表还需要有详细的文档,这依赖于环境。不同的项目有不同的需要。在每一个例子中,实际上你都是在开发、维护一个有足够的细节的架构模型,只是这个“足够的细节”的概念和环境有关。 敏捷模型能提供正面价值。对项目中的任一artifact,一个基本的要求是它们能够提供正面价值。一个架构模型给你的项目带来的价值是不是能够超过开发它、维护它(可选)的总成本?一个架构模型能够坚定你们团队为之努力的愿景,所以它当然是有价值的。但是,如果它的成本超过了这个价值,那就是说,它无法提供正面价值。投入100,000美元去开发一个详细的、重量级的文档化架构模型,而它的效用,只需一些画在白板上的图表就能够达到,这些图只需要花你 5,000美元,看看,这是多么轻率的做法。 敏捷模型要尽可能的简单。只要能够达到目的,你应当努力让你的模型尽可能保持简单。模型的详细程度会影响简单性,而所使用的符号范围也会影响简单性。例如,UML的类图就包括了无数的符号,包括对象约束语言 (Object Constraint Language OCL) ,但大多数的图使用符号的一部分就能够完成。所以你常常不需要使用所有的符号,你可以限制自己使用符号的一个子集,当然,这个子集是足够让你完成工作的。 因此呢,一个敏捷模型的定义就是一个实现它的目的,没有画蛇添足的模型;为你的预期听众所理解的模型;简单的模型;足够正确、足够一致、足够详细的模型;创建和维护它的投资能够给项目提供正面价值的模型。 一个普遍的哲学问题是源代码是不是一个模型,更重要的,它是不是一个敏捷模型。如果你是在我们这篇文章之外问我这个问题,我会回答说,是,源代码是一个模型,虽然是一个高度细节化的模型,因为它是软件的一个抽象。同时我还认为,优秀的代码是一个敏捷模型。但在这里,我还需要把两者区分开来,源代码和敏捷模型还是有区别的——敏捷模型帮助你得到源代码。
合格的敏捷建模者
敏捷建模者的个性 Alistair Cockburn指出:很多的方法学都定义了软件开发项目中开发人员所担任的角色,同时还定义个各个角色执行的任务,尽管入席,这些方法并没有定义这些角色最适合的人选。一个人要想成功的担任某个角色,他应当很好的适应它--虽然这并不需要人们掌握所有的技能,但人们必须要慢慢的熟悉这些技术。我的经验告诉我,要成为一个成功的敏捷建模者,下面的列出的个性是必要的: 第一点,也是最重要的一点,敏捷建模者总是积极的寻求协作,因为他们意识到他们不是万事通,他们需要不同的观点,这样才能做到最好。软件开发可不是游泳,单干是非常危险的。在敏捷的字典中没有“我”这个词。 敏捷建模者都有良好的沟通技巧--他们能够表达出他们想法,能够倾听,能够主动获取反馈,并且能够把需要的写出来。 敏捷建模者应当脚踏实地 他们的精力都集中在满足用户的需求上,他们不会在模型上画蛇添足,即便那双足是多么的好看。他们满足于提供可能的方案中最简单的一种,当然,前提是要能够完成工作。 敏捷建模者乐衷于研究问题,解决问题。
凡是都问个为什么
敏捷建模者看问题从不会至于表面,而是会
打破沙锅问到底 。他们从不会就想当然的认为一个产品或一项技术和它们的广告上说的那样,他们会自己试一试。 敏捷建模者都非常的谦逊,他们从不认为自己是个万事通,所以他们会在建立好模型之后,用代码来小心的证明模型的正确。 敏捷建模者应当愿意尝试新的方法,例如一项新的(或是已有的)建模技术。一般而言,他们也会接受敏捷建模开发技术,必要时,为了验证想法,他们愿意同传统的思想做斗争,例如在一个项目中减少文档数量。 要坚持不懈的遵循敏捷建模的实践。对你来说,你可能会在不经意间说,“加上这个功能吧!无伤大雅。”或是,“我比project stakeholder更了解。”在AM的道路上要想不偏离方向,是需要一定的纪律性的。
建模的误区
走出一般性的设计误区,迈向成功之途 无论你遵从的是重量级的方法,比如Enterprise Unified Process(EUP),还是轻量级的开发过程,如Extreme Programming(XP),建模在软件开发中都是不可或缺的。但不幸的是其中充斥着各种谬误与迷思。这来自于各个方面,有从理论家错误的研究、数十年来
信息技术领域内的文化沉积、软件工具开发商天花乱坠半的市场宣传以及象Object Management Group (OMG)和IEEE这类组织的标准。这个月,我要揭示建模中的误区,指出其相应的事实真相。 建模就等于是写文档 这很可能是其中最具破坏力的一条,因为开发人员可以此为借口而完全放弃建模。许多优秀的软件开发人员会说他们不想把时间浪费在这些“无用的“文档上。他们沉溺于编码之中,制造着一些脆弱而劣质的系统。另外,甚至于许多尽责的开发人员现在也认为建模是一件讨厌的事,而不愿去学习相应的建模技术。 事实分析:“模型”与“文档”这二者在概念上是
风马牛不相及 的—你可以拥有一个不是文档的模型和不是模型的文档。一幅设计图就是一个模型,而不论是被画在
餐巾纸的背面 ,或写在一块白板上,或在Class Responsibility Collaboration(CRC)卡片中,还是根据记录在报纸和便签纸上的流程图而生成的一个粗略的用户界面原型。虽然这些都不能说是文档,但他们却都是有价值的模型。 建模很象是作计划:作计划的价值在于计划编制的过程中,而非计划本身;价值体现在建模的活动中,而非模型本身。实际上,模型不是你系统中的一部分正式的文档,而且在完成它们的使命后可以被丢掉。你会发现值得保留的只有很少的模型,而且它一定是非常完美。 从开始阶段你可以考虑到所有的一切 这种说法流行于二十世纪七十年代到八十年代早期,现今的许多经理都是在那个时候学习的软件开发。对这一点的迷信会导致在前期投入可观的时间去对所有的一切建模以期把所有一切都弄正确,试图在编码开始前就“冻结”所有的需求(见误区四),以致于患上“分析期麻痹症” – 要等到模型非常完美之后才敢向前进。基于这个观点,项目组开发了大量的文档,而不是他们真正想要得到的—开发满足需要的软件。 事实分析:怎么才能走出这个误区呢?首先,你必须认识到你不能考虑到所有的细枝末节。第二,认识到编码员可能会对建模者的工作不以为然(这是可能的,事实上建模者所作的工作在实际价值中只占很少的部分),他们或许会说模型没有反应出真实的情况。第三,认识到不管你的最初所作的规格说明书有多好,但注定代码会很快地与之失去同步,即便是你自己建模自己编码。一个基本的道理就是代码永远只会和代码保持一致。第四,认识到迭代法(小规模地建模,编一些代码,做一些测试,可能还会做一个小的工作版本)是软件开发的准则。它是现代重量级的软件开发过程(如EUP),以及轻量级(如XP)的基本原理。 建模意味着需要一个重量级的软件开发过程 走入这个误区(经常与误区一有联系)的项目组常常是连建模都彻底地放弃了,应为这样的软件开发过程对他们来说太复杂太沉重了。这不亚于一场天灾。 事实分析:你可以用一种敏捷的方式取而代之。关于用简单的工具进行简单地建模的详细内容可参看Agile Modeling(AM)。而且,你可以丢弃你的模型当使命完之后,同样也可以很基本的方式进行建模(比如,从办公桌起来,来到白板前就开始构略草图)。只要你愿意,你就可以轻松地建模。 必须“冻结”需求 这个要求常常来自高级经理,他们确切地想知道他们从这个项目组能得到什么东西。这样的好处就是在开发周期的早期确定下需求,就可以确切地知道所要的是一个什么样的东西;缺点就是他们可能没有得到实际上所需要的。 事实分析:变化总会发生的。由于优先级的变化和逐渐对系统有了更进一步的理解,都会引起需求的变化。与冻结需求相反,估计项目成功的风险,尽量去接受变化而且相应地采取行动,就象XP所建议的一样。 设计是不可更改的 如同误区四,要求每一个开发人员必须严格遵从“设计“,导致开发人员为了符合“设计“而作了错误的事情或以错误的方式作正确的事情。或者是简单地忽略了设计,否定了所有设计可能带来的好处。冻结了设计,你就不能从在项目进程中所学到知识进一步获益。另外一个很大的趋势就是开发出大量的文档而不是实际的软件,使用面向文档的CASE工具而不是能给项目带来实际价值的面向应用的工具。 事实分析:事实上,设计会经常根据开发人员和
数据库管理员 的反馈进行修改,因为他们是最接近实际应用的人,通常他们对技术环境的理解要好于建模者。我们必须的面对这样一个事实:人无完人,他们所作的工作也不可能尽善尽美。难道您真的想将一个并不完善的设计固定下来而不再去修改其中的错误吗?另外,如果需求并没有被冻结,其实就意味着你不能冻结你的设计,因为任何需求的修改势必影响设计。对之,正确的态度是:只要你的代码还在改动,设计就没完。 必须使用CASE工具 建模常常被认为是一项复杂的工作,因此需要大量地使用CASE工具辅助进行。 事实分析:是的,建模可以是很复杂的。但你完全可以建立一个有效而简单的模型表述其中关键的信息,而不是将一些无关紧要的细节包括进来。 比如,我经常使用UML建立模型来表示类、它们的属性及一些关键的业务操作,但并不画出属性的存取操作(get和set),以及维护与其它类关系的框架代码,或者其他一些琐碎的实现细节。我通过建模寻找解决问题的方法,让我和我的同事能继续前进去实现这个模型。以这样灵活的方式,大多数情况下我并不需要一个CASE工具来支持建模工作,一块白板,或者一台数字相机足以。这样,我就不用花时间去评估CASE工具,不用去和工具供应商讨论许可证的问题,也免去了人员培训开销。CASE工具只有当它能体现最佳性价比时(相对你自己的情况而言),才值得购买。大多数情况下,我都能不用它而达到目的(完成建模)。我经常使用的工具有Together/J/) – 因为它能产生数目可观的Java框架代码;还有ERWin() -- 因为它能规划数据库。这两个工具真正地帮助我实现了软件开发的目的 – 制造满足用户要求的软件。但我绝大多数得建模工作仍然使用的是简单的工具,而不是CASE工具。 建模是在浪费时间 许多新手都这样认为,这主要是因为他们所接受的教育仅仅局限于如何编写代码,对于完整的开发流程鲜有接触。而且他们的经验也仅限于如何实现代码,就如初级程序员。他们放弃了提高效率和学习技能的机会,这些技能能够使他们很容易地适应不同的项目或组织。他们应该为此感到羞愧。 事实分析:在大多数情况下,在开始编码之前画一个草图、开发一个粗率的原型或者制作一些索引卡片都能提高你的生产效率。高效的开发者在编码之前都要进行建模工作。另外,建模是一种很好的在项目组成员与项目负责人之间沟通途径。你们在这个过程中探讨问题,从而对所要的是一个什么样的东西可以得到更好的理解,涉及到该项目中的每个成员也可得到对该项目有一个从分的了解。 数据模型(Data Model)就是一切 许多组织基于数据模型就蹒跚启动新的开发工作,也许正如你所在的组织:IT部门对于数据有非常严格的规定,控制着你的开发项目;或者你以前的数据库是一团糟,别无选择。 事实分析:数据模型是一个重要的但不是最重要的建模,它最好是建立在另外的模型之上。(参见“Extreme Modeling”,Thinking Objectively,Nov.2000)。这即使在象数据仓库这类面向数据的项目中也如此。如果没有很好的理解用户是如何使用该数据仓库的(在数据模型中没有表示出来),这些项目经常是以可悲的失败而告终。你可以使用的模型有很多 – 使用案例(use cases),业务规则(business rules),activity diagrams,类图(class diagrams),component diagrams,用户界面流程图(user interface flow diagrams)和CRC,等等。数据模型仅仅是其中的一种。每种模型都有其长处和短处,应该正确地使用。 所有的开发人员都知道如何建模 我们现在面临照这样一个严重的问题:许多不是开发人员的人,包括高级经理和用户,不知道软件是如何建成的。其结果,他们不能够区分开熟练的开发者和一般的程序员(当然也分不清高级程序员和一般程序员),他们想当然地认为所有的开发人员都具备从头到尾开发整个系统的技能。 事实分析:这肯定是不正确的。建模的技能,是只有当一个开发者通过学习它,并经过长期的实践才能够掌握。一些非常聪明的程序员常常相信自己无所不能,毕竟他们终究只是程序员。正因为这样的狂妄自大,他们承当的一些任务是他们根本就没有相应的技能去完成的。软件开发是如此的复杂,单单一个人是很难具备所有的技能去成功地进行开发,甚至也不可能去配置有一定复杂程度的系统。开发者应该有自知之明,明白他们自己的弱点,学无止境。通过互相取长补短,建模者可从程序员身上学到一项技术的具体细节,程序员也可从建模者那里学到有价值的设计和体系结构的技术。我个人认为所有的人,包括我自己,都是新手。
敏捷软件开发宣言
n 个体和交互 胜过 过程和工具 n 可以工作的软件 胜过 面面俱到的文档 n 客户合作 胜过 合同谈判 n 响应变化 胜过 遵循计划 虽然右项也有价值,但是我们认为左项具有更大的价值。
敏捷宣言遵循的原则
n 我们最优先要做的是通过尽早的、持续的交付有价值的软件来使客户满意。 n 即使到了开发的后期,也欢迎改变需求。敏捷过程利用变化来为客户创造竞争优势。 n 经常性地交付可以工作的软件,交付的间隔可以从几个星期到几个月,交付的时间间隔越短越好。 n 在整个项目开发期间,业务人员和开发人员必须天天都在一起工作。 n 围绕被激励起来的个体来构建项目。给他们提供所需的环境和支持,并且信任他们能够完成工作。 n 在团队内部,最具有效果并富有效率的传递信息的方法,就是面对面的交谈。 n 工作的软件是首要的进度度量标准。 n 敏捷过程提倡可持续的开发速度。责任人、开发者和用户应该能够保持一个长期的、恒定的开发速度。 n 不断地关注优秀的技能和好的设计会增强敏捷能力。 n 简单是最根本的。 n 最好的构架、需求和设计出自己组织的团队。 n 每隔一定时间,团队会在如何才能更有效地工作方面进行反省,然后相应地对自己的行为进行调整。 当软件开发需求的变化而变化时,软件设计会出现坏味道,当软件中出现下面任何一种气味时,表明软件正在腐化。 n 僵化性:很难对系统进行改动,因为每个改动都会迫使许多对系统其他部分的其它改动。 n 脆弱性:对系统的改动会导致系统中和改动的地方在概念上无关的许多地方出现问题。 n 牢固性:很难解开系统的纠结,使之成为一些可在其他系统中重用的组件。 n 粘滞性:做正确的事情比做错误的事情要困难。 n 不必要的复杂性:设计中包含有不具任何直接好处的基础结构。 n 不必要的重复性:设计中包含有重复的结构,而该重复的结构本可以使用单一的抽象进行统一。 n 晦涩性:很难阅读、理解。没有很好地表现出意图。 敏捷团队依靠变化来获取活力。团队几乎不进行预先设计,因此,不需要一个成熟的初始设计。他们更愿意保持设计尽可能的干净、简单,并使用许多单元测试和验收测试作为支援。这保持了设计的灵活性、易于理解性。团队利用这种灵活性,持续地改进设计,以便于每次迭代结束生成的系统都具有最适合于那次迭代中需求的设计。 为了改变上面软件设计中的腐化味,敏捷开发采取了以下面向对象的设计原则来加以避免,这些原则如下: n 单一职责原则(SRP) 就一个类而言,应该仅有一个引起它变化的原因。 n 开放-封闭原则(OCP) 软件实体应该是可以扩展的,但是不可修改。 n Liskov替换原则(LSP) 子类型必须能够替换掉它们的基类型。 n 依赖倒置原则(DIP) 抽象不应该依赖于细节。细节应该依赖于抽象。 n 接口隔离原则(ISP) 不应该强迫客户依赖于它们不用的方法。接口属于客户,不属于它所在的类层次结构。 n 重用发布等价原则(REP) 重用的粒度就是发布的粒度。 n 共同封闭原则(CCP) 包中的所有类对于同一类性质的变化应该是共同封闭的。一个变化若对一个包产生影响,则将对该包中的所有类产生影响,而对于其他的包不造成任何影响。 n
共同重用原则 (CRP) 一个包中的所有类应该是共同重用的。如果重用了包中的一个类,那么就要重用包中的所有类。 n 无环依赖原则(ADP) 在包的依赖关系图中不允许存在环。 n 稳定依赖原则(SDP) 朝着稳定的方向进行依赖。 n 稳定抽象原则(SAP) 包的抽象程度应该和其稳定程度一致。 上述中的包的概念是:包可以用作包容一组类的容器,通过把类组织成包,我们可以在更高层次的抽象上来理解设计,我们也可以通过包来管理软件的开发和发布。目的就是根据一些原则对
应用程序中的类进行划分,然后把那些划分后的类分配到包中。 敏捷设计是一个过程,不是一个事件。它是一个持续的应用原则、模式以及实践来改进软件的结构和可读性的过程。它致力于保持系统设计在任何时间都尽可能得简单、干净和富有表现力。