【AICon】AI 基础设施、LLM运维、大模型训练与推理,一场会议,全方位涵盖! >>> 了解详情
写点什么

解耦应用与依赖注入框架

  • 2010-01-21
  • 本文字数:1685 字

    阅读完需:约 6 分钟

由于 SOA、TDD 等众多因素的影响,依赖注入已成为近年来广为接受的软件开发方法,随之而来的则是依赖注入框架的大量应用(尤其是最近 Java EE 6 所包含的依赖注入)。Bob Martin 则通过实例演示了一种解耦应用代码与依赖注入框架的方法。

Dependency Injection Inversion 这篇文章中,Bob 大叔总结到:

…我可不想让依赖注入框架的代码散布在我的应用当中。相反,我想解耦框架与我自己编写的代码。

为了阐述这个问题,Martin 给出了一个示例,该示例围绕着 BillingService 类的创建展开,该类的构造方法定义了如下依赖:

复制代码
public class BillingService {
...
BillingService(CreditCardProcessor processor, TransactionLog transactionLog) {
this.processor = processor;
this.transactionLog = transactionLog;
}
...
}

首先,Martin 使用 Guice (Google 推出的依赖注入框架)创建 BillingService 类的实例:

复制代码
public static void main(String[] args) {
Injector injector = Guice.createInjector(new BillingModule());
BillingService billingService = injector.getInstance(BillingService.class);
billingService.processCharge(2034, "Bob");
}

在解释完该段代码的一些细节后,Martin 给出这样一个事实:我们不得不显式地让 Guice 通过 injector 来创建 BillingService 的实例。这么做的结果就是:使用 BillingService 的代码不再依赖 BillingService 的依赖了(这很好),但却依赖 Guice 了。

是不是有利就有弊呢?Martin 的回答是肯定的:

依赖注入不过是依赖倒置(Dependency Inversion)的一个特殊情况而已。我认为依赖倒置非常重要,因此打算转换对 Guice 的依赖。我可不想让那么多的 Guice 依赖搞乱了我的代码。

之后,他向我们展示了如何通过工厂对象来控制并降低应用对 DI 框架的依赖:

复制代码
public static void main(String[] args) {
Injector injector = Guice.createInjector(new BillingModule());
BillingService.factory = new BillingServiceFactory(injector);
}
...
// Deep in the bowels of my system.
BillingService billingService = BillingService.factory.make();
billingService.processCharge(2034, "Bob");

为什么这种方式比较好呢,Martin 说到:

我喜欢这么做,因为现在所有的 Guice 代码都放在了同一个地方,而非散布在应用的各个角落,这是通过工厂实现的。不仅如此,如果将 Guice 替换成其他 DI 框架,我会明确知道需要修改哪些类以及如何修改他们。通过这种方式达到了应用与 Guice 解耦的目的。

要澄清的一点是:在所有的示例中,BillingService 本身都坚持着依赖注入原则,而 BillingService 到底使用的是依赖(CreditCardProcessor 及 TransactionLog)的何种实现其本身是不得而知的。为了说明这一点,他在文章的最后通过 JUnit 对 BillingService 进行了测试,在测试中仅仅使用了简单的 TransactionLog 和 CreditCardProcessor 实例对其进行注入,最后无论应用使用何种依赖注入手段,测试结果都是正确的。

Gary Bernhardt 就这个测试也给出了一篇文章,提到在Java 这种静态类型语言中这么做需要慎之又慎,但对于Python 之类的动态语言就无所谓了。

你是否使用依赖注入呢?是否使用DI 框架呢?不管答案如何,以上这种做法是否与你产生共鸣了呢?

查看英文原文: Decoupling Your Application From Your Dependency Injection Framework

有 InfoQ 读者对 Bob 大叔的这种做法提出了不同的观点:

来自 InfoQ 英文站的读者 monser corp 说到:

我想知道 Bob 大叔在过去几年编了多少代码?

恩,这是一种典型的”顾问式“做法:了解一项新技术,拿起来玩弄一下,然后发表在博客上来满足自己的虚荣心。在我做过的很多项目(使用了 Spring)中,只有一个类会依赖于 Spring:获取 Context 并启动应用。99.99% 的代码都不知道 Spring 或 Guice 是啥(如果不是使用了 Spring 的某些库的话,IoC 容器与 Log4J 根本就没啥区别)。如果真的想将代码与容器解耦,你需要重新考虑设计与实现,而非使用另一个工厂。

作为读者的您有何高见呢?这里,译者推荐您先去阅读 Bob 大叔的原文,然后将您的高见发表在这里。

2010-01-21 06:364107
用户头像

发布了 88 篇内容, 共 258.7 次阅读, 收获喜欢 8 次。

关注

评论

发布
暂无评论
发现更多内容

推荐系统-协同过滤在Spark中的实现

vivo互联网技术

spark 推荐系统 协同过滤

C# 类库的生成,使用类库对象对DataGridView 进行数据绑定

IC00

C# 7月月更

Linux常用命令

五分钟学大数据

Linux 7月月更

JAVA编程规范之SQL 语句

源字节1号

前端开发 后端开发

STM32+HC05串口蓝牙设计简易的蓝牙音箱

DS小龙哥

7月月更

只知道预制体是用来生成物体的?看我如何使用Unity生成UI预制体

恬静的小魔龙

游戏开发 Unity 游戏引擎

如何判断静态代码质量分析工具的性能?这五大因素必须考虑

龙智—DevSecOps解决方案

静态代码分析 代码静态分析 静态代码安全

大话DevOps监控,团队如何选择监控工具?

龙智—DevSecOps解决方案

DevOps 监控 监控软件

【龙智技术指南】Helix4Git简明使用手册

龙智—DevSecOps解决方案

Helix Core Helix4Git

常见WEB攻击与防御

南城FE

前端 WEB安全 7月月更

任何时间,任何地点,超级侦探,认真办案!

龙智—DevSecOps解决方案

Jira Atlassian Jira Jira插件

idea / eclipse 配置 Tomcat 并发布 Web 项目

攻城狮杰森

eclipse tomcat IDEA javaWeb 7月月更

游戏背包系统,“Inventory Pro插件”,研究学习-----妈妈再也不用担心我不会做背包了(Unity3D)

恬静的小魔龙

游戏开发 Unity 插件 游戏引擎

让运动自然发生,FITURE打造全新生活方式

科技热闻

Qt|QLable多行展示时更改行间距

中国好公民st

qt 7月月更

玩游戏想记录一下自己超神的瞬间?那么就来看一下如何使用Unity截图吧

恬静的小魔龙

游戏开发 Unity 游戏引擎

同事看了我的代码惊呼:居然是这么在Unity中用单例的

恬静的小魔龙

游戏开发 Unity 单例模式 游戏引擎

活动报名 | 玩转 Kubernetes 容器服务提高班正式开营!

阿里巴巴云原生

阿里云 容器 云原生 训练营 课程

擎创科技加入龙蜥社区,共建智能运维平台新生态

OpenAnolis小助手

开源 操作系统 龙蜥社区 CLA 擎创科技

用Unity不会几个插件怎么能行?Unity各类插件及教程推荐

恬静的小魔龙

游戏开发 Unity 插件 游戏引擎

语音聊天app源码-钠斯网络源码出品

开源直播系统源码

语聊房 直播系统源码 开源源码 语音聊天系统

Android内存溢出

沃德

android 7月月更

【策略模式】就像诸葛亮的锦囊

掘金安东尼

前端 设计模式 7月月更

【高并发】如何实现亿级流量下的分布式限流?这些理论你必须掌握!!

冰河

并发编程 多线程 高并发 协程 异步编程

【IJCAI 2022】参数高效的大模型稀疏训练方法,大幅减少稀疏训练所需资源

阿里云大数据AI技术

深度学习 模型稀疏训练

Qt | 鼠标事件和滚轮事件 QMouseEvent、QWheelEvent

YOLO.

qt 7月月更

异步Servlet在转转图片服务的实践

转转技术团队

Servlet 异步

QCon 大会广州站它来了!独家定制双肩背包等你领取!

InfoQ写作社区官方

Qcon

2022 年中回顾|一文看懂预训练模型最新进展

澜舟孟子开源社区

人工智能 自然语言处理 算法 nlp 预训练模型

我为OpenHarmony 写代码,战“码”先锋第二期正式开启!

OpenHarmony开发者

OpenHarmony

阿里云技术专家秦隆:可靠性保障必备——云上如何进行混沌工程

阿里云弹性计算

分布式系统 混沌工程 故障演练

解耦应用与依赖注入框架_Java_Mike Bria_InfoQ精选文章