写点什么

解耦应用与依赖注入框架

  • 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:364222
用户头像

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

关注

评论

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

Principle for Mac(交互式原型设计工具) v6.29.6免激活版

真大的脸盆

Mac 交互设计 Mac 软件 交互式产品原型设计工具

数据散,管理难,制造企业如何走出数字化转型困局

科技怪授

华为云

商业智能公厕系统

光明源智慧厕所

智慧城市

使用卷积神经网络实现图片去摩尔纹

华为云开发者联盟

人工智能 华为云 华为云开发者联盟 企业号 3 月 PK 榜

华为云时习知助力华为终端全球零售门店,打造数字化人才培养最佳实践

科技怪授

华为云

谁能真正替代你?AI辅助编码工具深度对比(chatGPT/Copilot/Cursor/New Bing)

Zhendong

GitHub ChatGPT New Bing Copilot

极光笔记 | 如何在Shopify中使用Engagelab(上)

极光JIGUANG

市场营销 邮件发送 用户运营

跨越前后端排障鸿沟,精准排障,让IT人员不“撕逼”

嘉为蓝鲸

告警 后端技术 IT 运维

嘉为蓝鲸研发运营一体化解决方案入选金融信创优秀解决方案

嘉为蓝鲸

金融 解决方案 一体化

云服务过载控制的前世今生

华为云开发者联盟

云计算 后端 华为云 华为云开发者联盟 企业号 3 月 PK 榜

在Github上标星103K爆火的Spring Security手册及源码笔记,YYDS

程序知音

Java spring security Java进阶 后端技术 java 架构

Qualcomm QCA9880 MAXON MX530VX MIMO Mini PCIE WiFi5 Module

MAXON

QCA9880

Whats's New In Seata 1.6.x

阿里巴巴云原生

阿里云 开源 云原生 seata

如何构建用户体验优化体系?

嘉为蓝鲸

IT运维 用户体验设计 用户体验分析

MobTech MobPush|用户行为分析

MobTech袤博科技

拒绝“爆雷”!GaussDB(for MySQL)新上线了这个功能

华为云开发者联盟

数据库 后端 华为云 华为云开发者联盟 企业号 3 月 PK 榜

护航应用的“全科医生”,神州云科亮相四川卫生健康信息技术交流大会

通明湖

在 Rainbond 上使用 Curve 云原生存储

北京好雨科技有限公司

云原生 kubernete 分布式存储 rainbond

OceanBase大事记(2023年3月)

OceanBase 数据库

数据库 oceanbase

作业帮基于明道云开展的硬件业务数字化建设

明道云

直播预约 | 邀您共同探讨虚拟数字人如何赋能教育信息化创新发展

3DCAT实时渲染

数字人 实时云渲染 虚拟数字人

一份GitHub star过万的1121页图解算法让“他”成功杀进字节跳动

程序知音

Java 算法 编程语言 后端技术

低代码平台助力AIGC:让人工智能技术更加普及和高效

加入高科技仿生人

人工智能 低代码 AIGC 人工智能技术

MobTech SMSSDK|短信验证服务

MobTech袤博科技

直播揭秘,人人都在聊的AI技能究竟怎么学?

科技热闻

Nexus3 环境配置

流火

nexus3 群晖 maven私服

玩转 ChatGPT+极狐GitLab|自动化的MR 变更评审来了

极狐GitLab

DevOps Code Review 极狐GitLab 代码合并 ChatGPT

编码的未来是根本不需要编码

引迈信息

前端 低代码 JNPF

浅谈开源测试平台RunnerGo的使用体验

爱研究代码的极客人

软件测试 Jmeter 性能测试 压力测试 runnergo

中小企业上云如何降本增效,开年采购不容错过!

科技怪授

华为云

华为工单宝:制造业数字化转型利器,项目管理助力售后服务自动化

科技怪授

华为云

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