子程序
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),将这些运维能力本身通过架构和平台的方式固化下来。