为了账号安全,请及时绑定邮箱和手机立即绑定

正确架构设计:第一部分

它是什么,我们应该怎样看待它?

我们得拨开那些冗长的言辞,才能准确地理解软件架构!

当我们讨论软件架构时,理解这个术语不仅仅指一个方面是有用的。例如,宏观层面的架构、架构模式、模块间通信等,在软件系统的开发、部署与维护中,服务于不同的但必要的目的。

宏观架构

宏观架构(有时称为高层次架构),主要关心的是建立指导架构模式选择、详细设计和实现的基础属性和原则。

这一级别的架构对于设定方向以及确保系统在整个生命周期内与预期目标保持一致至关重要。

以下宏架构设计是企业应用程序的两个更佳的选择之一,更符合中文表达习惯。

整洁架构

《干净架构》(https://www.amazon.com/Clean-Architecture-Craftsmans-Software-Structure/dp/0134494164) 是一种设计理念,强调将系统划分为逻辑层,就像一个洋葱,每一层有自己的职责。核心思想是创建一个独立于框架、界面、数据库等外部因素的架构。它优先考虑核心业务逻辑和领域模型,确保这些核心元素不受技术或交付方式变化的影响。

这种架构设计通过允许开发人员在不影响核心业务逻辑的情况下修改和替换外部层(UI 和 数据库),从而提高系统的可维护性、可测试性和可扩展性。

精简架构

_《精简架构》(Lean Architecture)_ 是一种侧重于简洁性和效率的架构,旨在减少系统中的浪费和不必要的复杂性。受到制造业精益原则的启发,这种架构强调仅提供满足用户需求的功能,避免过度设计,并简化冗余流程。

这种架构支持持续交付与集成,从而实现快速的开发迭代和快速应对变化。它鼓励只开发必需功能的心态——确保系统保持灵活性、成本效益高,并能迅速响应客户反馈。

无论是‘Clean Architecture’还是‘Lean Architecture’,都旨在创建可维护、灵活且专注于提供价值的系统——但它们实现这些目标的方式不同。

Clean架构强调职责分离和保护核心业务逻辑,而精益架构则更注重效率、简洁性和对变化的响应。两者都指导架构模式的实施。

建筑设计模式

建筑模式是用于解决常见架构挑战的高层级可重用解决方案,提供组织和结构化软件系统的逻辑模板,解决特定关切并从而促进最佳实践。

  • 简化:它们通过提供一个起点和一组需要遵循的指导原则来简化设计过程。
  • 一致性:它们确保系统设计的一致性、可维护性并符合最佳实践。
  • 解决问题:它们解决了软件架构中常见的难题,例如可扩展性、灵活性和韧性。

有一种不幸的趋势是在没有先理解并选择合适的宏观架构之前就选择应用程序的架构模式,也很少有一种单一的架构模式能满足应用程序各个方面所有需求。

比如常见的架构模式有:

单一整体的

单块模式是一种统一的系统,在这种模式下,所有组件紧密集成并作为一个单一单元运行。整个应用,包括用户界面、业务规则和数据访问,都位于同一个加载模块中。

但随着系统规模的增长,可能会变得越来越难以扩展和维护,因为一处的改动可能会影响到整个系统。这种模式可以简化最初的开发和部署。

分层

分层模式将应用程序划分为几个独立的层次,每一层负责系统功能的一个特定方面,例如用户界面(UI)、业务逻辑层和数据访问层。每一层只和它旁边的层次交流,这样可以更好地分离关注点,并提高模块化程度。

采用这种模式可以使系统更容易理解和维护,虽然它可能变得僵硬且在扩展复杂的系统时变得困难。

基于事件的

事件驱动模式围绕事件的生成、检测和响应展开。系统中的组件通过生成和处理事件来进行通信,从而能够独立且异步地工作。

对于需要实时处理或大量交互的系统来说,这种模式可能很有用,但可能会增加管理工作流程和确保一致性的复杂性。

面向服务的架构(SOA)

SOA 模型将系统划分为一组松散耦合的服务组件,每个服务组件提供特定的业务功能支持,并通过标准协议在网络中进行通信。

这些服务应该做到自给自足,便于重复使用和扩展。

服务导向架构(SOA)促进了不同平台和技术之间的集成,但是由于服务的数量以及它们之间的相互依赖关系,因此管理起来可能会比较复杂。

微服务架构

微服务模式是SOA的发展,它将应用程序拆分成很多小型独立的服务,每个服务专注于特定的业务功能点。

这些微服务应该是可以独立部署和具备扩展能力的,从而实现更高的灵活性和更强的韧性。

此模式可以促进快速开发和迭代,并持续集成和部署,不过它需要仔细管理服务间的通信和依赖。

可组合的服务组件,简单来说就是...

The 可组合的服务 是微服务演化的结果,强调使用模块化且可重用的服务来构建应用,这些服务可以动态组合和配置,从而实现所需的功能。

这些服务旨在高度互操作性和自配置,以允许进行动态更新和扩展能力,支持动态且弹性的业务和运营需求。

这种模式可以促进灵活性和快速创新,因为服务可以混合和匹配以快速构建或调整功能,但需要谨慎的管理以确保服务之间的兼容性和整合。

每一种这些架构模式都提供了不同的优势和利弊,选择使用哪种模式取决于正在开发的系统的具体目标、复杂性和可扩展性需求。

几乎可以用这些模式中的任何一种组合来构建一个应用系统——尽管选择一个模式并将所有应用用例硬塞进它里面是一种过于常见的做法,这反而增加了复杂性,而不是减少了它。可组合的服务则不会遇到这个问题。

模块间的交流

在编程中,使用不同的范式来处理不同组件或系统之间的交互和通信。这里简要概述例如“过程调用(procedure call)”、“远程过程调用”、“消息传递(messaging)”和“事件发布(event publishing)”:

过程调用:(例如函数调用)

一个函数调用是调用同一程序或链接模块中的函数或过程的基本方式。这是直接调用的方式,调用代码执行该过程后,并在完成后可能返回一个值。

程序调用的工作原理是怎样的:

  • 程序中定义了一个函数或子程序。
  • 程序的另一部分或链接程序通过名称调用该过程,并传递必要的参数。
  • 控制流程传递给被调用的子程序。
  • 一旦子程序执行完毕,控制权返回给调用代码,可选地带有返回值。
远程过程调用 (RPC)

RPCs 将远程过程调用的概念扩展到了网络化和分布式系统中。一个 RPC 允许一个程序调用另一台机器或另一地址空间中的过程。

RPCs的工作方式是:

  • 客户端程序就像在本地调用一样进行调用,然而中间件实际上是在实现远程调用。
  • 然后调用通过网络发送到服务器。
  • 服务器执行该过程并返回结果给中间件。
  • 客户端接着收到结果并继续执行。
消息功能

消息通信指的是组件或系统通过消息进行的同步和异步通信。每个消息都是一种从一个组件发送至另一个组件的独立的数据单元。

消息传递是如何工作的

组件通过消息代理、编排器或队列来互相发送消息。

  • 发送组件将消息发送到协调器或队列。对于同步请求,响应由接收方发送。
  • 接收组件从代理或协调器接收消息——或从队列中取出消息并进行处理。
  • 发送方和接收方可以独立运行——既可以是同步也可以是异步——从而实现松散的耦合和可扩展性。
活动

组件通过发布事件来互相通信。事件最好被实现为一条消息,以代表系统中发生的重要的状态变化或所需的行动。其他感兴趣的组件可以订阅这些事件并作出相应的反应。

事件的工作原理是:

  • 例如,一个组件(发布者)检测到状态变化或需要采取的操作,并将事件发布到一个_话题_队列。
  • 比如,对该_话题_感兴趣的其他组件(订阅者)会轮询该_话题_队列,获取事件并作出反应。
  • 这样可以将发布者与订阅者解耦,使它们可以独立演化。
总结
  • 直接同步的过程调用:在同一程序或链接模块内的直接同步函数或子例程调用。
  • 远程过程调用 (RPC):通过网络扩展过程调用,允许一个系统上的函数调用另一个系统上的函数。
  • 消息传递机制:系统或组件之间通过消息代理、编排器或队列交换消息的同步和异步通信。
  • 事件模式:一种模式,其中更改或操作(事件)被广播,允许订阅这些事件的组件独立地作出反应。

每个范式有不同的用途,并适用于不同的架构需求。在一个应用程序系统中,可以使用多个通信范式,而且通常最好是使用多个。

编程范型

编程范式是一种根本的编程风格和方法,指导开发人员结构化和编写代码。它包括在编程语言中解决问题的概念、原则和实践。

不同的编程范式提供了不同的思考和组织程序的方法,每种范式都有其优点和缺点。我们来看看其中一些最常见的范式。

过程式编程

过程式编程是一种将代码组织成函数或子程序的编程范式,这些指令序列处理数据。

重点在于执行的动作顺序,程序一般通过一系列步骤来处理数据。这种做法对于那些需要按部就班完成的任务来说,既简单又容易理解。

  • 常用语言:C(C语言)、Pascal(Pascal语言)、Fortran(Fortran语言)
面向对象编程(OOP)

面向对象的编程 是一种以对象为中心的编程范式,对象是基于类的实例,封装了数据和行为。重点在于将应用程序实体建模为具有属性(即数据)和方法(即函数)的对象。

OOP推广诸如消息封装性,_多态性_和_继承_等原则,这些原则有助于通过创建可重用和模块化的组件来组织和管理复杂软件的结构。

  • 流行语言 :Java,Python,C++
函数式编程

函数式编程是一种将计算视为数学函数计算的编程风格,它强调不可变性、无状态性以及使用高阶函数。

程序是通过组合函数来构建的,避免改变状态和使用可变数据的方式,这有利于编写更可预测和可测试的代码。函数式编程鼓励使用声明式的风格,更注重做什么,而不是怎么去做。

  • 热门语言 :Haskell, Kotlin, Rust,

    这些编程范式提供了不同的方法来解决软件开发中的问题,过程导向的注重过程,对象导向的注重对象,而函数导向的则注重函数。

收尾

架构在处理软件复杂性上很重要——做好这一点还需要应用程序的利益相关者和开发人员之间保持良好沟通,使用相同语言也有帮助。

让我们知道你们觉得这篇文章有用,给它一个掌声,这样我们就能知道你们认为我们在正确的方向上。

谢谢!

如何正确构建架构:第二部分展示了我们如何使用精益架构方法和可组合的服务模块将多个架构和模块间通信模式的部分编织成一个高度功能化、性能优越、经济且能够快速响应客户不断变化的需求和反馈的系统。

推荐阅读:
点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消