第13章 逻辑架构
有没有一种方法在大产品和小团队之间的缺口上架起一座桥梁呢?答案是肯定的,有!那就是架构。架构最重要的一点,就是它能把难以处理的大问题分解成便于管理的小问题。
--Eric Brechner,《代码之道》
一流是每个程序设计人员向往并为之奋斗却又无法具体说出的、难以达到的境界。一流的软件非常简明。它灵活而清晰,能通过创造性的机制解决复杂的问题,这些机制语义丰富,可应用于其他可能完全无关的问题。一流意味着寻求恰当的抽象,意味着通过新的途径合理利用有限的资源。
-- Grady Booch,《面向对象项目的解决方案》
划分子系统、定义接口……,这些典型工作都属于逻辑架构设计的范畴。
本章阐释ADMEMS 5视图方法中逻辑架构视图的设计:
先从划分子系统的3种必用手段讲起;
随后,纠正"我的接口我做主"这种错误认识,代之以"协作决定接口"的正确理解;
而且,本章将解析逻辑架构设计的整体思维套路,解决一线架构师郁闷已久的"多视图方法只讲做什么、不讲怎么做"的问题;
最后,总结逻辑架构设计的10条经验要点。
13.1 划分子系统的3种必用策略
一线架构师最缺的不是理论,也不是技术,而是位于理论和技术之间的"实践策略"和"实践套路"。
就划分子系统这个架构师必做的工作而言,其实践策略可归纳为3种:
分层的细化。
分区的引入。
机制的提取。
13.1.1 分层(Layer)的细化
分层是最常用的架构模式,而笔者进一步认为:在架构设计初期,100%的系统都可以用分层架构,就算随着设计的深入而采用了其他架构模式也未必和分层架构矛盾。
于是,架构师在划分子系统时常受到初期分层方式的影响--实际上,很多一线架构师最熟知、最自然的划分子系统的方式就是:分层的细化。
例如,图13-1说明了基于3层架构进行"分层细化"的一种方式。
3层架构或4层架构的"倩影"经常出现在投标时,或者市场彩页中,于是有人戏称之为"市场架构"。的确,直接用3层架构或4层架构来支持团队的并行开发是远远不够的。所以,"分层的细化"是划分子系统的必用策略之一,架构师们不要忘记
--------------------------------------------------------------------------------------------
13.1.2 分区(Partition)的引入
序幕才刚刚拉开,划分子系统的工作还远远没有结束。
迭代式开发挺盛行,但所有真正意义上的迭代开发,都必须解决这样一个"困扰":如果架构设计中只有"层"的概念,以"深度优先"的方式完成一个个具体功能就是不可能的!如图13-2所示,就是一线程序员们经常遇到的烦恼。
例如《代码之道》一书中就论及了这一点:
为了得到客户经常性的反馈,快速迭代有个基本前提:开发应该"深度优先",而不是"广度优先"。
广度优先极端情况下意味着对每一个功能进行定义,然后对每个功能进行设计,接着对每个功能进行编码,最后才对所有功能一起进行测试。而深度优先极端情况下意味着对每个功能完整地进行定义、设计、编码和测试,而只有当这个功能完成了之后,你才能做下一个功能。当然,两个极端都是不好的,但深度优先要好得多。对于大部分团队来说,应该做一个高级的广度设计,然后马上转到深度优先的底层设计和实现上去。
为了支持迭代开发,逻辑架构设计中必须(注意是必须)引入分区。分区是一种单元,它位于某个层的内部,其粒度比层要小。一旦架构师针对每个层进行了分区设计,"深度优先"式的迭代开发就非常自然,图13-3说明了这一点。
架构是迭代开发的基础。架构师若要在"支持迭代"方面不辱使命,必须注重"分区的引入"--这也是划分子系统的必用策略之一。
-----------------------------------------------------------------------------------------------------------
13.1.3 机制的提取
Grady Booch在他的著作中指出:
机制才是设计的灵魂所在……否则我们就将不得不面对一群无法相互协作的对象,它们相互推搡着做自己的事情而毫不关心其他对象。
机制之于设计是如此地重要。那么,什么是机制呢?
本书为"机制"下的定义是:软件系统中的机制,是指预先定义好的、能够完成预期目标的、基于抽象角色的协作方式。机制不仅包含了协作关系,同时也包含了协作流程。
对于面向对象方法而言,"协作"可以被定义为"多个对象为完成某种目标而进行的交互",而"协作"和"机制"的区别可以概括为:
基于接口(和抽象类)的协作是机制,基于具体类的协作则算不上机制。
图13-4与图13-5显示了协作与机制的不同。
对于编程实现而言,在没有提取机制的情况下,机制是一种隐式的重复代码--虽然语句直接比较并不相同,但是很多语句只是引用的变量不同,更重要的是大段的语句块结构完全相同。如果提取了机制,它在编程层面体现为"基于抽象角色(OO中就是接口)编程的那部分程序"。
对于逻辑架构设计而言,机制是一种特殊的子系统--架构师在划分子系统时不要遗忘这点。最容易理解的子系统,是通过"直接组装"粒度更小的单元来实现软件"最终功能"的子系统;相比之下,作为子系统的机制并不能"直接实现"软件的"最终功能"。在实现不同的最终功能时,可以重用同一个机制,避免重复进行繁琐的"组装"工作。例如,如图13-6所示,网络管理软件中拓扑显示和告警通知都可利用消息机制。