分析模型是采用分析类,在系统架构和框架的约束下,来实现用例场景的产物。
分析模型是高层次的系统视图,在语义上,分析类不代表最终的实现。它是计算机系统元素的高层抽象。 笔者认为分析模型正是OO设计的核心,而设计类只是OO的实现手段。
分析模型是MVC模式的经典应用。对比分析类的名称,MVC模式,读者应该能够发现分析类在OO和商业目标中精妙的对应关系:人,事,物,规则--actor,boundary,engity,control。这就是为什么笔者说分析模型是OO设计的核心。
(让关心OO之路列的朋友们久等了,今天正式开始推出之路系列的第二部,OO系统设计师之路。在第一部OO系统分析员之路中,我们始于什么是用例,结束于需求规格说明书。我们还记得在第一部中,最后的结果是系统用例。系统用例规定了系统范围,通过用例场景,规定了系统蓝图,让我们知道了系统将如何实现业务用例中规定的业务。这些工作,是由系统分析员来完成的。到这里为止,我们还不知道如何让计算机来执行这些业务。大家都知道,在需求过程结束后,即将进行的是分析设计过程,这是系统设计师的职责。OO之路第二部正是针对系统设计师的,笔者将试图在接下来的文章里,说明如何做系统设计,要运用哪些工具,产生哪些结果,以及如何来验证我们的设计是否正确。
这是设计师之路的第一篇,笔者要讨论的是分析模型。我们经常会听到分析模型这个词,但真正懂得,或者用过分析模型的人却少之又少。下面笔者将写下一段对话,这段对话是笔者在招聘设计师的过程中与许多应聘者对话的场景模拟。90%以上的应聘者都不能很好的回答这些问题。读者也可以试着回答,看看你对用UML进行OO系统设计有多深的了解。 对话场景:
-在需求过程结束以后,接下来你会做什么? -分析设计
-你的设计依据是什么? -需求结果,用例模型
-你是如何设计的?设计的结果是什么?
-设计类图,确定类的方法和属性,会用时序图来表达类之间的交互。还有会应用设计模式来增强系统的扩展性和复用能力。
-那你是如何确定出类来的呢?比如针对一个特定的需求,为什么你决定用三个类而不是五个类?类方法又是如何确定的呢?为什么设计七个方法而不是十个方法?
-短暂沉默后:经验啊,从我多个项目的设计经验和实际情况来看,用这几个类和这些方法完全可以满足业务要求,并且是经过优化的,是最好的方案。
-那么你如何能够保证,或者,你用什么来证明,你的设计能够满足需求呢?除了经验之外,你能用什么方法来证明呢?
-沉默之后:我有很丰富的设计经验,我的设计是经过深思熟虑的。设计会经过评审,讨论和充分的沟通,后面还有测试,不满足需求时会再进行修改和补充的。
-刚才你也说了,需求结束后你将进行分析设计的工作。你能说说分析和设计的差别吗?分析做什么,设计做什么?
-更长时间的沉默:分析和设计是同一个过程,分析是想的过程,设计是把想的内容用类表达出来。 -我们知道在UML里有分析模型和设计模型,如果分析和设计是同一个过程,你能说说分析模型和设计模型的区别吗? -沉默...
是的,的确是这样。很多人分不清分析和设计不同的目标,没有使用过或根本不知道分析模型。更多的人无法回答他的设计如何能够被证明是满足需求的,那些类在他们看来,都是凭经验,如同精灵一般从脑子里蹦出来的。他们很自信自己的经验和设计能力,津津乐道于一个又一个设计模式,他们认为,如此优秀的设计怎么会不满足需求呢?证明?很奇怪的问题,我设计的目的就是为了满足需求,不满足需求的设计我会不断改进啊,最终它一定是满足的啊。
可惜这并没有回答我的问题,我问的是如何证明,而不是是不是满足。即使设计师拥有丰富的经验和超强的设计能力,设计结果的确满足了需求,并且很优秀,但那只是结果而不是过程,那是个人英雄的胜利,而不是软件过程的胜利。
事实上,这一切问题,都只是因为设计师们遗忘了很重要的一个过程,分析模型。那么什么是分析模型呢?为什么分析模型能够解决这些问题呢?
RUP里对分析模型和分析类的定义是:分析类用于获取系统中主要的“职责簇”。它们代表系统的原型类,是系统必须处理的主要抽象概念的“第一个关口”。如果期望获得系统的“高级”概念 性简述,则可对分析类本身进行维护。分析类还可产生系统设计的主要抽象:系统的设计类和子系统。
如果你对上面的定义感到迷惑不解(RUP的定义一向如此),下面是笔者在实际工作中对分析模型的理解和应用经验,或许可以帮助读者理清头绪。
分析模型是采用分析类,在系统架构和框架的约束下,来实现用例场景的产物。在OO之路的第一部里,我们说用例和用例场景规定了业务范围和要求,如果分析类完全实现了这些用例和场景,我们就能肯定的说分析类已经满足了需求。
分析类是什么呢?一般来说,分析类有:
再加上实现用例场景需要的actor类,共四种。这些分析类将在后面的文章里详细讨论,读者现在只需要记住它们的样子。
分析模型是高层次的系统视图,在语义上,分析类不代表最终的实现。它是计算机系统元素的高层抽象。上述的四个分析类可以完全模拟计算机的执行过程。分析类具化以后产生真正的实现类,即所谓的设计类,也就是大多数设计师所说的类图。
笔者认为分析模型正是OO设计的核心,而设计类只是OO的实现手段。还记得上一部第一篇中笔者提到的复用的三个层次吗?组件级的复用实际上是通过分析模型表达的,而设计模型中的复用,只是利用了OO语言的特性,来实现复用的要求。
分析模型是MVC模式的经典应用。从分析类的名称就可以看出来。笔者在上一部第四篇中讲到的一个观点:“商业系统无论多复杂,无论什么行业,其本质无非是人,事,物, 规则。人是一切的中心,人做事,做事产生物,规则限制人事物。人驱动系统,事体现过程,物记录结果,规则则是控制。无论OO也好,UML也好,复杂的表面下其实只是一个简单的规则,系统分析员弄明白有什么人,什么人做什么事,什么事产生什么物,中间有什么规则,再把人,事,物之间的关系定义出来,商业建模也就基本完成了。”。根据这一段话,再对比分析类的名称,想想MVC模式,读者应该能够发现分析类在OO和商业目标中精妙的对应关系:人,事,物,规则--actor,boundary,engity,control。这就是为什么笔者说分析模型是OO设计的核心。
问题是为什么要用分析模型呢?现在绝大多数系统的产生过程并没有用分析模型,不也照样运行?而且在RUP里,分析模型也只是一个Optional的过程,并非强制过程啊?
的确如此,这可能也是为什么大多数设计师并不用分析模型的原因。但是,同时,文章前面的对话场景中的问题也产生了。有读者要问,你说分析模型完全实现用例场景因此可以证明设计满足需求,那么我用设计类来实现用例场景,不也可以同样证明? 那分析模型又有何用呢?
而这正是分析模型要存在的原因。刚才,笔者说了,分析类不代表实现,它具化成设计类以后才是实现。分析类是系统元素的高层抽象。有经验的设计师,特别是那些擅长于使用设计模式的设计师们都知道,OO系统要保持扩展能力,复用性要好,要把变更影响控制在小范围内,就要应用高层次的抽象,用高层次的抽象接口来表达系统行为,而把具体实现delay到子类,配置文档,甚至运行期去。所有的设计模式,不论采取了怎样的技巧,均是为了这些目的。分析模型对系统设计来说也同样延续了这样的思想,用四个高度抽象的分析类来表达系统行为,而把实现delay到设计类中去。这些抽象透明于实现方式,也透明于实现语言,它表达的核心观点是系统架构,业务实现模式和规范,需求可回溯的验证。
比如,我们用一个实体分析类表达了某个业务实体,在分析模型中我们定义了所有针对该实体的交互和存取操作,对分析模型这个层次的抽象来说已经完整表达了计算机系统对业务需求的模拟实现。但其实这时并未真正的实现这个业务需求,一直到具化成设计类后,根据开发语言特性,框架,规范等等要求,这个实体分析类可以被具化成一个或多个SDO,POJO,EntityBean,可以用Hibernate,可以用 Webshpere BO,也可以用Weblogic XMLbean...等等。完全可以根据实际需要来确定实现方式和语言,因此实现得以delay,这就带来了OO扩展和复用的潜在能力。并且这时设计师已经不用担心具化出的设计类是否会脱离需求,它们已经在分析模型层次被验证,而能专心考虑系统实现所要求的那些特性。在后续的文章里笔者还会更详细的讨论这些问题,这里只是举一个例子。
为什么要用分析类而不是设计类去验证需求呢?这是由于抽象层次更高,分析类比设计类验证需求的工作量以及可能的变化都要少很多。比如针对登录要求,如果用分析类来表达,我们只需要向登录control类发一条登录请求就OK了。而设计类由于与实现方式相关,并且已经具化到了实现,所以根据安全验证方式不同,LDAP,CA,SSL,或应用服务器不同,登录方式和方法都不同,并且可能是很多个步骤,例如getUser(),getRole(),getGroup(),register()...你愿意用这么多说明才能表示已经验证了一个简单的登录要求吗?慢着,如果更换了安全模式呢?更换了应用服务器呢?这在现实情况中也很常见,对分析类来说,由于抽象层次高于实现方式,因此继续有效,而设计类却必须更改。这就是为什么要用分析模型来验证需求的原因之一。
较真的读者或许会说,安全模式变了,就算不为了验证需求,设计类本身也不得不改,这看起来没什么必然因果关系啊?考虑一下,在一个项目组里,当一份设计文档被share到负责各个摸块的开发小组时,各小组对该文档都形成了一个共同的认识。如果这个认识是基于分析模型而不是设计模型的,当安全模式改变,对负责安全模块的开发小组来说,他可以改变他负责的设计类而无需通知其它小组。因为从分析模型的层次来看,一切都没有改变。 这与大家熟悉的设计类中更换了类实现而保持接口不变的道理是一样的,只要接口不变就无须通知任何人。 而如果这个共识是基于设计模型的,一点小的改变都需要通知到各个小组,因为各小组的认识是基于类名,方法名的,改动了,能不通知他人么?从OO角度来说,这就是松藕合和紧藕合的差别。