系统架构重构

下面,我们针对系统架构和设计中的“坏味”(注:“坏味”是 Martin Fowler 的一个著
名概念),分别总结出的一些“重构模式”,看看这些模式是如何把这些设计“坏味”去掉的。
1,实体重新命名
问题:进行架构和设计时所界定出来的系统组成元素(子系统、构件、模块等)名称使
用混乱,不能很好地表达该系统元素的用途或语义,使系统结构难以理解。事实上,一个架
构发展的历程中,命名的逐渐混乱,是促使架构老化的重要原因。
解决方案:
在系统全局范围内,使用事先定义的命名规则和编码规则。
尽量使用容易使项目相关人员理解的含有明显语义的名称来给系统元素命名。
改变系统元素名称时,需要考虑该元素与其他系统元素间的引用关系,使元素名称
包含引用的概念。
举例:
重构时,我们可以使用适当的名称来表达两个构件或服务间的关系,如下图所示。
2,转移重复元素
问题:系统架构和设计中,同样的功能或系统元素屡次出现在很多其他系统元素中。这
样会降低系统的可理解性,并使这些相同功能的代码散布在整个系统设计当中,无论从设计
或编码的角度上,都无疑增加了理解和维护的复杂性。
解决方案:根据面向对象的“封装性”原则,一些共用的系统元素可以考虑封装起来,
这样方便系统其他部分对其的重用。同时,这样的架构和设计将使系统结构描述更加简捷直
接。我们需要做的事情是:
识别这些散布在系统结构当中的公共功能或公共任务。
汇总有哪些系统元素会利用这些公共部分。
尝试将这些共用部分从各个系统元素中转移到一个封装起来的系统元素中。
也就是说,我们可以使用一个新的构件来封装共享的功能,并移除原先那些构件中相同
的设计逻辑;取而代之的是以调用的方式来满足各个构件的功能引用。
3, 利用抽象的层次结构
问题:架构重构期间,我们会发现有些设计单元所实现的功能非常相近。这些重复出现
的相似设计单元以及后继的相似功能的代码,会严重干扰系统架构一些概念的一致性,从而
降低了架构描述的简捷和可读性。进一步可能会导致系统调用时需要和各种对象变种进行紧
耦合,从而形成难以应对的设计结构。
解决方案:
为了保持系统架构和设计中相似概念的一致性,应该考虑使用数据抽象的方式来使对象
之间形成自然的层次结构关系。这里需要注意 Barbar Liskov 著名的 LSP(Liskov Substitution
Principle,替换原则),这个原则的原始表述是:使用指针或引用基类的函数,必须使应用的
时候不需要知道它的派生类的对象。一般的处理方法如下:
利用 LSP 为指导原则,引入一个“通用抽象”来封装那些相似通用的功能。
定义一个以“通用抽象”为基础的层次结构。
将其他具体变种的架构设计单元,按照层次结构依次进行衍生。
举例:在.NET 架构中,每个控件都需要存在一个集合,用以记录下一层控件的引用。
按照 LSP 原则,可以组成以组合为特征的抽象层次结构,以便衍生其他特定的具体元素,如
下图所示。
4,以适配(Adaption)方式替代中介方式(Mediation)
问题:
架构重构期间,我们会发现一些过分使用集中式设计的情况。当对等系统实体之间的交
互顺序比较复杂的时候,适当地使用一些中介协调器(Mediator)不失为一种好的选择。但
是,这样集中管理的架构方式,对系统的可扩展能力、可修改能力有着明显的抑制作用。因
为每增加一个新的系统实体,我们就必须修改一系列的中介协调器(Mediator),这明显非常
不利于系统的维护。
解决方案:
为了替代集中管理的中介方式系统设计,可以采用如下办法:
在系统架构中增加一个“系统集成层”,系统实体(例如:构件或服务)完全是以
插件的方式集成在这个“集成层”中。
将这些对等实体的调用逻辑转移到该集成层之外的其他系统代码位置当中,系统通
过“系统集成层”来调用相应的构件或服务。
举例:将中介方式的架构设计转换为适配器方式,明显增强了系统的可扩展能力,如下
图所示。
5,合并子系统
问题:
架构重构时,我们经常会见到一个系统内的各个子系统之间存在着紧耦合关系。根据高
内聚低耦合的原则,一个系统中的各个子系统之间,在架构时应该尽量保持相对的松耦合关
系;同时,一个子系统内的各个构件之间可以保持紧耦合关系。如果子系统间的耦合关系太
高,对系统整体架构而言,系统进行维护和修改的代价就会非常高,并且重用一个子系统也
会变得非常困难。这完全是由于紧耦合造成了子系统间复杂关系的结果。
解决方案:
一个大规模系统中存在一些子系统,这些子系统间或多或少存在着相互耦合的关系。两
个子系统间的这种紧耦合关系,其实就意味着这两者是为了同样的功能目的而协作。这时可
以考虑将这两个子系统进行合并。
举例:与其将紧耦合分成两个子系统,倒不如将其合并。这符合“子系统间松耦合,子
系统内紧耦合”的设计原则。
6,强化层间调用
问题:
如果我们重构系统,经常会发现出现跨层进行层间调用的现象。这种设计的出现,完全
打破了 Layer 架构风格的优势,很容易造成架构的混乱。
解决方案:
目前系统架构经常会采用 Layer 的架构风格,这样分层的结构非常适于系统功能的切分,
使系统结构清晰,从而方便了未来的维护。当出现越层调用的情况,需要重新构建层间关系,
使系统保持严格逐层调用的架构风范。
注意:解决越层调用并不是一件非常容易的事,有时甚至需要进行商业逻辑重构才能解
决。
7,以消息通信替代远程方法调用
问题:
重构系统时,经常会发现大量使用远程方法调用(RPC,Remote Procedure Call)方式进
行通信,这无疑是一种最常见的通信实现方式。即便是在前端应用层可能需要的是一个异步
的通信方式,但是后端通信层的实现往往还是利用 RPC 同步方式进行实现。
然而,在一个分布式系统中,如果存在基于事件的异步通信需要,最佳的通信机制还是
采用 Message 形式的中间件方式。
解决方案:
分布式系统中异步通信方式是一种非常有利的通信机制。系统通信方式从同步机制向真
正的异步方式进行转变,可以采用渐进的办法来重构:对现有系统中仍旧需要同步通信方式
的,保留这种架构方式。同时,在系统架构中增加一个“消息中间件层”,把允许异步消息
传输的通信转向这个消息中间件层。
举例:两种通行方式并存的局面,会随着后续功能的修改和新功能的加入,逐渐修改为
依赖于“消息中间件层”的异步通信方式。
8,以缓存方式优化资源利用
问题:
重构系统时,经常会发现系统性能存在着严重的问题。进一步分析就会发现,系统性能
的瓶颈正是因为大量的系统实体对一个共享资源进行频繁存取所致。因为资源每次存取都会
经过资源创建、分配等一系列非常消耗性能的动作。如果提高了资源存取的效率,系统性能
就能够明显得到改善。这在一些实时系统的设计方面有着极为重要的意义。
解决方案:
系统中往往有很多共享的资源,在资源访问方面尽量优化,是克服系统性能问题的一个
重要手段。利用 Caching 来缓存利用率较高的资源,同时定义一个适当的资源分配原则来使
系统各个实体能够共享该缓存的资源。对于实时系统,采用基于内存的所谓“内存数据库”
是一个比较广泛采用的方法。
举例:在子系统当中,有意识地将访问频繁的资源暂时存放在访问速度较高的缓存 Cache
中,从而避免了不停地进行资源创建这种消耗系统性能的动作。我们可以来看看三种数据访
问形式,并比较它们的优缺点。
9,避免构件接口的膨胀
问题:
现实中,一个软件应用,经常会出现利用接口这样的抽象方式,来尽可能地使该接口的
功能抽象满足各种各样的应用要求。一个经历了数年维护的系统,随着新功能的增加,系统
构件的接口也会随之变化,这就导致了构件接口的膨胀。
试图满足各种要求的接口设计,会导致系统的可用性、可维护性、可管理性明显降低。
最严重的情况是,这样膨胀的接口可能会导致系统代码的混乱。
解决方案:
我们必须承认这样一个事实,那就是构件的接口(Interface)是会膨胀的。可以考虑引
入一个接口的层次结构关系,再提供一个公共的接口导航方式,以便客户端代码可以在一个
层次结构的接口关系中寻找相应的功能实现。
举例:将一个膨胀的构件接口重构为层次化的结构,并提供寻找具体功能实现的导航机
制,如下图所示。
10,保持架构和设计的对称
问题:
在初步设计的系统中,我们经常能够看到有些子系统的消息处理机制是使用“观察者设
计模式”,将消息与消息处理进行衔接。但是有的子系统却又使用 Hard Code 的方式,大量地
使用判断代码将消息与消息处理以编码的方式捆绑在一起。有些构件设计只照顾了资源的获
取,而在构件任务结束后没有释放资源。这些都是现实中我们经常能够看到的所谓“不对称”
的架构和设计方式。
结构匀称的系统,是指在系统全局范围内,在各个子系统、构件层面,尽量利用相同的
架构概念和设计手段来解决那些相似的问题。这样的匀称,对维护人员理解系统结构非常重
要。反之,一个系统如果使用了不对称的架构和设计,往往会造成系统概念的混乱,从而使
后续维护非常困难。
解决方案:
如果系统架构是以对称的方式来匀称地组织系统内结构和关系,在系统维护期间,将非
常有利于问题的识别和修改工作,其方法为:
系统重构期间,首先需要识别系统中那些重要的战略和战术层面的设计抉择。
将这些设计抉择背景相似的汇总为一类。然后对相同类型的设计抉择统一考虑使用
相同的架构原理或设计手段。
举例:将相似背景的设计抉择点汇总,并采用相同的 Observer 机制来进行事件的分发和
处理。可能是一种更加对称的方法。
软件重构是架构的一个优化过程,也是一个敏感而且风险比较大的过程,所以必须遵循
小步前进、一个时间只解决一个问题的原则,逐步的使架构得到优化。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值