热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

快速概览软件架构风格:从历史到现代的全面总结与分析

每个软件项目都是不同的,但这并不意味着我们没有可以挑选的趋势。大泥球(BigBallofMud)当您不选择架构时,您最终会得到BigBallofMud

每个软件项目都是不同的,但这并不意味着我们没有可以挑选的趋势。

大泥球(Big Ball of Mud)

当您不选择架构时,您最终会得到 "Big Ball of Mud" 架构。泥泞的“大球”是指从一个没有计划如何构建他们的解决方案的团队中出现的非结构化的意大利面条式代码库。

ea8de2e38110c1b189f39137387c3f7c.png

Big Ball of Mud 的名字来源于无组织的耦合和调用模式的网络,这些模式代表了没有清晰架构的项目.

分层架构

最简单和最常见的架构风格之一是分层架构。代码按技术领域划分为离散层。这清楚地表明了代码所属的位置。

d6a5a1367dbbdb76be884958b898f26c.png

将代码库典型地分解为层
一个典型的规则是每一层都是封闭的,这意味着它只能被它旁边的层访问,这有助于防止耦合。每一层都可以作为一个整体部署在一起,也可以单独部署。通常,表示层(UI)和数据库将分别部署到代码的其余部分。

管道架构

b3e94b278a78dc2315de0e75c0446d78.png

流水线架构以两种类型的单元为中心;管道和过滤器:

过滤器是独立的无状态计算单元。他们应该专注于完成一项特定任务。过滤器可以生成、测试、转换或使用数据。

管道是过滤器之间的通信通道。它们是一种方式,用于从过滤器构建管道。

微内核架构(插件架构)

82e9c575f902cd9e3a19af0b87793503.png

微内核架构基于构建核心系统的想法,该系统包含系统完成其核心目的所需的最少功能。然后通过独立插件提供附加功能。想想 VS Code:基本应用程序非常有限,但通过添加插件,您可以使应用程序非常强大,并为您和您的项目量身定制。

通常,插件彼此隔离,因此彼此分离。他们也有独立的存储。插件可以是具有核心系统的单体的一部分,也可以单独部署。如果与插件的通信是通过某种标准化形式的消息(如 REST)完成的,则无需要求所有内容都使用相同的语言编写。

基于服务的架构

966a1b565c5ee03f6ef5c44fc7a10e0f.png

在此体系结构中,功能由基于域的服务划分。该服务可以共享数据库和用户界面,但彼此独立运行。

服务可以相互独立部署。可以为需求较高的服务提供更多资源或进行复制。还可能有一个 API 代理将请求从 UI 路由到正确的服务。

事件驱动架构

0567a18564479a8cfe7abf0e0e784f7f.png

事件驱动系统对用户界面或内部发生的事件做出“反应”。这种系统是由事件处理器构建的;小的独立计算单元。通过系统的事件流可以以两种不同的方式发生。

在代理拓扑下,没有对事件处理的集中控制。每个处理器都可以广播自己的事件以触发另一个处理器形成事件链。不需要管理特定事件处理器或执行步骤之间的连接。

4686263b0ad9e12f4ca7a33ccf2e5588.png

在中介拓扑下有一些中央控制。事件调解器控制调用哪些处理器以及事件进入系统时的顺序。可能有多个事件中介以并行或分层方式工作。

微服务架构

8804f50d21e52ca980ce4f16a0079d6b.png

微服务系统由许多可独立部署的、以领域为中心的服务构建而成。“微”来自于每个服务应该只专注于完成一项任务的事实。微服务通常使用 REST 之类的东西(可能通过 API 网关)进行通信,用不同的语言编写并具有独立的存储。

微服务通常是独立部署的。这是一个“云原生”架构,它使用弹性来提供性能和可用性。

Clean Architecture

  • 域层:实体+用例+网关协议

  • 数据层:网关实现+ API(网络)+数据库

  • 表示层:视图模型+视图+导航器+场景用例

3755626b543e027b1e73dea9137c27eb.png

510c3087bcd43e456c0bfdd8140d8c76.png


26d2c7c0a229ed60f2c366c949595408.png


f67bd3135d9e5ca9333ca4ccff3b38b5.png

实体

实体封装了企业范围内的关键业务规则。实体可以是带有方法的对象,也可以是一组数据结构和函数。只要实体可以被企业中的许多不同应用程序使用,都没有关系。-清洁架构:软件结构和设计手工艺指南(Robert C. Martin)

实体是简单的数据结构:

struct Repo {var id = 0var name = ""var fullname = ""var urlString = ""var starCount = 0var folkCount = 0var avatarURLString = ""
}

用例

用例层中的软件包含特定于应用程序的业务规则。它封装并实现了系统的所有用例。这些用例协调了进出实体的数据流,并指示这些实体使用其关键业务规则来实现用例的目标。-清洁架构:软件结构和设计手工艺指南(Robert C. Martin)

UseCases是执行一项特定操作的协议:

protocol GettingRepos {var repoGateway: RepoGatewayType { get }
}extension GettingRepos {func getRepos(_ dto: GetPageDto) -> Observable> {repoGateway.getRepos(dto)}
}

数据传输对象-DTO

DTO-在进程之间传送数据的对象,它还执行数据验证:

struct LoginDto: Dto {@Validated(.nonEmpty(message: "Please enter user name"))var username: String?@Validated(.nonEmpty(message: "Please enter password"))var password: String?var validatedProperties: [ValidatedProperty] {return [_username, _password]}init(username: String, password: String) {self.username = usernameself.password = password}init() { }static func validateUserName(_ username: String) -> Result {LoginDto()._username.isValid(value: username)}static func validatePassword(_ password: String) -> Result {LoginDto()._password.isValid(value: password)}
}

网关协议

通常,网关只是另一个抽象,它将隐藏实际的实现,类似于外观模式。它可以是数据存储(存储库模式),API网关等。例如数据库网关将具有满足应用程序需求的方法。但是,请勿尝试在此类网关后面隐藏复杂的业务规则。对数据库的所有查询都应相对简单一些,例如CRUD操作,当然也可以接受一些过滤。-来源

protocol RepoGatewayType {func getRepos(_ dto: GetPageDto) -> Observable>
}

注意:为简单起见,我们将网关协议和实现放在同一文件中。实际上,网关协议应该在域层,实现应该在数据层。

资料层

f97fe90406e0424e72816d1ecf8323fa.png

数据层包含网关实现和一个或多个数据存储。网关负责协调来自不同数据存储的数据。数据存储可以是远程或本地(例如,持久数据库)。数据层仅取决于域层。

参考资料

https://blog.devgenius.io/some-software-architecture-styles-fbb57f7716b9

https://www.nuomiphp.com/github/zh/5fdc441a99daa46c1242dceb.html


推荐阅读
  • Ralph的Kubernetes进阶之旅:集群架构与对象解析
    本文深入探讨了Kubernetes集群的架构和核心对象,详细介绍了Pod、Service、Volume等基本组件,以及更高层次的抽象如Deployment、StatefulSet等,帮助读者全面理解Kubernetes的工作原理。 ... [详细]
  • 本文详细探讨了JDBC(Java数据库连接)的内部机制,重点分析其作为服务提供者接口(SPI)框架的应用。通过类图和代码示例,展示了JDBC如何注册驱动程序、建立数据库连接以及执行SQL查询的过程。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 数据管理权威指南:《DAMA-DMBOK2 数据管理知识体系》
    本书提供了全面的数据管理职能、术语和最佳实践方法的标准行业解释,构建了数据管理的总体框架,为数据管理的发展奠定了坚实的理论基础。适合各类数据管理专业人士和相关领域的从业人员。 ... [详细]
  • 本文详细介绍了macOS系统的核心组件,包括如何管理其安全特性——系统完整性保护(SIP),并探讨了不同版本的更新亮点。对于使用macOS系统的用户来说,了解这些信息有助于更好地管理和优化系统性能。 ... [详细]
  • 使用Python在SAE上开发新浪微博应用的初步探索
    最近重新审视了新浪云平台(SAE)提供的服务,发现其已支持Python开发。本文将详细介绍如何利用Django框架构建一个简单的新浪微博应用,并分享开发过程中的关键步骤。 ... [详细]
  • MySQL 数据库迁移指南:从本地到远程及磁盘间迁移
    本文详细介绍了如何在不同场景下进行 MySQL 数据库的迁移,包括从一个硬盘迁移到另一个硬盘、从一台计算机迁移到另一台计算机,以及解决迁移过程中可能遇到的问题。 ... [详细]
  • Scala 实现 UTF-8 编码属性文件读取与克隆
    本文介绍如何使用 Scala 以 UTF-8 编码方式读取属性文件,并实现属性文件的克隆功能。通过这种方式,可以确保配置文件在多线程环境下的一致性和高效性。 ... [详细]
  • 深入探讨CPU虚拟化与KVM内存管理
    本文详细介绍了现代服务器架构中的CPU虚拟化技术,包括SMP、NUMA和MPP三种多处理器结构,并深入探讨了KVM的内存虚拟化机制。通过对比不同架构的特点和应用场景,帮助读者理解如何选择最适合的架构以优化性能。 ... [详细]
  • 本文详细介绍如何使用Python进行配置文件的读写操作,涵盖常见的配置文件格式(如INI、JSON、TOML和YAML),并提供具体的代码示例。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 使用 Azure Service Principal 和 Microsoft Graph API 获取 AAD 用户列表
    本文介绍了一段通用代码示例,该代码不仅能够操作 Azure Active Directory (AAD),还可以通过 Azure Service Principal 的授权访问和管理 Azure 订阅资源。Azure 的架构可以分为两个层级:AAD 和 Subscription。 ... [详细]
  • 如何配置Unturned服务器及其消息设置
    本文详细介绍了Unturned服务器的配置方法和消息设置技巧,帮助用户了解并优化服务器管理。同时,提供了关于云服务资源操作记录、远程登录设置以及文件传输的相关补充信息。 ... [详细]
  • 在当前众多持久层框架中,MyBatis(前身为iBatis)凭借其轻量级、易用性和对SQL的直接支持,成为许多开发者的首选。本文将详细探讨MyBatis的核心概念、设计理念及其优势。 ... [详细]
  • UNP 第9章:主机名与地址转换
    本章探讨了用于在主机名和数值地址之间进行转换的函数,如gethostbyname和gethostbyaddr。此外,还介绍了getservbyname和getservbyport函数,用于在服务器名和端口号之间进行转换。 ... [详细]
author-avatar
伤心怪人_234
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有