解耦的艺术_应用架构中的解耦

news/2025/2/24 18:03:09

文章目录


在这里插入图片描述

Pre

解耦的艺术_通过DPI依赖倒置实现解耦

解耦的艺术_通过中间层映射实现解耦


解耦的技术演化

技术的演化史,也是一部解耦的历史。从最初的面向对象编程(OOP)到Spring框架的依赖注入,再到分布式架构中的微服务,技术的每一次进步都伴随着解耦的推进。

  • 原始社会:最初的编程往往是“高耦合”的,创建对象的过程没有解耦机制,每个对象都由开发人员手动管理。

    UserService userService = new UserService(); // 直接依赖UserService
    
  • 工业社会:随着工厂模式(Factory Pattern)的引入,开发人员不再自己创建对象,而是通过工厂来进行管理,帮助我们将对象的创建和使用分离,完成了初步的解耦

    UserServiceFactory factory = new UserServiceFactory();
    UserService userService = factory.createUserService();
    
  • 共产主义社会:随着依赖注入(DI)技术的普及,特别是Spring框架的引入,解耦进一步得到提升。应用不再关心如何创建对象,而是通过依赖注入由框架自动管理对象的生命周期和依赖关系

    @Service
    	public class BusinessService {
    	    @Autowired
    	    private UserService userService;
    	    
    	    // 业务逻辑...
    	}
    
  • 分布式时代:随着分布式系统的崛起,RPC技术解决了系统之间的通信问题,但仍面临着技术依赖的问题。Web Service和RESTful架构的出现,则进一步降低了分布式系统中的耦合度,支持平台无关和语言无关的服务调用。


应用架构中的解耦

Robert C.Martin在其博客文章“The Clean Architecture”中提出的观点:应用架构之道,就是要实现业务逻辑和技术细节的解耦

不管是六边形架构、洋葱圈架构,还是COLA架构,其核心要义都是做核心业务逻辑和技术细节的分离和解耦

试想,如果业务逻辑和技术细节杂糅在一起,将所有的代码都写在ServiceImpl中,前几行代码负责validation,接下来几行代码负责convert,然后是几行业务逻辑代码,之后我们需要通过RPC或DAO获取更多的数据,拿到数据后,又是几行convert的代码,再接上一段业务逻辑代码,最后还要落库、发消息,等等。按照上面这种写代码的方式,再简单的业务都会变得复杂且难以维护

COLA 1.0

在这里插入图片描述
让领域层(Domain Layer)对基础设施层(Infrastructure Layer)进行直接依赖比较方便,而且似乎也没什么大问题.

然而实际上,这种“偷懒”的行为有悖于框架设计的初衷,因为在设计之初,我们就希望领域层是应用的核心,类似于洋葱圈架构所提倡的——让领域层处于架构的中心位置,即洋葱圈最核心的部分。也就是说,领域层不应该依赖基础设施层,相反地,应该让基础设施层依赖于领域层。

如果让领域层依赖基础设施层,会“污染”领域层的纯粹性,影响其独立性和可测试性。也就是说,层次之间不再是正交的了,基础设施层的任何变动都可能影响到领域层,而这不是我们想看到的。

COLA 2.0

COLA 2.0时,特意使用依赖倒置反转了领域层和基础设施层的依赖关系.

在这里插入图片描述
COLA 2.0的核心变化是领域层不再直接依赖基础设施层,而是通过一个新的抽象Gateway(网关)对领域层和基础设施层进行了解耦,这两个层次不再彼此依赖、彼此耦合,而是都依赖于Gateway .

举个例子,假如某个应用中需要用到类目(Category)这个实体,但是类目又不在本域中,需要通过一个RPC调用才能获取相应的信息。那么这时我们就可以在领域层中定义一个类目网关(CategoryGateway),这是一个纯抽象的概念

public interface CategoryGateway{
	Category getCategoryById(Long categoryId);

}

这个抽象相当于告诉基础设施层:你需要按照这个接口来提供数据。至于这个数据是如何被获取、被组装、被转换的,都是基础设施层需要关心的事情,不再需要领域层去关心.

综上,通过依赖倒置方式,我们倒置了领域层和基础设施层的依赖关系,让两个模块从原来的依赖关系变成了正交关系,两者可以独立地改动和变化,而不会影响到另一方。

例如,要想让类目信息的获取从RPC变成本地数据库调用,那么我们只需要修改基础设施层的代码即可,领域层可以完全不动。同理,如果在领域层有关于类目的业务变化,比如原来需要通过三级类目去判断同类品的逻辑,现在要放宽到二级类目,这种变化也不会影响到基础设施层的代码


小结

  • “高内聚、低耦合”是软件设计追求的重要目标之一,组件、模块、层次设计都应该遵循“高内聚、低耦合”的设计原则。
  • 正交的关键在于如何识别耦合性,我们可以通过识别系统需要扩展的地方来识别耦合性。比如,关于配置系统的设计不应该耦合于某一种特定的实现方式,而是应该更灵活一些。
  • 解耦主要有依赖倒置和中间层映射两种方式。
  • 我们要尽可能多地依赖抽象而不是具体,这能使系统更灵活,这种编程方式也叫作面向接口编程。
  • “计算机中的任何问题,都可以通过加一层来解决”,中间层的价值也在于解耦

在这里插入图片描述


http://www.niftyadmin.cn/n/5864684.html

相关文章

API接口设计模式:从分层架构到CQRS的实战应用

以下将从分层架构和 CQRS(命令查询职责分离)的基本概念入手,为你阐述从分层架构到 CQRS 的实战应用相关内容: 分层架构 概念:分层架构是将系统按照功能划分为不同的层次,每个层次负责特定的职责&#xff0c…

【HarmonyOS Next】拒绝权限二次申请授权处理

【HarmonyOS Next】拒绝权限二次申请授权处理 一、问题背景: 在鸿蒙系统中,对于用户权限的申请,会有三种用户选择方式: 1.单次使用允许 2.使用应用期间(长时)允许 3.不允许 当用户选择不允许后&#xff0…

Java还是网络安全 java 网络安全面试题

🍅 点击文末小卡片 ,免费获取网络安全全套资料,资料在手,涨薪更快 1.网络七层协议 第一层:物理层 机械、电子、定时接口通信信道上的原始比特流传输 第二层:数据链路层 物理寻址,同时将原始比特…

谷歌浏览器更新后导致的刷新数据无法显示

这几天突然出现的问题,就是我做了一个网站,一直用Google展示,前两天突然就是刷新会丢失数据,然后再刷新几次吧又有了,之前一直好好的,后端也做了一些配置添加了CrossOrigin注解,然而换了edge浏览…

文档检索服务平台

文档检索服务平台是基于Elasticsearch的全文检索,包含数据采集、数据清洗、数据转换、数据检索等模块。 项目地址:Github、国内Gitee 演示地址:http://silianpan.cn/gdss/ 以下是演示角色和账号(密码同账号)&#xf…

【quicker】调节PPT指定字号字体大小/快速调节WPS的PPT字体大小

在quicker的拓展动作中找不到直接指定字号大小方式的动作。 换个思路,既然无法通过alt键模拟,不如模拟右键菜单触发?尝试过失败了 所以有了第三种方法 ,首先给字体窗口设置快捷键,此处设置的是altshiftf,然…

接雨水的算法

题目 代码 # 接雨水算法 def trap(height):# 1. 特殊情况:数组为空 则返回0if not height:return 0n len(height)# 2. 初始化左右指针,左右最大值,结果left, right 0, n - 1# maxleft代表左边最大值,maxright代表右边最大值max…

Ubuntu22.04 - brpc的安装和使用

目录 介绍安装使用 介绍 brpc 是用 c语言编写的工业级 RPC 框架,常用于搜索、存储、机器学习、广告、推荐等高性能系统 安装 先安装依赖 apt-get install -y git g make libssl-dev libprotobuf-dev libprotoc-dev protobuf-compiler libleveldb-dev libgflags-d…