4色图

在图论的基本理论中,有加权顶点的概念。顶点具有的与之相关的数,称为权(weight);该顶点称为加权顶点。



  这里我们做个扩充,引入着色顶点的概念:顶点具有的与之相关的颜色,称为着色(color);该顶点称为着色顶点。
  用UML为问题及解决方案建模的时候,有时UML图会比较复杂,不容易读懂。下面以两个例子来说明如何运用着色顶点的方法,提高UML图的易读性。



建模的本质是抽象,抽象的目的是把握重点,以使结构清晰化。如果我们画的UML图太复杂,那就应当想一想,我们是不是犯了“为建模而建模”的毛病,忘记了原本的目的呢?



  使UML图清晰易读的方法有很多,为图元着色就是其中一种,并且它是令人愉快的。仔细想来,上面两例都是用颜色为图元分类,这种分类带来了两条令人兴奋的好处:其一,为原图附加了一层大局信息,这些大局信息会被读者最先注意到,并为进一步理解图的细节打下基础;其二,由于大局信息是通过着色的方式提供的,并没有引入任何新的图元,所以图的复杂性并没有增加。



三、着色顶点的UML应用——UML彩色建模方法介绍
  如果问我,看完《人月神话》这本书,给我印象最深的一个词是什么,我会毫不犹豫地回答:概念完整性。为了达到概念完整性,领域建模(domain modeling)是非常重要的一个环节。可喜的是,领域建模已经越来越被业界所重视,也有不少好书和好的方法浮出水面。本节介绍Peter Coad大师的著作《Java Modeling In Color With UML: Enterprise Components and Process》中讲述的彩色建模方法——一种领域建模方面的优秀技术。



  Peter Coad认为,领域模型主要由四种元素组成,它们分别是:瞬间事件(MomentInterval)、角色(Role)、人-物-地点(PartyPlaceThing)、描述(Description)。彩色建模技术的目的是“为模型增加一层‘视觉可监测的’信息”,具体而言,它定义了四种颜色分布标识上述四种领域元素。



粉红:代表“瞬间事件”。在模型中,瞬间事件往往封装了我们最感兴趣的方法(method),这些方法和系统将来的功能有直接的联系,它们可以说是模型的灵魂。它们也是最容易变的,因此选用了最活跃的粉红色代表。
黄色:代表“角色”。瞬间事件的发生,往往会牵涉到多个角色,角色具体由“人-物-地点”来扮演。角色意味着在特定场景下的责任,它们也是比较容易变化的,但比起瞬间事件还是要稳定些,所以用比较活泼的黄色代表。
绿色:代表“人-物-地点”。业务领域不同,会牵涉到不同的人、物、地点。它们都比较稳定,用安静的绿色表示。
蓝色:代表“描述”。最后为人、物、地点引入更抽象一级的描述元素,这些描述元素可以被多个不同的“人-物-地点”所共享。比如Date就是描述元素,人可以有生日,汽车可以有生产日期,等等。描述是最为稳定的一类模型元素,用稳定得几乎忧郁的蓝色代表。

Edward R. Tufte在其经典著作《Envisioning Information》中指出,颜色在信息设计中的基本作用有四:



分类
度量
模仿
装饰
  彩色建模方法充分利用了颜色的分类和度量功能(当然经过颜色装饰的模型也比原来更赏心悦目):它不仅利用了四种颜色来为图元分类,而且粉红、黄、绿、蓝四种颜色分别代表不同等级的“易变程度”,具有度量意义。



 由于篇幅所限,以上只是对彩色建模方法的简单介绍,感兴趣的朋友还是找书来看看吧。



四、着色边
  在上文中,我们对经典图论进行了小小扩充,并且体会了这种扩充的应用价值。接下来,我们对边的概念进行类似的扩充——着色边。



 边具有的与之相关的颜色,称为着色(color);该边称为着色边。



五、着色边的UML应用——标识良性依赖与恶性依赖
  合理处理依赖关系,是“拥抱变化”的关键所在。在《拥抱变化:敏捷设计从理论到实践》(《程序员》2004年第11期)一文中,笔者阐述了敏捷设计的理解基础:良性依赖原则。不会“在实际中”造成危害的依赖关系,都是良性依赖;依赖的“理论危害”不一定成为“实际危害”,反之亦然。这就是良性依赖原则。



  那么,如果能使用着色边的方法,将依赖的良、恶性可视化,对软件设计人员无疑是大有裨益的。我们规定:



良性依赖用绿色表示;
恶性依赖用红色表示。
  例如,敏捷设计大师们提倡的“通过重构得到设计模式”,在着色边方法的帮助下,变得易于理解,并且极具可操作性;其步骤如下:



  1. 使用最简单的设计,完成当前的功能。此时,往往是类之间的直接调用,但由于功能需求也简单,所以类之间的依赖关系也往往是良性依赖。



  2. 当需求有所变化或增加时,首先考察原先的设计是否可以直接支持新需求;如果可以通过直接增强某个类来达到目的,但是原先的良性依赖也随之变成了恶性依赖,那就应当否定这种方案,而去做第3步的重构。



  3. 通过重构改变原先的设计,使新的设计为支持新需求做好准备,且保证依赖关系都是良性依赖。



  4. 在新设计的基础上,增加新功能的支持。这时你往往会发现,哇,设计模式出现了。



  下面举例。为了突出着色边方法给“通过重构得到设计模式”带来的可操作性,我们再来看看(上)篇的那个例子:需求跟踪矩阵工具,其最初的需求是支持项目以专有格式保存,后来,又要求能够导出成HTML格式的网页。下面的四幅设计类图都运用了着色边方法,它们概括了整个设计变化的过程:




  1. 最初的设计。符合敏捷设计的简单性原则。

  2. 考察老设计在新需求下的情况。CProjectSaver要支持多种保存策略,违反了单一职责原则。

  3. 重构得到的新设计。很好的设计,但对最初的需求而言,却是过度设计(over-engineering)。

  4. 在新设计之上添加新功能。就是策略(strategy)模式呀。
    通过上面的例子可以看出,着色边方法在某种程度上,将设计的依据“可视化”了,因此为设计人员带来了方便。


Category architect