Log4D

Log4D

马上订阅 Log4D RSS 更新: https://blog.alswl.com/atom.xml

架构设计 the Easy Way

2023年7月29日 14:54

arch-easy

image via Pixabay

概览

前几日,我在团队内部举行了一场技术分享,我介绍了关于架构设计的最佳实践。将这些实践凝练成了 20 字口诀

  1. 架构看问题
  2. 需求看用例
  3. 设计看模型
  4. 细节看时序

我将顺口溜转到了 Twitter,不少朋友对这些顺口溜产生了浓厚兴趣,希望深入了解。因此,我将我分享中的观点扩展成了这篇文章。

架构设计和系统分析

让我们首先澄清 什么是架构设计和系统分析(简称系分)。有些朋友对前者很熟悉,对后者却不太了解。 不过没关系,以下是维基百科上的介绍:

架构,软件架构是有关软件整体结构与组件的抽象描述,用于指导大型软件系统各个方面的设计。

系统分析,旨在研究特定系统结构中各部分(各子系统)的相互作用,系统的对外接口与界面,以及该系统整体的行为、 功能和局限,从而为系统未来的变迁与有关决策提供参考和依据。

来看一下英文定义可能会更清晰:

我们有时候提到的设计文档,可能涵盖整个设计过程,包括架构设计、系统分析以及其他设计活动(交流、PoC)。

软件架构(设计)= Software Architecture

  • 设计和实现软件系统的基本结构和组织形式
  • 在业务层面:明确问题,厘定概念,呈现价值
  • 在技术层面:确定基础框架,将不确定性转化为确定性
  • 工程层面:识别边界和拆分各个模块,提高应用开发效率

系统分析 = System Analysis

  • 对业务需求和问题进行分析和研究的过程
  • 在业务层面:需求收集、需求分析
  • 在技术层面:建模,绘制流程图、数据流图和接口设计
  • 工程层面:在应用、系统框架内实现需求

最后,我来解释一下我对这两者边界的理解。实际上,我认为架构设计和系统分析并没有明显的界限。 一个系统或模块不管如何都会进行系统分析,而当出现以下几个特征时,就开始考虑架构设计问题:

  • 当有超过 3 个团队在协作时,因为这时涉及到利益和边界的问题。
  • 当开始主动或被动引入不确定性。
  • 当开始平衡取舍,需要先做到什么程度,再做到什么程度。
  • 当不系统过于复杂,太容易达成一致,开始有解释成本时。
  • 当能够提供别人不了解的信息。

什么是架构

在这里,我们讨论的是技术架构,不会涉及业务架构或产品架构等方面。 技术方面的讨论重点是如何更高效地利用技术能力和方法来解决特定类型的问题

进一步地,技术架构可以分为两种:一种是从顶层向下看,包括业务、战略和框架划分; 另一种是关注工程实现(编码)层面需要解决的架构问题。

那些经验丰富的人常常有较宏观的视角,使用的常见名词有:全局、宏观、领域、战略、平衡、规划。我将这些词汇整理成了一个词云如下:

word-cloud-arch-biz

generted by https://tendcode.com/tool/word-cloud/

以上这些概念在架构设计和系统分析中都非常重要,因为它们帮助我们在整体上考虑问题,甚至超越技术层面, 从业务价值、商业策略和业务战略的角度思考问题。

另一种架构偏重于工程设计和实现。常见的关键词有:领域建模、UML、GoF23,SOLID,高内聚低耦合等等。对应的词云如下:

word-cloud-arch-impl

generted by https://tendcode.com/tool/word-cloud/

架构的话题非常广泛,本文选择从一个切入点出发:通过实践和方法论,使架构意识在日常工作中发挥作用,以满足 80%的工程设计开发场景。 我称之为「架构设计 the easy way」。

极简架构设计 - 架构看问题

理解架构的第一步,也是最重要的一步,就是关注「问题」。也就是说,你遇到了什么问题,你将如何去解决它

通常情况下,如果我们的业务和系统都稳定运行,没有遇到任何问题,我们就不太需要进行架构设计。但是,只要涉及到架构设计, 必定是因为我们遇到了问题。这些问题可能源自新的需求,也可能是外部环境的变化, 亦或是系统自身随着时间的发展而出现的。无论问题的来源如何,我们都遇到了问题。

遇到问题之后,我们该如何解决?就像将大象装进冰箱一样,需要分成几个步骤。

把大象装进冰箱

image via unkown

因此,解决问题也有三个步骤:第一步是将问题描述清楚,第二步是进行协商和决策达成一致,第三步则是着手解决问题。

问题-一致-行动

我还想问一个听上去很愚蠢的问题:为什么不能直接解决问题?

因为问题是复杂的,有许多解决路径,不同的解决方案各有优劣和成本。在架构设计中,我们需要完成这些决策。

那为什么不直接进行决策,甚至直接开始动手?

首先可能涉及到职权问题,架构师未必有最终决策权,需要有决策权的人来做最后的决定。 第二个原因是架构师未必是方方面面的专家,设计一个复杂系统时候需要协调多个部分和领域专家来一起评估决策。

案例

我举 Prometheus 的架构设计来作为例子。

Prometheus architecture

image via Prometheus

这个架构图回答了很多问题,我举几个例子:

  • 问题:数据采集使用 Push 还是 Pull?使用什么存储?如何设计告警链路?
  • 决策:采用 Pull(少量情况下使用 Pushgateway);使用自己实现的 TSDB;使用 Alertmanager 与外部系统对接
  • ROI:采用 Pull 降低 Target 观测成本,不需要使用 Push-based 的 Registry; 没有现成的外部实现(当时);提供 Router / Sub 的告警机制以便灵活接入外部系统

小结

问题驱动架构变化,架构方案应对问题,架构评审统一解决方案。

关于决策拍板问题。我强烈推崇架构师根据自己具备的领域知识、对行业的判断以及对现状的了解, 做出自己的思考和独立判断。这些思考过程应该有因果关系的支持,一个优秀的架构师必定拥有自己的观点

最后,我补充一个小问题:为什么这里没有提到架构分层、模块分层?

不是因为分层和框架不重要,而是在因为大家都很专业。分层和模块化已经是基本常识和技能,因此反而往往不会成为争论和决策的焦点。 如果分层和框架无法快速形成一致,有可能团队构成上存在问题,也可能问题过于复杂已经不是 80% case。

在本阶段,产出的成果包括架构图以及对问题、价值、成本、风险和分工达成一致的认识。

极简架构设计 - 需求看用例

需求是对问题的解答。我个人喜欢用思维导图或白纸来画图,将需求讲清楚。 画什么内容呢?理清角色,并列出各种动作和行为。

那有什么技巧可以将事项都整理出来呢?我经常使用主谓宾状从的方法。 也就是说,明确哪些人,在什么场景(可选),以什么状态(可选)做着什么事情。

主谓宾

image via unkown

通过用例将需求清晰地拆解,并在这个过程中不断与需求提供方进行交流和沟通。

Demo 稿是产品经理的武器,而需求用例则是工程师的武器。

有些初入职场的研发人员会不自然地变成需求的执行者。我比较果断地判断,不了解业务的工程师和外包没什么区别。而需求分析环节是最重要的, 是对业务输入进行理解、梳理、重新设计的机会。通过用例的整理,我们可以将一些不切实际、不可靠的需求反馈给需求方。

这是少数可以推动(反馈)需求方的阶段,一定要珍惜。

案例

这里有一个产品用例的范例:

网易云音乐

image via 网易云音乐产品分析报告

实际上,这个用例是敌对势力那边总结的 😄,但仍然能够体现用例的重要性。

小结

除了使用主谓宾的方式来进行设计,还有一些其他技巧:

  • 使用动线(行动路线):想象用户(或行动者)完成他们目标的行动路线
  • 可以优先考虑解决核心路径中的...

剩余内容已隐藏

查看完整文章以阅读更多