软件工程第六课
L6_CS335_Arch_Design
什么是软件系统架构? (What is Software System Architecture?)
“一个系统的软件架构是为了对系统进行推理所需的一组结构,这组结构包含了软件元素、它们之间的关系以及两者都具备的属性。”
-- Bass, L. Clements, P. and Kazman, R. 《软件架构实践》(Software architecture in practice), 第3版, 2013.
“一个系统的架构是该系统在其环境中的一组基本概念或属性,体现在其元素、关系以及其设计和演化原则之中。”
-- Rozanski, N. and Woods, E., 《软件系统架构:使用视点和视角与利益相关者协作》(Software systems architecture: working with stakeholders using viewpoints and perspectives). Addison-Wesley, 2012.
“架构设计关注于理解一个软件系统应该如何组织,并设计该系统的整体结构。”
-- Sommerville, I., 《软件工程》(Software engineering), 第10版. Pearson Education, 2016.
软件架构的重要性 (The Importance of Software Architecture)
- 促进利益相关者 (stakeholders) 之间的沟通。
- 使架构师和项目经理能够估算成本和进度。
- 为后续的实现定义约束。
- 包含了最基本且难以更改的设计决策。
- 为软件产品创建可传递和可复用的模型。
- 便于系统分析。
架构是一种抽象 (Architecture is an Abstraction)
- 在所有现代系统中,元素通过接口 (interfaces) 相互交互。
- 接口将元素的细节划分为公共 (public) 和私有 (private) 部分:
- 私有: 内部实现的细节。
- 公共: 元素如何排列、与其他元素交互、如何组合,以及支持设计推理的属性。
- 抽象的层次 (Levels of abstraction):
- 小型架构 (Architecture in the small):
- 单个程序的架构。
- 主要关注单个程序如何分解为组件 (components)。
- 单个组件实现功能性系统需求。
- 大型架构 (Architecture in the large):
- 由分布式组件组成的复杂系统的架构。
- 主要关注分布式组件如何组合形成新系统。
- 小型架构 (Architecture in the small):
注意: 元素的私有细节不属于架构范畴!
好的,这是使用 Markdown 格式,最高标题为三级的说明:
小型架构 (Architecture in the Small) - 关注单个程序/组件内部
这涉及到平台中 某一个具体程序或服务 的内部结构设计。
例子 1:商品详情页面服务 (Product Detail Service)
假设我们有一个微服务,专门负责获取和展示商品的详细信息。
小型架构 关注的是:这个 单一服务内部 是如何组织的?
- 分解: 它可能被分解为几个主要的内部模块或类:
Controller/API层: 接收来自前端或其他服务的HTTP请求(比如请求某个商品ID的详情)。Service层: 包含业务逻辑,比如从数据库获取商品信息、调用库存服务检查库存、调用评论服务获取评论。Repository/DAO层: 负责与商品数据库进行交互,执行SQL查询或使用ORM。Data Transfer Objects (DTOs): 用于在不同层之间传递数据。Utility类: 提供一些辅助功能,如价格格式化、数据验证等。
- 交互: 这些内部模块如何通信?Controller 调用 Service,Service 调用 Repository 和其他外部服务(对这个小服务来说是外部的,但在整个大平台内)。
- 模式: 可能采用了像 “分层架构” (Layered Architecture) 或者 “领域驱动设计” (Domain-Driven Design) 中的某些模式来组织内部代码。
- 关注点: 代码的可维护性、可测试性、模块间的低耦合、高内聚,确保这个 单一服务 本身是健壮和易于修改的。
例子 2:购物车组件 (Shopping Cart Component - 在前端应用中)
在前端的Web应用(比如用React或Vue构建的单页应用)中,可能有一个专门处理购物车的组件。
小型架构 关注的是:这个 购物车组件本身 如何设计?
- 分解: 可能包含:
UI视图 (View): 显示购物车内容、数量、总价。状态管理 (State Management): (如 Redux store 或 Vuex module) 存储购物车数据(商品列表、数量)。Action/Reducer/Mutation: 处理添加商品、移除商品、更新数量等操作的逻辑。API调用模块: 负责与后端的购物车服务进行通信(保存购物车状态、获取最新价格等)。
- 交互: 用户在UI上的操作触发Action,Action调用API模块并更新状态管理,状态变化驱动UI更新。
- 关注点: 组件的可复用性、状态管理的一致性、UI与逻辑的分离,确保这个 前端组件 功能正确且易于维护。
大型架构 (Architecture in the Large) - 关注多个程序/系统之间的交互
这涉及到整个在线购物平台是如何由 多个不同的、可能分布式的程序或服务 组合而成的。
例子:整个在线购物平台
这个平台不是一个单一的程序,而是由许多独立的系统/服务组成。
大型架构 关注的是:这些 不同的系统/服务 如何协同工作?
- 组件:
Web前端应用: 用户直接交互的界面。用户服务 (User Service): 处理用户注册、登录、信息管理。商品服务 (Product Service): 管理商品目录、详情(可能是上面例子1中的服务)。订单服务 (Order Service): 处理订单创建、支付、状态更新。库存服务 (Inventory Service): 管理商品库存。支付服务 (Payment Service): 与第三方支付网关交互。购物车服务 (Cart Service): 管理用户的购物车数据。消息队列 (Message Queue): (如 Kafka, RabbitMQ) 用于服务间的异步通信(例如,订单创建后通知库存服务扣减库存)。API网关 (API Gateway): 作为所有后端服务的统一入口,处理路由、认证、限流等。数据库集群: 可能包含多个不同类型的数据库(关系型、NoSQL)服务于不同的微服务。
- 交互:
- Web前端通过API网关调用用户服务进行登录。
- 用户浏览商品时,前端调用商品服务获取信息。
- 用户添加商品到购物车,前端调用购物车服务。
- 用户下单时,前端调用订单服务,订单服务内部可能需要调用用户服务、商品服务、库存服务、支付服务。
- 订单支付成功后,订单服务可能通过消息队列发布一个“订单已支付”事件,库存服务和可能的物流服务会订阅这个事件并做出响应。
- 模式: 可能采用了像“微服务架构” (Microservices Architecture)、“事件驱动架构” (Event-Driven Architecture)、“客户端-服务器架构” (Client-Server Architecture) 等模式。
- 关注点: 系统的整体可伸缩性 (Scalability - 如何处理大量用户和请求?)、可用性 (Availability - 单个服务故障是否影响整个系统?)、可靠性 (Reliability - 数据一致性如何保证?)、性能 (Performance - 用户请求的响应时间如何?)、服务间的通信协议 (如 RESTful API, gRPC, 消息队列)、数据如何在不同服务间同步等。
架构设计生命周期 (Architecture Design Lifecycle)
- 在所有需求中,有少数对架构具有特殊重要性,称为架构显著性需求 (Architecturally Significant Requirements - ASRs):
- 例如,系统最重要的功能、约束条件以及高质量属性(如高性能、高可用性等)。
- 设计是从需求到解决方案的转化 (translation) 过程,解决方案可以是由代码、框架和组件构成的结构。
- 应在架构设计阶段创建结构的初步文档(草图)。
- 如果正在开发的项目并非微不足道,则应对设计进行评估 (evaluated),以确保所做的决策能恰当满足ASRs。
- 架构师在实现阶段的职责是确保代码符合 (conformance) 设计。
好的,我们通过一个具体的例子来解释架构设计生命周期的各个阶段。
架构设计生命周期实际例子:构建一个在线视频流媒体平台 (类似简化版Netflix)
假设我们要从头开始设计一个新的在线视频流媒体服务。
-
识别架构显著性需求 (ASRs - Architecturally Significant Requirements)
在与产品经理、业务方、技术团队等沟通后,我们识别出对系统架构影响最大的需求:
- 核心功能: 用户能够流畅地观看视频库中的视频。
- 高质量属性 (ASRs):
- 高性能 (High Performance): 视频加载时间必须短(例如,点击播放后2秒内开始),播放过程中缓冲卡顿要尽可能少。用户搜索视频响应要快。(这是关键用户体验,直接影响架构选择,如CDN、流媒体协议)
- 高可伸缩性 (High Scalability): 系统需要能够支持未来百万级甚至千万级并发用户观看视频,尤其是在热门内容发布时。视频库会不断增长。(这决定了不能用单体应用,需要分布式、可独立扩展的组件)
- 高可用性 (High Availability): 服务需要接近 7x24 小时可用。单个服务器或组件的故障不应导致整个服务中断。(需要冗余设计、故障转移机制)
- 可维护性 (Maintainability): 需要能够方便地添加新功能(如用户评论、个性化推荐、直播功能)和更新现有功能,不同功能模块的开发应能并行。(影响模块划分、接口设计)
- 约束 (Constraints):
- 必须部署在公有云平台(如 AWS 或 Azure)上。(限制了可选的技术栈和基础设施)
- 需要支持多种客户端设备(Web浏览器、iOS App、Android App、智能电视)。(影响API设计、视频编码格式)
我们确定,高性能(播放体验)、高可伸缩性(用户量)和高可用性是这个项目的核心ASRs。
-
设计解决方案 (Design Solution)
基于上述ASRs,架构师开始设计系统的整体结构:
- 针对高性能和可伸缩性:
- 决定采用微服务架构 (Microservices Architecture),将系统拆分为独立的服务,如:用户服务、视频元数据服务、推荐服务、流媒体网关服务、视频处理服务等。每个服务可以独立部署和扩展。
- 视频内容存储在云对象存储(如AWS S3)中,并使用内容分发网络 (CDN - Content Delivery Network) 将视频片段缓存到离用户近的边缘节点,以减少延迟,提高加载速度和播放流畅度。
- 采用自适应比特率流媒体 (Adaptive Bitrate Streaming - ABR) 技术(如 HLS 或 DASH),根据用户网络状况动态调整视频清晰度。
- 针对高可用性:
- 所有微服务都部署多个实例,分布在云平台的多个可用区 (Availability Zones - AZs)。
- 使用负载均衡器 (Load Balancers) 分发请求到健康的实例。
- 数据库采用主从复制或集群模式,实现数据冗余和故障转移。
- 针对约束:
- 所有设计都基于选定的云平台提供的服务(虚拟机/容器、对象存储、CDN服务、数据库服务等)。
- API网关 (API Gateway) 提供统一接口,适配不同客户端的需求。
解决方案的结构大致是:客户端 -> CDN/API网关 -> 各微服务 -> 数据库/对象存储/消息队列。
- 针对高性能和可伸缩性:
-
创建初步文档 (Document the Design - Sketches)
架构师绘制草图和初步的架构图来沟通和记录设计:
- 高层组件图: 显示主要的微服务(方框表示)、CDN、API网关、数据库等,以及它们之间的主要交互关系(箭头表示)。
- 部署图 (初步): 粗略展示服务如何部署到云的不同可用区,以及负载均衡器的位置。
- 关键场景序列图: 如“用户点击播放视频”的交互流程,涉及客户端、CDN、API网关、流媒体网关服务等。
这些文档在早期可能比较简单,用于团队内部讨论和评审。
-
评估设计 (Evaluate the Design)
由于这是一个重要的商业项目(非微不足道),需要评估设计能否满足ASRs:
- 性能评估:
- 分析:估算使用CDN后,不同地区用户的视频加载延迟。
- 原型:构建一个简单的流媒体网关原型,测试其处理并发流的能力。
- 可伸缩性评估:
- 场景分析:模拟热门剧集发布时的高并发场景,分析哪些服务(如流媒体网关、推荐服务)可能成为瓶颈。数据库能否支撑预期的读写负载?
- 评审:检查微服务划分是否合理,是否有利于独立扩展。
- 可用性评估:
- 故障场景分析:讨论如果某个微服务的一个实例挂了会怎样?一个可用区断网了会怎样?数据库主节点故障了会怎样?设计的冗余和故障转移机制是否充分?
- 可以使用 ATAM (Architecture Tradeoff Analysis Method) 等更正式的方法进行评审。
评估可能会发现问题,比如:“推荐服务的算法复杂度高,可能成为扩展瓶颈”,或者“数据库选型在千万用户规模下可能成本过高且性能不足”。基于评估结果,可能需要修改设计(比如更换推荐算法、选择更合适的数据库类型或引入缓存)。
- 性能评估:
-
确保实现符合设计 (Ensure Conformance during Implementation)
设计通过评估并确定后,开发团队开始实现。架构师的职责转变为:
- 沟通和指导: 向开发团队详细解释架构设计、选型原因、接口约定。
- 评审代码和实现:
- 检查代码是否遵循了微服务边界,有没有服务之间产生不合理的强耦合调用?
- 视频上传和处理流程是否按照设计的异步方式(如使用消息队列)实现?
- 数据库访问是否高效?是否正确使用了连接池?
- 部署脚本是否按照高可用性要求配置了多实例和跨AZ部署?
- 把关技术决策: 当开发中遇到新的技术选择或需要对原设计做微调时,架构师需要评估这些变更对整体架构(尤其是ASRs)的影响,并做出决策。例如,某个团队想引入一个新的缓存库,架构师需要评估其性能、可靠性以及是否符合整体技术栈策略。
- 维护架构文档: 随着实现的进行,更新和细化架构文档。
如果发现实现偏离了核心架构设计(例如,一个团队为了图方便,绕过API网关直接调用了另一个内部服务),架构师需要及时纠正,解释为什么这会违反可维护性或安全性的原则,并要求其按照架构设计进行修改。
通过这个例子,你可以看到架构设计不是一次性的活动,而是一个贯穿项目始终、不断迭代和演进的过程,其核心是围绕着满足关键的架构显著性需求(ASRs)来进行决策、评估和验证。
原则性方法 (Principled Methods)
- 我们实际上如何进行设计?
- 执行设计以确保满足业务需求需要一种原则性的方法 (principled method)。
- 方法提供指导。
- 架构设计方法 (Architectural Design Methods): (列举)
- 属性驱动设计 (Attribute-Driven Design - ADD)
- 西门子4视图 (Siemens 4 Views)
- 业务架构、过程与组织 (Business Architecture Process and Organization - BAPO)
- 关注点分离架构 (Architecture Separation of Concerns - ASC)
- 软件架构设计通用模型 (General Model of Software Architecture Design)
- 以架构为中心的设计方法 (Architecture-Centric Design Method - ACDM)
- 视点与视角方法 (Viewpoint and Perspective Method)
- RUP的4+1视图 (RUP’s 4+1 Views)
架构视图 (4+1) (Architectural Views (4+1))
- 逻辑视图 (Logical View): 展示系统中的关键抽象,表现为对象或对象类。
- 用于将系统需求与逻辑视图中的元素关联起来。
- 物理视图 (Physical View): 展示系统硬件以及软件组件如何在系统中分布。
- 用于规划系统部署。
- 过程视图 (Process View): 展示系统在运行时如何由交互的进程组成。
- 用于对非功能性系统特性做出判断。
- 开发视图 (Development View): 展示软件如何为开发而分解。
- 用于分配工作和规划开发。
- 场景 (Scenarios): 用于阐释和验证上述4个视图。
参考 (4+1模型): Kruchten, P.B., 1995. The 4+ 1 view model of architecture. IEEE software, 12(6), pp.42-50.
结构与视图 (Structures and Views - ADD概念)
- 视图 (view) 是一组架构元素的表示。
- 视图包含一组元素及其关系的表示。
- 结构 (structure) 是元素集合本身,存在于软件或硬件中。
- 模块结构 (Module structures): 系统如何结构化为一组必须构建或采购的代码或数据单元。
- 组件与连接件结构 (Component-and-connector structures): 系统如何结构化为一组具有运行时行为(组件)和交互(连接件)的元素。
- 分配结构 (Allocation structures): 展示软件元素与其操作环境中元素之间的关系。
架构师设计结构。他们文档化这些结构的视图。
参考 (结构与视图): Bass, L. Clements, P. and Kazman, R. 《软件架构实践》(Software architecture in practice), 第3版, 2013.
视点与视角 (Viewpoints & Perspectives)
“视点 (Viewpoint) 是用于构建一种类型视图的模式、模板和约定的集合。”
“视图 (View) 是架构的一个或多个结构方面的表示,它阐释了架构如何解决其一个或多个利益相关者所持有的一个或多个关注点。”
“架构视角 (Architectural perspective) 是一组架构活动、策略和指南的集合,用于确保系统展现出特定的一组相关质量属性,这些属性需要在系统的多个架构视图中加以考虑。”
-- Rozanski, N. and Woods, E., 《软件系统架构:使用视点和视角与利益相关者协作》(Software systems architecture: working with stakeholders using viewpoints and perspectives). Addison-Wesley, 2012.
视点 (Viewpoints)
- 上下文视点 (Context viewpoint): 描述系统与其环境之间的关系、依赖和交互。
- 功能视点 (Functional viewpoint): 描述系统的功能元素、它们的职责、接口和交互。
- 信息视点 (Information viewpoint): 描述系统如何存储、操作、管理和分发信息。
- 并发视点 (Concurrency viewpoint): 描述系统的并发结构,并将功能元素映射到并发单元。
- 开发视点 (Development viewpoint): 描述支持软件开发过程的架构。
- 部署视点 (Deployment viewpoint): 描述系统将如何在其操作环境中安装和部署,以及相关的依赖关系。
- 运维视点 (Operational viewpoint): 描述系统将如何被操作、管理和支持。
![image]()
(图示:展示了不同视点之间的关系)
架构视角 (Architectural Perspectives): 视点为构建视图提供了模板。
架构模式 (Architectural Patterns)
- 架构元素可以以解决特定问题的方式进行组合。
- 这些组合随着时间的推移,在许多不同领域都被证明是有用的。
- 它们已被文档化和传播。
- 这些架构元素的组合被称为架构模式 (architectural patterns)。
- 模式为解决特定类型的问题提供了打包的策略。
- 架构模式描绘了解决问题所使用的元素类型及其交互形式。
- 包含:上下文 (Context), 问题 (Problem), 和 解决方案 (Solution)。
阅读 (架构风格): Mary, S. and David, G., 1996. 《软件架构:新兴学科的视角》(Software architecture: perspectives on an emerging discipline). Prentice-Hall.
客户端-服务器架构 (Client-Server Architecture)
- 上下文 (Context): 存在共享资源和服务,大量分布式客户端希望访问,并且我们希望控制访问或服务质量。
- 问题 (Problem): 通过管理一组共享资源和服务,我们可以通过分解出公共服务并在单一或少数位置修改来提升可修改性 (modifiability) 和复用性 (reuse)。我们希望通过集中控制这些资源和服务,同时将资源本身分布到多个物理服务器上来提高可伸缩性 (scalability) 和可用性 (availability)。
- 解决方案 (Solution): 客户端通过请求服务器的服务进行交互,服务器提供一组服务。某些组件可能同时扮演客户端和服务器的角色。可以有一个中央服务器或多个分布式服务器。
(图示:Client(s) <--> Server(s))
客户端-服务器架构特性 (Client-Server Architecture Features)

- 优点 (Advantages):
- 服务器可以分布在网络中。
- 通用功能可供所有客户端使用。
- 约束 (Constraints):
- 客户端通过请求/应答连接件连接到服务器。
- 服务器组件也可以是其他服务器的客户端。
- 弱点 (Weaknesses):
- 服务器可能成为性能瓶颈。
- 服务器可能成为单点故障。
- 关于功能定位(客户端或服务器)的决策通常很复杂,且在系统构建后更改成本高昂。
好的,这是使用 Markdown 格式,最高标题为三级的客户端-服务器架构知识点解释:
客户端-服务器架构 (Client-Server Architecture) 详解
核心思想:分工与协作
最核心的概念是,系统中的不同部分扮演不同的角色:
-
服务器 (Server):
- 角色: 服务提供者。它拥有资源(比如数据、文件、计算能力)或者提供特定的服务(比如用户认证、数据处理、打印)。
- 行为: 它通常是被动等待的,等待客户端来请求服务。当收到请求后,它会处理请求,然后返回结果(或执行某个动作)。
- 类比: 餐厅的厨房和厨师。厨房拥有食材(资源),厨师提供烹饪服务。他们等待顾客(客户端)点单(请求)。
-
客户端 (Client):
- 角色: 服务请求者或使用者。它需要服务器提供的资源或服务来完成自己的任务。
- 行为: 它是主动发起请求的。它知道找哪个服务器,发送请求,然后等待服务器的响应。
- 类比: 去餐厅吃饭的顾客。顾客需要食物(资源)和服务。他们主动向服务员或厨房(服务器)点单(发出请求)。
它们如何交互?
客户端和服务器通过网络连接。交互的基本流程是请求-响应 (Request-Reply):
- 客户端向服务器发送一个请求 (Request),说明它想要什么(比如,“给我这个网页”、“验证这个用户名和密码”、“保存这个文件”)。
- 服务器接收并处理这个请求。
- 服务器向客户端发送一个响应 (Response),包含请求的结果(比如,网页内容、认证成功/失败信息、文件保存确认)或者一个错误信息。
结合PPT内容解释:
-
上下文 (Context):
- “存在共享资源和服务”: 就像网站的网页文件、公司的共享打印机、银行的账户数据库。
- “大量分布式客户端希望访问”: 很多用户(在不同的电脑、手机上)都想看这个网页、用这个打印机、查自己的银行余额。
- “我们希望控制访问或服务质量”: 网站可能需要登录才能看某些内容(控制访问),银行系统需要保证交易的准确性(服务质量)。
- 简单说: 当有很多分散的用户需要访问集中的资源或服务,并且需要对这种访问进行管理时,就适合用客户端-服务器架构。
-
问题 (Problem):
- “通过管理一组共享资源和服务...提升可修改性 (modifiability) 和复用性 (reuse)”: 如果把处理共享资源(如用户信息)的逻辑都放在服务器上,当需要修改逻辑(比如增加一个新的用户信息字段)时,只需要修改服务器代码,所有客户端都能受益。这个逻辑也可以被不同的客户端(网页、手机App)复用。
- “通过集中控制...提高可伸缩性 (scalability) 和可用性 (availability)”:
- 可伸缩性: 如果访问量增大,可以通过增加更多服务器(或者给服务器增加配置)来处理更多请求,而客户端通常不需要大改动。
- 可用性: 虽然PPT提到服务器可能是单点故障(下面会说),但通过部署多个服务器(备份、负载均衡),可以提高整体的可用性。集中控制使得管理这些服务器成为可能。
- 简单说: 如何有效地管理共享资源,让修改更容易,让更多人能用,并且保证服务尽可能不断线?把核心逻辑和资源管理放到服务器是个好办法。
-
解决方案 (Solution):
- “客户端通过请求服务器的服务进行交互,服务器提供一组服务”: 这就是上面说的请求-响应模式。
- “某些组件可能同时扮演客户端和服务器的角色”: 想象一个Web服务器(对你的浏览器来说是服务器),它可能需要去请求数据库服务器(此时Web服务器扮演了客户端的角色)来获取数据。
- “可以有一个中央服务器或多个分布式服务器”: 可以是一个大服务器处理所有请求,也可以是很多服务器分散在不同地方协同工作(比如大型网站的服务器集群)。
- 简单说: 让需要服务的客户端主动去请求提供服务的服务器。
特性解释:
-
优点 (Advantages):
- “服务器可以分布在网络中”: 服务器和客户端不需要在同一个地方,可以通过互联网或局域网连接。
- “通用功能可供所有客户端使用”: 比如用户登录验证,这个功能放在服务器上,无论是网页端登录还是App端登录,都可以调用同一个服务。
-
约束 (Constraints):
- “客户端通过请求/应答连接件连接到服务器”: 它们之间的沟通方式主要是这种一问一答的模式。
- “服务器组件也可以是其他服务器的客户端”: 如上所述,一个服务器为了完成任务,可能需要请求另一个服务器。
-
弱点 (Weaknesses):
- “服务器可能成为性能瓶颈”: 如果所有客户端都向同一个服务器发送大量请求,服务器可能处理不过来,导致响应变慢。就像高峰期只有一个厨师的餐厅。
- “服务器可能成为单点故障”: 如果只有一个服务器,一旦它宕机了,所有客户端都无法获得服务。就像餐厅厨房关门了,所有顾客都吃不上饭。 (虽然可以通过部署多个服务器来缓解,但这是基本模型的一个固有风险)。
- “关于功能定位...复杂且 costly to change”: 在设计初期,要决定哪些计算和逻辑放在客户端做(比如输入验证),哪些放在服务器做(比如核心业务处理)。这个决定会影响性能、安全性和开发复杂度。一旦系统建好,要改变这个分工(比如把原来在服务器做的计算移到客户端)可能会非常困难和昂贵。
常见例子:
- Web浏览: 你的浏览器是客户端,它向Web服务器请求网页。
- 收发邮件: 你的邮件软件(如Outlook, Foxmail)或网页邮箱是客户端,它连接到邮件服务器来下载和发送邮件。
- 在线游戏: 你的游戏程序是客户端,它连接到游戏服务器来同步游戏状态、玩家位置等信息。
- 文件共享: 你电脑上的文件管理器访问网络共享文件夹,你的电脑是客户端,提供共享文件夹的电脑或服务器是服务器。
分层架构 (Layered Architecture)

- 上下文 (Context): 所有复杂系统都面临需要独立 开发和演进(evolve) 的挑战。因此,系统开发者需要清晰且文档化的关注点分离 (separation of concerns),以便系统的模块可以独立开发和维护。
- 问题 (Problem): 软件需要以这样一种方式进行分割:模块可以独立开发和演进,部件之间交互很少,从而支持可移植性 (portability)、可修改性 (modifiability) 和复用性 (reuse)。
- 解决方案 (Solution): 为实现关注点分离,分层模式将软件划分为称为层 (layers) 的单元。每一层是一组提供内聚服务集(a cohesive set of services)的模块。使用关系必须是单向的。层完全划分了软件集合,每个分区通过公共接口暴露。
(图示:User Interface (UI) Layer -> Business Logic Layer -> Data Access Layer)
分层架构特性 (Layered Architecture Features)
- 优点 (Advantages):
- 如果接口保持不变,允许替换整个层。
- 可以在每层提供冗余设施以提高系统的可靠性 (dependability)。
- 约束 (Constraints):
- 每个软件片段都精确分配到一层。
- 至少有两层(但通常是三层或更多层)。
- 允许使用的关系不应是循环的(即,下层不应使用上层)。
- 弱点 (Weaknesses):
- 增加层会增加系统的前期成本和复杂性。
- 层会带来性能损失。
模型-视图-控制器 (MVC) 架构 (Model-View-Controller (MVC) Architecture)

- 上下文 (Context): 用户界面通常是交互式应用程序中最常被修改的部分。用户经常希望从不同角度查看数据。这些表示应能反映数据的当前状态。
- 问题 (Problem): 如何将用户界面功能与应用程序功能分离,同时又能响应用户输入或底层应用程序数据的变化?当底层应用程序数据变化时,如何创建、维护和协调用户界面的多个视图?
- 解决方案 (Solution): 模型-视图-控制器 (MVC) 模式将应用程序功能分离为三种组件:
- 模型 (Model): 包含应用程序的数据(数据和业务逻辑 比如 service)。
- 视图 (View): 显示底层数据的某一部分并与用户交互。(就是UI 前端交互界面)
- 控制器 (Controller): 在模型和视图之间进行协调,并管理状态变化的通知。
(图示交互:View -> (User Events) -> Controller -> (State Change) -> Model -> (Change Notification) -> View; Controller -> (View Selection) -> View; View -> (State Query) -> Model)
MVC 架构特性 (MVC Architecture Features)
- 优点 (Advantages):
- 允许数据独立于其表示进行更改,反之亦然 Allows the data to change independently of its representation and vice versa(就是动 UI 不动 service ,动 service 不动 UI)。
- 支持以不同方式呈现相同数据。
- 约束 (Constraints):
- 必须至少存在模型、视图和控制器各一个实例。
- 模型组件不应直接与控制器交互(就是 service 不能调用 controller)。
- 弱点 (Weaknesses):
- 对于简单的用户界面,其复杂性可能不值得。
- 可能不适用于某些用户界面工具包。
参考架构 – Web 应用 (Reference Architectures – Web Application)
- 参考架构 (Reference architectures) 是为特定类型的应用程序提供整体逻辑结构的蓝图。
- Web 应用程序通常通过 Web 浏览器访问,浏览器使用 HTTP 协议与后端服务器通信。
- 考虑使用此参考架构的情况:
- 不需要富用户界面 (rich user interface)。
- 不想安装任何客户端软件。
- 可移植性 (Portability) 和可访问性 (accessibility) 对软件架构很重要。
- 最小化客户端资源的使用。
- HTTP: 超文本传输协议 (Hypertext Transfer Protocol)
(图示:Web Browser <-(HTTP)-> Web Server -> Application Logic -> Database)
参考架构 – 移动应用 (Reference Architectures – Mobile Application)
- 移动应用程序通常安装在移动设备上,并由后端基础设施支持。
- 考虑使用此参考架构的情况:
- 移动应用包含两部分:运行在移动设备上的客户端部分,以及运行在后端服务器(如云环境)上的服务部分。
- 网络连接不可靠。当网络不稳定时,客户端软件可能在没有后端服务的情况下运行。
(图示:Mobile Device (Client App) <-(Network)-> Backend Infrastructure (Services, Data))
架构设计过程经验法则 (Architectural Design Process ‘Rules of Thumb’)
- 软件架构应由单一架构师或小型架构师团队负责。
- 以获得更好的概念完整性 (conceptual integrity) 和技术一致性 (technical consistency)。
- 架构师应基于优先排序且定义明确的质量属性需求列表来构建架构。
- 应对架构进行评估,以确定其满足系统重要质量属性的能力。
- 架构不应依赖于特定版本的商业产品或工具。
“好设计” vs. “坏设计” (“Good Design” vs. “Bad Design”)
“一个好的架构是能够成功解决其利益相关者关注点,并且当这些关注点冲突时,能够以利益相关者可接受的方式进行平衡的架构。”
-- Rozanski, N. and Woods, E., 《软件系统架构:使用视点和视角与利益相关者协作》(Software systems architecture: working with stakeholders using viewpoints and perspectives). Addison-Wesley, 2012.
“不存在所谓固有好或坏的架构。架构只有在某种程度上更适合或不适合某个特定目的。”
-- Bass, L. Clements, P. and Kazman, R. 《软件架构实践》(Software architecture in practice), 第3版, 2013.

浙公网安备 33010602011771号