1.6 架构与设计:保持定义简单
一个让架构师永远抓狂的问题便是如何让架构和设计作为独立而又关联的活动。关于两者区别的争论没完没了,我们不想趟这摊浑水。出于以下原因,我们将在本书中力求坚定地站在架构这一边。
首先,为了做出有效的决策,架构师必须理解底层架构原则。例如,选用同步通信还是异步通信会带来一系列利弊,架构师在一头扎进实现细节之前需要仔细考虑。在Fundamentals of Software Architecture一书中,作者定义了软件架构的第二定理:为什么做比如何做更重要。虽然架构师最终还是要知道如何实现方案,但他们必须首先知道为什么这个选择优于另外一个。
其次,把重点放在架构的概念上,避免深入这些概念的无数种实现方式。架构师可以用各种方式实现异步通信,但我们关注的是为什么架构师应该选择异步通信,这里对具体实现细节不做探讨。
最后,如果开始深入书中各种选择的实现中去,这将会是我们写过的最长的书。关注架构原则可以让其保持尽可能通用。
在本书中,我们使用如下定义。
服务
通俗地说,服务是可以独立部署和执行的功能的内聚集合。我们讨论的大多数关于服务的概念都应用于分布式架构,尤其是微服务架构。
在第2章定义的术语中,服务是架构量子的一部分,也进一步包含服务和其他量子之间的静态耦合和动态耦合等定义。
耦合
如果一个工件(包括服务)中的变化需要另外一个工件也做出改变才能保持功能正常,则两者是耦合的。
组件
应用程序的架构组成要素,执行某种业务或者基础设施功能,通常可以通过包结构(Java)、命名空间(C#)或源代码文件在目录结构中的物理分组来声明。例如,组件Order History可以通过在命名空间app.business.order.history里的一系列类文件来实现。
同步通信
如果调用者必须得到响应才能进行下一步,那么这两个工件是同步通信的。
异步通信
如果调用者不需要等待响应就可以继续运行,那么这两个工件是异步通信的。或者,当请求完成时,接收者可以通过单独的通道通知调用者。
集中编排
如果工作流包含一个主要职责是编排工作流中的服务,那么这个工作流是集中编排的。
分散协作
如果没有编排者,则这个工作流是分散协作的。更准确地说,工作流中的服务共同分担了协调职责。
原子性
如果工作流中的所有部件一直保持统一的状态,则称这个工作流是原子性的。反过来,它们也可以保持不同程度的最终一致性,这在第6章中会详细阐述。
契约
我们广泛使用契约来定义两个软件部分之间的接口,它可能包括方法调用和函数调用、集成架构远程调用、依赖项等。两个软件有交集的任何地方,契约就会出现。
软件架构天生就是抽象的。我们不可能知道读者面对的是什么问题,各种平台、技术、商业软件和其他令人头晕目眩的可能性组成了独一无二的情况,我们只知道没有完全相似的情况。我们讲到了很多抽象概念,但必须让它们落地,通过一些实现细节把它们具象化。为此,我们需要一个具体的问题来阐述架构概念——Sysops Squad。