软件体系结构——发展脉络

发布于:2025-09-15 ⋅ 阅读:(21) ⋅ 点赞:(0)

子程序

20 世纪 60 年代是子程序的年代:出现了原始的软件架构,即子程序,并以程序间的调用为连接关系。

核心思想:将一段常用的代码封装起来,起一个函数名,在程序的不同地方调用,已解决重复编写的动作

进步

解决重复编写

子程序化后,主程序逻辑更清晰

修改功能时,只需要修改子程序的一处即可,所有调用自动生效

问题

全局变量混乱:大量的子程序调用,需要大量全局变量进行数据传递。一旦程序特别大,对于谁修改的数据难以跟踪,状态混乱。

全局变量命名重复:大量变量导致命名困难。

高耦合:修改一个子程序可能牵一发而动全身

复用性低:子程序的编写与主程序强相关,难以跨项目直接使用

模块化

20 世纪 70 年代是模块化的年代:出现了数据流分析、实体—关系图(E-R 图)、信息隐藏等工具和方法,软件的抽象层次发展到了模块级。

核心思想: 将功能相关的子程序和数据封装在一起,形成一个独立的模块(Module)。对外提供明确的接口,并隐藏其内部实现细节。

进步

解决全局变量混乱:数据封装在模块内部,不再是全局的,控制了数据的修改路径

初步复用:模块可以一定程度编写成库,被多个程序调用。

问题

设计难度:模块边界难以划分,提升了设计的难度,设计不好模块间仍会存在高耦合

抽象程度不够:模块与现实联系若,难以顺应思维链路编写代码。

面向对象

20 世纪 80 年代是面向对象的年代:基于模块化的编程语言进一步发展成面向对象的语言,继承性地增加了一种新元素之间的连接关系。

核心思想: 使用对象作为程序的基本单元。对象将数据和函数捆绑在一起。通过消息传递进行数据交流。核心特性是封装、继承、多态。

进步

更自然的抽象:对现实的模拟更自然,符合思维方式

更强的封装和信息隐藏:通过public、private严格限制外部对象对内部状态的访问

复用和拓展性优化:基于父类进行新类的创建,加强了复用性和拓展性。还添加了重写的特性。

多态降低耦合:程序可以通过多态依赖父类,而非通过大量具体实现的子类。使得调用和实现的解耦。

问题

类爆炸:复杂的程序仍会产生大量的类,各种类之间的继承、组合、依赖异常复杂,难以管理。

过渡设计:为了面向对象而复杂化程序

类的定义和观念不一致:导致开发后的分歧

仍存在大量重复基础工作:数据库连接、身份认证、网络通信等

框架

20 世纪 90 年代是框架的年代:标准的基于对象的架构以框架的形式出现了。如电子数据表、文档、图形图像、音频剪辑等可互换的黑箱对象,可以相互嵌入。

核心思想:框架是半成品的程序,编写了基础的结构和流程。开发者只需要通过按照框架规则,自行填入自己的业务逻辑,通过框架调用代码即可。

进步

解决重复造轮子的问题:将基础工作通用化,如Web MVC、ORM、事务管理、配置等

规范化和一致性:塑造了编写规范,加强了团队和项目间的交流成本。

效率提升:开发者更专注于业务创新,而非底层实现,缩短了开发周期。

问题

学习成本升高:每个框架都有自己的规则,使用需要时间学习和适应

灵活性受限:一旦采用框架,就必须规范编写,框架设计外的功能实现会很困难

系统互通困难:不同团队、不同项目可能使用不同框架、技术栈,互通困难。

中间件&微服务

当前(最近 10 年来):中间件和微服务作为标准平台出现,用可购买可复用的元素来构建系统,同时,基于架构的开发方法和理论不断成熟。

核心思想:
中间件是介于操作系统和程序之间的通用服务软件。
微服务是这一思想的直至体现,将程序拆分为一组小而自治的服务。

进步

解决异构系统间的互通:中间件如消息队列MQ、API网关、分布式缓存Redis,为不同技术栈的系统提供了标准的通信协议,如HTTP/REST, AMQP。

解耦:通过异步消息队列,系统间不再需要同步调用,实现了时间解耦和位置解耦。

分布式提升处理效率

问题

运维复杂度升高:需要管理大量服务、服务器、网络调用、依赖关系。部署、监控、调试、数据一致性变得极其复杂。

分布式固有问题:网络延迟、故障、数据一致性

IT架构

云计算、大数据、 DevOps 文化的成熟,使从更宏观的角度进行组织应用、数据、技术、人员。常见架构包括企业架构(EA)、业务架构、应用架构、数据架构、技术架构等。

进步

系统性的整合和优化,明确了标准

管理超大规模系统: 为应对微服务和云计算带来的运维复杂度,衍生出云原生架构(容器化Docker、编排Kubernetes、服务网格Istio、DevOps),将这些运维能力本身通过架构和平台的方式固化下来。