如何正确地理解应用架构并开发(上)

简介: 如何正确地理解应用架构并开发(上)




许多同学或多或少都经历过这样的流程:

  1. 新同学刚来公司,学习了解团队的一些工程代码,并了解其中的代码风格
  2. 团队新接手了一些其他团队的项目,需要了解工程结构以及概念
  3. 如何定义工程项目的工程结构,包目录结构并达成团队共识

如果你有上述经历,并对工程应用之中的Module划分及其背后的意义理解上存在一些困扰, 那本文对你或许会有一些帮助。


理解代码从理解应用架构开始


应用架构

 混乱的应用架构


最近看了一些业务工程的代码,发现业务系统非常混乱,混乱主要体现在:

  1. 应用的层次结构混乱:不知道应用应该如何分层、应该包含哪些组件、组件之间的关系是什么
  2. 缺少规范的指导和约束:新加一段业务逻辑不知道放在什么地方(哪个类,哪个包)、应该起什么名字比较合适
  3. 每个工程的Module数量不一样,Module的命名和定义不一样,不同的Module之间的依赖关系混乱(延伸下就是:Module和Package的作用不清晰,不能很好的区分两者之间的区别


但有一个共同点就是都很复杂。导致复杂性的原因有很多,如果从架构的层面看,主要有两点:

  1. 架构设计过于复杂,层次太多能把人绕晕。
  2. 架构简单,ServiceImpl作为上帝类包揽一切,一杆捅到DAO(就简单场景而言,这种Transaction Script也还凑合,至少实现上手都快。


这种人为的复杂性导致系统越来越臃肿,越来越难维护,新来的同学,往往要捂着鼻子抠几天甚至几个月,才能理清系统和业务脉络,然后又一头扎进各种bug fix,业务修补的恶性循环中,暗无天日!

(Transaction Script地址:https://martinfowler.com/eaaCatalog/transactionScript.html


 有序的应用架构


一个没有架构的应用系统,就像一堆随意堆放、杂乱无章的玩具,只有熵值,没有熵减。而一个有良好架构的应用系统,有章法、有结构,一切都显得井井有条。

好的组织架构会遵循一定的架构模式,大部分的组织都会按职能和业务来设计自己的架构。如果你反其道而行之,硬要把销售、财务和技术人员放在一个部门,就会显得很奇怪。


对于应用架构而言,代码是其核心组成要素,结构就是这些代码该如何被组织,也就是要如何处理模块(Module)包(Package)类(Class)之间的关系。简而言之,应用架构就是要解决代码要如何被组织的问题。


 包和模块之间的区别


包和模块这两个概念是比较容易发生混淆的。比如在《实现领域驱动设计》中,作者就说:If you are using Java or C#, you are already familiar with Modules, though you know them by another name. Java calls them packages. C# calls them namespaces.他认为Module是Package,这个定义容易造成混淆。特别是在使用Maven的时候,在Maven中,Module是一个Artifact,通常是一个Jar而不是Package。比如NBF-Falcon Framework基础类型的工程就包括如下3个Module:


<modules>
    <module>{应用Code}-api</module>
    <module>{应用Code}-service</module>
    <module>{应用Code}-start</module>
</modules>


的确,Module和Component这两个概念很相近,很容易造成混淆。比如,在StackOverflow上有一个提问,就是问Module和Component之间区别的。获得最高赞的答案是通过Scope来区分的。The terms are similar. I generally think of a "module" as being larger than a "component". A component is a single part, usually relatively small in scope.「这两个概念类似,我通常认为“模块”比“组件”更大。组件是一个单独的部分,通常范围相对较小。」(StackOverflow地址:https://softwareengineering.stackexchange.com/questions/178927/is-there-a-difference-between-a-component-and-a-module?spm=ata.21736010.0.0.48807536xgth68

这个回答和我的直觉反应是一致的,即Module比Package要大。根据以上信息,我在此对Module和Package进行一下定义说明,在本文中,都会遵照如下的定义。- 模块(Module):和Maven中Module定义保持一致,简单理解就是Jar。- 包(Package):和UML中的定义类似,简单理解就是一个文件夹。
一个Moudle通常是由多个Package组成的,其关系如下图所示:


 典型的业务系统


典型的业务系统都需要:

  1. 接收request,响应response;
  2. 做业务逻辑处理,像校验参数,状态流转,业务计算等等;
  3. 和外部系统有联动,像数据库,微服务,搜索引擎等;

如何正确的组织这些业务代码,让他们处于自身该存在的位置,就是我们今天要聊的话题。


常见的工程结构(理论部分)


同样,好的应用架构,不管是六边形架构、洋葱圈架构、整洁架构等,都提倡以业务为核心,解耦外部依赖,分离业务复杂度和技术复杂度

简单理解下业务复杂度和技术复杂度的概念: 对于一个最简单的钱包扣钱的user case来说 业务复杂度:钱包扣钱时的规则(eg:不能扣成负值)就是业务复杂度 技术复杂度:钱包最终是如何存储的,是用mysql还是lindorm

应用架构的本质(核心),就是要从繁杂的业务系统中提炼出共性,找到解决业务问题的最佳共同模式,为开发人员提供统一的认知,治理混乱。帮助应用系统“从混乱到有序”,物流技术部的工程脚手架就是为此而生,其核心职责就是定义良好的应用结构,提供最佳实践。


 分层模式


分层是一种常见的根据系统中的角色(职责拆分)和组织代码单元的常规实践。常见的分层结构如下图所示:


 CQRS模式(命令和查询责任分离)


CQRS(Command Query Rsponsibility Segregation,命令查询分离)


其基本思想在于,任何一个对象的方法可以分为两大类:* 命令(Command):不返回任何结果(void),但会改变对象的状态。* 查询(Query):返回结果,但是不会改变对象的状态,对系统没有副作用。




 六边形架构


六边形架构是Alistair Cockburn在2005年提出,解决了传统的分层结构所带来的问题,实际上它也是一种分层架构,只不过不是上下,而是变成了内部和外部(如下图所示)。


六边形架构又称为端口-适配器架构,这个名字更容器理解。六边形架构将系统分为内部(内部六边形)和外部,内部代表了应用的业务逻辑,外部代表应用的驱动逻辑、基础设施或其他应用。


适配器分为两种类型(如下图所示),左侧代表 UI 的适配器被称为主动适配器(Driving Adapters),因为是它们发起了对应用的一些操作。而右侧表示和后端工具链接的适配器,被称为被动适配器(Driven Adapters),因为它们只会对主适配器的操作作出响应。

 洋葱圈架构


洋葱架构与六边形架构有着相同的思路,它们都通过编写适配器代码将应用核心从对基础设施的关注中解放出来,避免基础设施代码渗透到应用核心之中。这样应用使用的工具和传达机制都可以轻松地替换,可以一定程度地避免技术、工具或者供应商锁定。


不同的是洋葱架构还告诉我们,企业应用中存在着不止两个层次,它在业务逻辑中加入了一些在领域驱动设计的过程中被识别出来的层次(Application,Domain Service,Domain model,Infrastructure等)


另外,它还有着脱离真实基础设施和传达机制应用仍然可以运行的便利,这样可以使用 mock 代替它们方便测试。


在洋葱架构中,明确规定了依赖的方向:

  1. 外层依赖内层;
  2. 内层对外层无感知。



如何正确地理解应用架构并开发(中):https://developer.aliyun.com/article/1443482

目录
相关文章
|
7天前
|
监控 Go API
Go语言在微服务架构中的应用实践
在微服务架构的浪潮中,Go语言以其简洁、高效和并发处理能力脱颖而出,成为构建微服务的理想选择。本文将探讨Go语言在微服务架构中的应用实践,包括Go语言的特性如何适应微服务架构的需求,以及在实际开发中如何利用Go语言的特性来提高服务的性能和可维护性。我们将通过一个具体的案例分析,展示Go语言在微服务开发中的优势,并讨论在实际应用中可能遇到的挑战和解决方案。
|
7天前
|
网络协议 数据挖掘 5G
适用于金融和交易应用的低延迟网络:技术、架构与应用
适用于金融和交易应用的低延迟网络:技术、架构与应用
33 5
|
8天前
|
Go 数据处理 API
Go语言在微服务架构中的应用与优势
本文摘要采用问答形式,以期提供更直接的信息获取方式。 Q1: 为什么选择Go语言进行微服务开发? A1: Go语言的并发模型、简洁的语法和高效的编译速度使其成为微服务架构的理想选择。 Q2: Go语言在微服务架构中有哪些优势? A2: 主要优势包括高性能、高并发处理能力、简洁的代码和强大的标准库。 Q3: 文章将如何展示Go语言在微服务中的应用? A3: 通过对比其他语言和展示Go语言在实际项目中的应用案例,来说明其在微服务架构中的优势。
|
6天前
|
监控 持续交付 Docker
Docker 容器化部署在微服务架构中的应用有哪些?
Docker 容器化部署在微服务架构中的应用有哪些?
|
6天前
|
监控 持续交付 Docker
Docker容器化部署在微服务架构中的应用
Docker容器化部署在微服务架构中的应用
|
8天前
|
监控 API 持续交付
后端开发中的微服务架构实践与挑战####
本文深入探讨了微服务架构在后端开发中的应用,分析了其优势、面临的挑战以及最佳实践策略。不同于传统的单体应用,微服务通过细粒度的服务划分促进了系统的可维护性、可扩展性和敏捷性。文章首先概述了微服务的核心概念及其与传统架构的区别,随后详细阐述了构建微服务时需考虑的关键技术要素,如服务发现、API网关、容器化部署及持续集成/持续部署(CI/CD)流程。此外,还讨论了微服务实施过程中常见的问题,如服务间通信复杂度增加、数据一致性保障等,并提供了相应的解决方案和优化建议。总之,本文旨在为开发者提供一份关于如何在现代后端系统中有效采用和优化微服务架构的实用指南。 ####
|
10天前
|
消息中间件 设计模式 运维
后端开发中的微服务架构实践与挑战####
本文深入探讨了微服务架构在现代后端开发中的应用,通过实际案例分析,揭示了其在提升系统灵活性、可扩展性及促进技术创新方面的显著优势。同时,文章也未回避微服务实施过程中面临的挑战,如服务间通信复杂性、数据一致性保障及部署运维难度增加等问题,并基于实践经验提出了一系列应对策略,为开发者在构建高效、稳定的微服务平台时提供有价值的参考。 ####
|
10天前
|
消息中间件 监控 数据管理
后端开发中的微服务架构实践与挑战####
【10月更文挑战第29天】 在当今快速发展的软件开发领域,微服务架构已成为构建高效、可扩展和易于维护应用程序的首选方案。本文探讨了微服务架构的核心概念、实施策略以及面临的主要挑战,旨在为开发者提供一份实用的指南,帮助他们在项目中成功应用微服务架构。通过具体案例分析,我们将深入了解如何克服服务划分、数据管理、通信机制等关键问题,以实现系统的高可用性和高性能。 --- ###
33 2
|
14天前
|
机器学习/深度学习 人工智能 自然语言处理
医疗行业的语音识别技术解析:AI多模态能力平台的应用与架构
AI多模态能力平台通过语音识别技术,实现实时转录医患对话,自动生成结构化数据,提高医疗效率。平台具备强大的环境降噪、语音分离及自然语言处理能力,支持与医院系统无缝集成,广泛应用于门诊记录、多学科会诊和急诊场景,显著提升工作效率和数据准确性。
|
6天前
|
缓存 负载均衡 JavaScript
探索微服务架构下的API网关模式
【10月更文挑战第37天】在微服务架构的海洋中,API网关犹如一座灯塔,指引着服务的航向。它不仅是客户端请求的集散地,更是后端微服务的守门人。本文将深入探讨API网关的设计哲学、核心功能以及它在微服务生态中扮演的角色,同时通过实际代码示例,揭示如何实现一个高效、可靠的API网关。