写点什么

解耦应用与依赖注入框架

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

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

关注

评论

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

产教融合加速数据库人才培养 | OceanBase数据库大赛10强诞生

OceanBase 数据库

数据库 oceanbase 产教融合

[go] 后台管理数据权限控制实现 (无业务修改)

林逸民

迷宫问题java(DFS,回溯法,递归)

写代码两年半

DFS 迷宫 javase 回溯算法 6月月更

生态对对碰丨OceanBase如何与Prometheus与Grafana监控结合

OceanBase 数据库

Grafana Prometheus oceanbase

OceanBase 源码解读(十二):事务日志的提交和回放

OceanBase 数据库

oceanbase 源码解读

15 个用于创建漂亮图表的 JavaScript 库

devpoint

eCharts D3 plotly 图表库 6月月更

模块七:王者荣耀商城异地多活架构

jiaoxn

「架构实战营」

在 CloudIDE 里实现天猫精灵自定义技能的业务逻辑

汪子熙

人工智能 机器学习 机器人 Cloud 6月月更

linux之yum下载rpm包离线安装

入门小站

Linux

数据库每日一题---第1天:超过经理收入的员工

知心宝贝

数据库 算法 前端 后端 6月月更

UNet语义分割实战:使用UNet实现对人物的抠图

AI浩

图像分割 6月月更

生态对对碰丨详解 Flink CDC+OceanBase 全增量一体化数据集成方案

OceanBase 数据库

数据库 oceanbase Flink CDC

Docker下RabbitMQ延时队列实战两部曲之二:细说开发

程序员欣宸

Java RabbitMQ RabbitMQ延时队列 6月月更

SDN系统方法 | 2. 用例

俞凡

架构 网络 sdn SDN系统方法

云原生之 Ansible 篇(一)

看,未来

云原生

透过华为军团看科技之变(一):广域网络

脑极体

【愚公系列】2022年06月 二十三种设计模式(二十一)-策略模式(Stragety Pattern)

愚公搬代码

6月月更

[ Kitex 源码解读 ] 代码解读思路的总结

baiyutang

字节跳动 微服务 kitex 6月月更

C#入门系列(三) -- 数据类型

陈言必行

C# 6月月更

Javascript中的垃圾回收

大熊G

JavaScript 前端 6月月更

ElasticSearch部署架构和容量规划

IT巅峰技术

Python爬虫基础-requests模块-1

zyf

6月月更

云原生之 Ansible 篇(二)

看,未来

云原生

OceanBase 源码解读(十四):集群位置信息的存储与汇报

OceanBase 数据库

数据库 oceanbase 集群位置信息

Fabric.js 上标和下标的使用偏方🔥

德育处主任

Web canvas 前端可视化 Fabric.js 6月月更

SpringBoot下用Kyro作为Redis序列化工具

程序员欣宸

Java 6月月更 Kyro

Flutter使用自定义字体

坚果

6月月更

【LeetCode】统计一个数组中好对子的数目Java题解

Albert

LeetCode 6月月更

模块7作业

KennyQ

InfoQ 极客传媒 15 周年庆征文|分布式系统解决之道:目录、消息队列、事务系统及其他

No Silver Bullet

分布式系统 消息队列 6月月更 事务系统 InfoQ极客传媒15周年庆

共享主机和 WordPress 主机之间的区别

海拥(haiyong.site)

6月月更

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