技术开发 频道

体系结构的历险

    图 3 — 对于向用户借出图书馆书籍的设计 #2

    

    讨论

    图 2 和图 3 说明了两种可能的完成借书给某一个用户这一需求所做的面向对象的设计。两种设计都具有三个相同的对象:LibrarySystem、LibraryUser(代表借书用户的对象)和 LibraryBookCopy (代表书籍本身的对象)。两种方案的差别在于责任在对象之间的分布方式和对象之间的合作本质。

    ** 在设计 #1,LibrarySystem 负责借书给用户。LibrarySystem 通过询问 LibraryUser 和 LibraryBookCopy,确信上面列出的条件都被满足了,然后 LibrarySystem 告诉 LibraryBookCopy 它目前正在被借阅,同时告诉 LibraryUser 它正在借这本书。

    ** 在设计 #2,LibrarySystem 仅负责把借书给用户的责任委托给 LibraryBookCopy 对象 — LibraryBookCopy 有效地把自己借出。为了做到这一点,LibraryBookCopy 对象首先确定条件 3 是被满足的,接着告诉 LibraryUser 来借它。LibraryUser 对象负责确认条件 1 和条件 2 是被满足的,然后告诉自己正在借书。控制权返回给 LibraryBookCopy,LibraryBookCopy 告诉自己目前正在被借阅。

    两个设计在功能上都是相同的:它们都要检查所有三个条件是否被满足,然后确定 LibraryUser 知道它正在借阅 LibraryBookCopy,LibraryBookCopy 知道它正被 LibraryUser 借阅。它们的不同之处在于它们的结构。软件的体系结构处理的是系统的结构而不是其功能。

    体系结构选择

    如果两个设计在功能上相同,应该选择哪个? 这个表格总结了两个设计之间的差别

    


    表中的开始三个条目描述了两个方法的不同的本质。功能定位和合作本质都是技术差别:它们说明了责任怎样在对象之间分布,以及对象之间为了应付整个责任是怎么进行通信的。设计理念就是推理风格,它引导作出技术的决定。这对于一致的体系结构起着很重要的作用,因为设计的决定并不是在真空中做出的(“我怎么考虑它?”“我怎么实现它?”)而是在一个有支持作用的上下文中(“体系结构把这样的事物描述成什么样?”和“类似这样的事物在这里是怎样实现的?”)做出的。这就是“体系结构视点”的概念。

    最后的四个条目都是说明了两种设计在它们的非功能特性方面的差别。规模和性能是可以衡量的差别。因为两个系统做了相同的事情,所以复杂程度是一样的,但是它们在不同的方面表现其复杂性。考虑两种类型的变化:添加新的服务(就像允许用户在一个特定的日期预定项目)和添加新类可以被借出的事物(就像 CD 或录像带)。对于每个设计来说,实现这些变化是不同的。设计 #1 能更好的适应第一种变化,因为所有的对于预定的规则被加到了 LibrarySystem ,一个新的 Reservation 对象是简单和被动的。设计 #2 将有一个更复杂和主动的 Reservation 对象,在 LibraryUser 和 LibraryBookCopy 之间有更复杂的交互。对于第二种变化,设计 #2 比设计 #1 进行得更好,因为一个 CD 负责其自身的借出,所以任何差异或增加的需满足的条件(例如对用户的租借收费)被隐藏在 loanTo: 消息的后面 — 没有其他对象需要改变。在设计 #1 中实现这个变化需要一个新的 CD 对象和在 LibrarySystem 中添加新代码。

    所以,在规模、性能和复杂本质方面的差异说明了设计风格的选择直接影响了系统的非功能特性。这是体系结构的选择。大多数人通常把“体系结构”和系统设计最上层的大规模功能块联系在一起,但是关于功能定位和通信本质的相同问题却必须在系统设计的各层被提出。体系结构是与结构和功能分布相关的,不是直接和功能有关的:在许多功能相同的设计中,选择出最符合用户需求的设计。

0
相关文章