C_Meng PSNA

Never wait for the storm to pass, just dance in the rain.

0%

软件架构及常用的架构风格

前言:本来只想做一个“什么是微服务架构”,后来发现有许多基础的知识如果不做会很难看懂,因此把软件架构和常用的架构风格也一并讲了。大佬们的请直接移步第三部分。

软件架构

软件架构的定义

要理解微服务架构,首先要理解什么是软件架构。

计算机系统的软件架构是构建这个系统所需要的一组结构,包括软件元素、它们之间的关系以及两者的属性。————卡耐基梅隆大学 Len Bass

这句话,本质上就是在讲:应用程序的架构是将软件分解为元素(element),这些元素之间的关系(relation),以及这些元素自有的属性(property)。

软件架构的意义

应用程序有两个层面的需求。第一类是功能性需求,这些需求决定一个应用程序做什么。这些通常都包含在用例(use case)或者用户故事(user story)中。应用的架构其实跟这些功能性需求没什么关系。功能性需求可以通过任意的架构来实现,甚至是非常糟糕的大泥球架构。

架构的重要性在于,它帮助应用程序满足了第二类需求:非功能性需求。我们把这类需求也称之为质量属性需求,或者简称为“能力”。这些非功能性需求决定一个应用程序在运行时的质量,比如可扩展性和可靠性。它们也决定了开发阶段的质量,包括可维护性、可测试性、可扩展性和可部署性。为应用程序所选择的架构将决定这些质量属性。

也可以从以下几点来讲软件架构的意义:

  • 它促进了劳动和知识的分工。它使具有特定专业知识的人们(或多个团队)能够就应用程序高效地协同工作。
  • 它定义了软件元素的交互方式。
  • 将软件分解成元素以及定义这些元素之间的关系,决定了软件的能力。

软件架构的4+1视图模型

每个视图的目的如下:

逻辑视图:开发人员创建的软件元素。在面向对象的语言中,这些元素是类和包。它们之间的关系是类和包之间的关系,包括继承、关联和依赖。

实现视图:构建编译系统的输出。此视图由表示打包代码的模块和组件组成,组件是由一个或多个模块组成的可执行或可部署单元。在Java中,模块是JAR文件,组件通常是WAR文件或可执行JAR文件。它们之间的关系包括模块之间的依赖关系以及组件和模块之间的组合关系。

进程视图:运行时的组件。每个元素都是一个进程,进程之间的关系代表进程间通信。

部署视图:进程如何映射到机器。此视图中的元素由(物理或虚拟)计算机和进程组成。机器之间的关系代表网络。该视图还描述了进程和机器之间的关系。

除了这四个视图以外,4+1中的+1是指场景,它负责把视图串联在一起。每个场景负责描述在一个视图中的多个架构元素如何协作,以完成一个请求。例如,在逻辑视图中的场景,展现了类是如何协作的。同样,在进程视图中的场景,展现了进程是如何协作的。

常用的架构风格

架构风格的定义如下:

架构风格根据结构组织模式定义了一系列此类系统。更具体地说,架构风格确定可以在该风格的实例中使用的组件和连接器的词汇表,以及关于如何组合它们的一组约束。————David Garlan and Mary Shaw

特定的架构风格提供了有限的元素(组件)和关系(连接器),你可以从中定义应用程序架构的视图。应用程序通常使用多种架构风格的组合。例如,单体架构可以通过不同的风格通的实现视图构造为单个(可执行与可部署)组件的架构样式。微服务架构将应用程序构造为一组松散耦合的服务,也可以通过不同的风格进行表示。

分层式架构风格

架构的典型例子是分层架构。分层架构将软件元素按“层”的方式组织。每个层都有明确定义的职责。分层架构还限制了层之间的依赖关系。每一层只能依赖于紧邻其下方的层(如果严格分层)或其下面的任何层。

可以将分层架构应用于前面讨论的四个视图中的任何一个。流行的三层架构是应用于逻辑视图的分层架构。它将应用程序的类组织到以下层中:

  • 表现层:包含实现用户界面或外部API的代码。
  • 业务逻辑层:包含业务逻辑。
  • 数据持久化层:实现与数据库交互的逻辑。

分层架构是架构风格的一个很好的例子,但它确实有一些明显的弊端:

  • 单个表现层:它无法展现应用程序可能不仅仅由单个系统调用的事实。
  • 单一数据持久化层:它无法展现应用程序可能与多个数据库进行交互的事实。
  • 将业务逻辑层定义为依赖于数据持久化层:理论上,这样的依赖性会妨碍你在没有数据库的情况下测试业务逻辑。

此外,分层架构错误地表示了精心设计的应用程序中的依赖关系。业务逻辑通常定义数据访问方法的接口或接口库。数据持久化层则定义了实现存储库接口的DAO类。换句话说,依赖关系与分层架构所描述的相反。

六边形架构风格

六边形架构是分层架构风格的替代品。如图所示,六边形架构风格选择以业务逻辑为中心的方式组织逻辑视图。应用程序具有一个或多个入站适配器,而不是表示层,它通过调用业务逻辑来处理来自外部的请求。同样,应用程序具有一个或多个出站适配器,而不是数据持久化层,这些出站适配器由业务逻辑调用并调用外部应用程序。此架构的一个关键特性和优点是业务逻辑不依赖于适配器。相反,各种适配器都依赖业务逻辑。

业务逻辑具有一个或多个端口(port)。端口定义了一组操作,关于业务逻辑如何与外部交互。例如,在Java中,端口通常是Java接口。有两种端口:入站和出站端口。入站端口是业务逻辑公开的API,它使外部应用程序可以调用它。入站端口的一个实例是服务接口,它定义服务的公共方法。出站端口是业务逻辑调用外部系统的方式。出站端口的一个实例是存储库接口,它定义数据访问操作的集合。

业务逻辑的周围是适配器。与端口一样,有两种类型的适配器:入站和出站。入站适配器通过调用入站端口来处理来自外部世界的请求。入站适配器的一个实例是Spring MVC Controller,它实现一组REST接口(endpoint)或一组Web页面。另一个实例是订阅消息的消息代理客户端。多个入站适配器可以调用相同的入站端口。

出站适配器实现出站端口,并通过调用外部应用程序或服务处理来自业务逻辑的请求。出站适配器的一个实例是实现访问数据库的操作的数据访问对象(DAO)类。另一个实例是调用远程服务的代理类。出站适配器也可以发布事件。

六边形架构风格的一个重要好处是它将业务逻辑与适配器中包含的表示层和数据访问层的逻辑分离开来。业务逻辑不依赖于表示层逻辑或数据访问层逻辑。

由于这种分离,单独测试业务逻辑要容易得多。另一个好处是它更准确地反映了现代应用程序的架构。可以通过多个适配器调用业务逻辑,每个适配器实现特定的API或用户界面。业务逻辑还可以调用多个适配器,每个适配器调用不同的外部系统。六边形架构是描述微服务架构中每个服务的架构的好方法。

reference:
https://mp.weixin.qq.com/s/r9eKHhEKWo5TovFN87HtPw