前言
很多领域都要求从业人员具备整合能力,程序员也不例外,相信很多猿友们在接收项目或者任务的时候,总会被要求给出一份详细的技术方案或者设计思路,这毫无疑问需要我们输出大量的构思“图纸”,就像建筑行业的设计图纸一样。
可见,我们不仅仅要面向代码编程,还得学会如何给出指导性的决策思路,而这其实已经是属于架构的范畴了。今天,就让我们来聊一聊关于架构的认知吧!
定义
我们先来看看“架构”的含义:架构是软件整体结构与组件的抽象描述,它定义了系统涉及到的各个元素,并将这些元素通过一定的规则联合起来,协同完成整体的目标功能。而这一过程的产物就是所谓的架构图,它将涉及的元素和关系可视化出来,形成有标注、有说明的构建蓝图。
实际上,架构它将需要面向多种人群进行阐述,比如 boss 想要了解的是概念,产品经理想看到的是设计,而开发工程师关心的则是能力边界。因此,我们往往会自顶向下的考虑软件的体系结构。从概念、模块、运行、代码的角度去组织。
当然,软件架构不仅仅是关于组件的定义与连接,还需关注“适当正确”的决策,并衡量这些决策的产生对现有模型的影响。它需要我们掌握更多的架构知识,比如性能、成本、安全等。以构成一个经得起推敲的架构流程。
这也是一个不断在“折腾”的过程,从架构分析、架构合成、架构评估再到架构演进,我们需要不断的进行知识整合、设计推理、合理决策、编写文档。而只有不断进行更新的架构图才是具有生命力的,因为它对齐了现实的变化过程。
思路
当系统需要架构分析的时候,意味它是复杂的。在软件行业里,针对复杂的事物总会进行分层,或者将关注点进行拆分,通过不同的视角来完善结构体系。像4 + 1 架构视图
就为我们提供了一个分析模型,如下图:
它以场景视图即用户实例为核心,把功能需求、运行时态、软件实现、物理部署紧紧的结合在一起,让我们能更全面的看待系统架构。
当然,这里面的场景用例是需要我们去构建,一般来讲,我们会使用 UML
来描述,UML
主要由参与者、用例组成。参与者比较好理解,即与系统交互的人或事物,而用例可以理解为系统提供的服务。
在这些用例和参与者之间是有边界划分,并且有关联关系的。通过用例图,我们就可以分析系统的功能和行为了。
UML
例子:
不过,在敏捷开发流行的今天,可能架构图的输出已经没有那么的具体了,更多的是很简单的文字、框线。为了能在效率与细节上取得平衡,架构师 Simon Brown 提出了 C4
模型。通过容器(包含应用程序、数据存储、微服务)、组件和代码来解释当前系统的静态结构。
其中:
系统上下文(Context): 重点描述用户是如何和系统交互的,并且不同系统之间的交互又是怎么样的。
容器(Container): 将系统分解为相互关联的容器,每个容器可以是服务、应用程序、DB、文件系统等。是系统的执行或存储单元。
组件(Container): 将容器分解为相互关联的组件, 组件是可以给多个容器或多个系统复用的。它代表是更为详细的实现方案。
代码(code): 代码是程序真正的实现,包括面向对象设计、实体关系图(ER)等。
完整的 C4 模型案例如下:
常见架构模式
前面也提到过,软件行业里有针对复杂场景的常见解决思路。这些思路其实算是一种架构模式或风格,它站在了较高的角度去看待整个系统,下面让我们具体来看看有哪些架构模式吧。
分层架构
分层架构是常见的架构模式,它通过将系统的关注点拆分到几个层次里,进而隔离了不同的变化,使得职责分明,能降低整体的复杂度。像经典的三层架构:UI 层、业务逻辑层、数据访问层。它们从用户的交互、服务的处理、数据的管理这三个角度对系统进行了划分。
不过,分层架构也不是层次越多越好,一旦多了,系统认知成本就会高,调用链就变深,而且容易各自开发,各自为政,复用性随之降低。
主从式架构
主从式架构也称客户端/服务器架构、C/S 架构,是一种网络架构,它把客户端与服务器区分开来。每一个客户端软件的实例都可以向一个服务器或应用程序服务器发出请求,并且允许存在很多不同类型的服务器,例如文件服务器、游戏服务器等。
主从式架构界定了服务使用者和服务提供者,一个是主动角色,另一个是被动角色。通过请求-响应类似的交互进行通信。重点在于服务提供者能提供哪种能力。
事件驱动架构
事件驱动架构是属于异步的体系结构,从事件的发起到路由再到接收处理都允许并发的进行。它专注的是业务系统状态的变化从而衍生的一系列动作处理,这是和面向服务即以数据为中心的架构模式的不同之处。
微服务架构
微服务架构是现在较为流行的架构模式,它将大型应用分解为多个独立的组件,每个组件都有各自的责任领域,都是一个独立的服务。其目标旨在提供某种应用特性的服务单元,能快速开发、降低协同成本。
另一方面,微服务在运维上面临着较大的管理难度,毕竟它将系统拆分的更细、更多了。不过当配合了容器
、K8s
这些 DevOps
神器后,微服务的开发部署效率将大大的提升,使得敏捷开发更容易推行。
当然,微服务也带来其他的挑战,比如分布式事务、监控告警等,这些都需要有一个强大的团队支持才行。
步骤
如果我们要为某个系统进行架构设计,画架构图,那将会是一个庞大的工程。因为我们将会和不同的参与人员,比如项目经理、产品经理、运营人员进行反复的沟通确认,来得出合适的解决方案。
为了能让自己有计划,有步骤的进行这项设计工程,我们可以按以下的阶段来整合结果。
架构分析
架构分析是为了解系统将要运行的环境,以及将会由哪些系统需求。关于需求的输入可以来自项目参与人员,也可以是以下几种:
- 系统运行时将会做什么、操作什么
- 系统的支撑需求是什么,比如可靠性、可操作性、性能效率、安全性,和兼容性
- 系统非功能性要求有哪些,比如故障转移、自动扩容等
- 系统以外的附加要求有哪些,比如人脸识别的安全存储、数据脱密等
总之,我们将会列出和系统架构相关的需求,或许不能面面俱到,但也一定是重点需求。
架构合成评估
分析出需求后,我们将会进行方案的设计或者改善现有方案。但无论怎么样,我们每产出一个结果时,都要和之前的产物整合到一起,以便提前纠错。另外,我们在整合时应该要有个评估标准,比如性能、成本、合理性等,最好是能对问题的产生有多个决策选型,然后进行取舍。
架构演进
在确认当前的架构设计满足各个需求后,此时我们也就完成现阶段的架构设计了。不过,在后续新功能的加入或者旧功能的改造时,要能平衡现有系统的设计,重新进行架构分析、架构合成、架构评估。
注意项
人的大脑所能承载的知识是有限的,因此,在输出想法的时候,我们应该要学会记录和管理。还得将产出的文档不断的推送给项目相关人员,沟通确认。
或许这一步对于程序员来讲,可能会比架构设计更难,因为它需要我们有沟通能力、组织能力,这已经不仅仅涉及软件领域了,还得和人打交道。
而当架构设计出来后,我们是有责任负责项目落地实现的,此时将涉及工作的分解和反馈。如何能保证系统按照我们的预期进行,或者在进行过程中能不断的反馈修正,这也大大考验了我们的组织领导能力。
所以,除了架构设计需要过硬的知识,还得在项目管理上具备一定的推动能力,这样才能形成闭环。
总结
架构设计是对项目解决方案的高级抽象,它决定了后续系统的实现方向。从系统分析到汇总方案再到具体实现,这都需要我们储备大量的知识去推动。希望今天的文章能对大伙有所帮助!