企业架构设计实战3 怎样进行系统逻辑架构?
Posted 禅与计算机程序设计艺术
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了企业架构设计实战3 怎样进行系统逻辑架构?相关的知识,希望对你有一定的参考价值。
有没有一种方法在大产品和小团队之间的缺口上架起一座桥梁呢?答案是肯定的,有!那就是架构。架构最重要的一点,就是它能把难以处理的大问题分解成便于管理的小问题。
-- Eric Brechner,《代码之道》
“一流” 是每个程序设计人员向往并为之奋斗却又无法具体说出的、难以达到的境界,一流的软件非常简明。它灵活而清晰,能通过创造性的机制解决复杂的问题,这些机制语义丰富,可应用于其他可能完全无关的问题,一流意味着寻求恰当的抽象,意味着通过新的途径合理利用有限的资源。
-- Grady Booch,《面向对象项目的解决方案》
划分子系统、定义接口......,这些典型工作都是属于逻辑架构设计的范畴。
接下来,我们主要说说5视图方法中逻辑架构视图的设计:
先从划分子系统的3种必用手段讲起。
随后,纠正“我的接口我做主”这种错误认识,代之以“协作决定接口”的正确理解。
而且,接下来将解析逻辑架构设计的整体思维套路,解决架构师郁闷已久的“多视图方法只讲做什么、不讲怎么做”的问题。
最后,总结逻辑架构设计的10条经验要点。
划分子系统的3种必用策略
架构师最缺的不是理论,也不是技术,而是位于理论和技术之间的“实践策略”和“实践套路”。
就划分子系统这个架构师必须做的工作而言,其实实践策略可以归纳为3种:
分层的细化
分区的引入
机制的提取
分层(Layer
)的细化
分层是最常用的架构模式:在架构设计初期,100%的系统都可以用分层架构,就算随着设计的深入而采用了其他架构模式也未必和分层架构矛盾。
于是,架构师在划分子系统时常受到初期分层方式的影响--实际上,很多架构师最熟悉、最自然的划分子系统的方式就是:分层的细化。
3层架构或4层架构的“倩影”经常出现在投标时,或者市场彩页中,于是有人戏称之为“市场架构”。
的确,直接用3层架构或4层架构来支持团队的并行开发是远远不够的。所以,“分层的细化”是划分子系统的必用策略之一,架构师们不要忘记。
分区(Partition
)的引入
序幕才刚刚拉开,划分子系统的工作还远远没有结束。
迭代式开发挺盛行,但所有真正意义上的迭代开发,都必须解决这样一个“困扰”:如果架构设计中只有“层”的概念,以“深度优先”的方式完成一个个具体功能就不可能的!
所以,工程师们就经常遇到这样的烦恼
例如《代码之道》一书中就论及了这一点:
为了得到客户经常性的反馈,快速迭代有个基本前提:开发应该是“深度优先”,而不是“广度优先”。
广度优先极端情况下意味着每一个功能进行定义,然后对每个功能进行设计,接着对每个功能进行编码,最后才能对所有功能一起测试。而深度优先极端情况下意味着每个功能完整的进行定义、设计、编码和测试,而只有当这个功能完成之后,你才能做下一个功能。当然,两个极端都是不好的,但深度优先要好的多。对于大部分团队来说,应该做一个高级广度设计,然后马上转到深度优先的底层设计和实现上去。
为了支持迭代开发,逻辑架构设计中必须(注意是必须)引入分区。分区是一种单元,它位于某个层的内部,其粒度比层 要小。一旦架构师针对每个层进行了分区设计,“深度优先”式的迭代开发就非常自然。
架构是迭代开发的基础。架构师若要在“支持迭代”方面不辱使命,必须注重“分区的引入”--这也是划分子系统的必用策略之一。
机制的提取
Grady Booch在他的著作中指出:
机制才是设计的灵魂所在......否则我们就不得不面对一群无法相互协作的对象,它们相互推搡着做自己的事情而不关心其他对象。
机制之于设计是如此的重要。那么,什么是机制呢?
那“机制”的定义是:软件系统中的机制,是指预先定义好的、能够完成预期目标的、基于抽象角色的协作方式。机制不仅仅包含协作关系,同时也包含了协作流程。
对于面向对象方法而言,“协作”可以定义为“多个对象为完成某种目标而进行的交互”,而“协作”和“机制”的区别可以概况为:
基于接口(和抽象类)的协作是机制,基于具体类的协作则算不上机制。
对于编程实现而言,在没有提取机制的情况下,机制是一种隐式的重复代码--虽然语句直接比较并不相同,但是很多语句只是引用的变量不同,更重要的是大段的语句块结构完全相同。如果提取了机制,它在编程层面体现为“基于抽象角色(OO中就是接口)编程的那部分程序”。
对于逻辑架构设计而言,机制是一种特殊的子系统--架构师在划分子系统时不要忘记这一点。最容易理解的子系统,是通过“直接组装”粒度更小的单元来是吸纳软件的”最终功能“。在实现不同的最终功能时,可以重用同一个机制,避免重复进行繁琐的”组装“工作。例如,网络管理软件中拓扑显示和告警通知都可利用消息机制。
回顾”三维思维“
至此,我们讨论了划分子系统的3种手段:分层的细化、分区的引入、机制的提取。通过这3种手段的综合运用,就可更理性、更专业的展开逻辑架构的设计。
如何通过关注点分离来达到“系统中的一部分发生了改变,不会影响其他部分”的目标呢?
首先,可以通过职责划分来分离关注点,面向对象的关键所在,就是职责的识别和分配。每个功能的完成,都是通过一系列职责组成的“协作链条”完成的;当不同职责被合理分离之后,为了实现新的功能只需构造新的“协作链条”,而需求变更也往往只会影响到少数职责的定义和实现......
其次,可以利用软件系统各部分的通用性不同进行关注点分离。不同的通用程度意味着变化的可能性不同,将通用性不同的部分分离有利于通用部分的重用,也便于专用部分修改......
另外,还可以先考虑大粒度的子系统,而暂时忽略子系统是如何通过更小粒度的模块和类组成的......
总结了上述的架构设计关注点分离原理。可以说,根据职责分离关注点,根据通用性分离关注点,根据不同粒度级别分离关注点是三种位于不同“维度“的思维方式,所以在实际工作中必须综合运用这些手段。
于是,不难理解分层的细化、分区的引入、机制的提取这3种划分子系统手段之间的关系:它们处在思维的3个维度上。
首先,分层和机制位于不同的维度:职责维度和通用维度。
另外,是否引入分区,设计所“覆盖”的Scope
是完全相同的。原因是层的粒度较大,而是层内部引入的分区的粒度更小,便于组合出一个个功能(支持迭代开发)。这是第三维:粒度。
看来,分层的细化、分区的引入、机制的提取这3个手段不是相互替代的关系,而是相辅相成的关系。
探究:划分子系统的4个重要原则
重要的内容就值得多讲几遍。
下面的分层的细化、分区的引入、机制的提取这3种策略背后的4个通用设计原则:
职责不同的单元规划不同子系统
通用性不同的单元划归不同子系统
需要不同开发技能的单元划归不同子系统
兼顾工作量的相对均衡,进一步切分到多个原则综合作用的结果
接口设计的事实与缪误
世界是复杂的,很多东西难以直接获取。
例如直接最强幸福,是永远追不到的(《乐在工作》一书中说幸福是副产品)。
殊不知,合理的接口设计也不是“直接”得到的。
由于面向对象非常强调“自治”,许多人不知不觉的形成了一种错误认知:面向对象推崇“我的接口我做主”。很遗憾,“自治”正确。但“我的接口我做主”这个推断是错误的。
软件世界中本无模块。1968年,Dijkstra发表了第1篇关于层次结构的论文《The Structure of THE-multiprogramming System》(原文PDF)。1972年,Parnas发表论文《On the Criteria To Be Used in Decomposing Systems into Modules》论及了模块化和信息隐藏的话题......这是架构学科开始萌芽的标志。
那么,为什么要对软件进行模块化设计呢?是为了解决复杂性更高的大问题。于是,我们突然领悟:对问题进行分解,分别解决小问题,其实这只是手段。每个架构师应该牢记:
“分”是手段,“合”是目的。不能“合”在一起支持更高层次功能的模块,又有何用呢?
因此,我们必须把模块放在协作的上下文之中进行考虑。架构师设计接口时,要考虑的重点是“为了实现软件系统的一系列功能,这个软件单元要和其他哪些单元如何协作”,总结成一句话就是:
协作决定接口
相反,直接设计接口,是很多“面向接口的”架构依然拙劣的原因之一。类似“我的接口我做主”的观点是错误的,每个模块或子系统(甚至类)无视协作需要而进行的接口定义很难顺畅的被其他模块或子系统使用。
逻辑架构设计的10条经验要点
我们归纳了逻辑架构设计的10条经验要点,其中,如何划分子系统,如何定义接口,如何运用质疑驱动的事物套路等已经介绍,其他几点再继续简单介绍。
划分子系统:分层的细化
划分子系统:分区的引入
划分子系统:机制的提取
接口的定义:协作决定接口
选用序列图:杜绝协作图
包-接口图:从结构到行为的桥
灰盒包图:描述关键子系统
循序渐进的螺旋思维
设计模型:包内结构
设计模式:包间协作
逻辑架构设计中设计模式应用
设计模式是Class Level
的设计,它如何用于架构一级的设计呢?
基本观点是:让Class
和SubSystem
搭上关系。不难理解,设计模式用于架构设计主要有两种方式:
明确子系统内的结构
明确包间的协作关系
如何做呢?答案是灰盒包图。下图中说明了灰盒包图的意义,它打破了“子系统黑盒”,关系子系统中的关键类,从而可以更到位的说明子系统之间的协作关系,并成为设计模式应用的基础。
例如,我们对比一下黑盒包图和灰盒包图(背景是项目关系系统甘特图展示的问题)。后者明确了子系统之间的交互机制,还显式的说明了Adpter
设计模式的应用--这就是灰盒包图的价值。
逻辑架构设计的建模支持
工欲善其事,必先利其器。在实践中必须选择最适合的模型,甚至做一些改造工作让UML
更适合特定的实践目的。例如:灰盒包图就是一种“专门说明重要子系统设计”的UML
图的应用。
另外,包-接口图是类图的一种特定形式,它包含“包(package
)”和“接口(interface
)”两种主要元素。这种图的作用很专一:说明包之间的协作需要哪些接口。逻辑架构设计中,包-接口图是从结构设计到行为设计的思维桥梁。
最后,“逻辑架构设计的整体思维套路”时已亮明了观点:逻辑架构的设计,应该使结构设计和行为设计相分离。这样才利于更有效的思维。不信?请看下面所示的“设计图”(这是很多设计者习惯的思维方式)。思维清楚吗?
思维混乱的原因:将结构和行为过多的混在了一起。
推荐用时序图(它较为专注于行为设计)辅助逻辑架构设计,尽量不要用协作图(虽然在UML 1.4
中,它和时序图等价,但从形式上它的“结构气”太重)。
【更多阅读】
Redis 作者 Antirez 讲如何实现分布式锁?Redis 实现分布式锁天然的缺陷分析&Redis分布式锁的正确使用姿势!
B-树(B-Tree)与二叉搜索树(BST):讲讲数据库和文件系统背后的原理(读写比较大块数据的存储系统数据结构与算法原理)
《人月神话》8 胸有成竹(Chaptor 8.Calling the Shot -The Mythical Man-Month)
《人月神话》(The Mythical Man-Month)5画蛇添足(The Second-System Effect)
《人月神话》(The Mythical Man-Month)4概念一致性:专制、民主和系统设计(System Design)
Redis 作者 Antirez 讲如何实现分布式锁?Redis 实现分布式锁天然的缺陷分析&Redis分布式锁的正确使用姿势!
十年技术进阶路:让我明白了三件要事。关于如何做好技术 Team Leader?如何提升管理业务技术水平?(10000字长文)
……
以上是关于企业架构设计实战3 怎样进行系统逻辑架构?的主要内容,如果未能解决你的问题,请参考以下文章
企业架构设计实战0 企业数字化转型和升级:架构设计方法与实践
5.业务架构·应用架构·数据架构实战 --- 业务驱动的数据架构设计