文章目录
【Java设计模式】依赖注入模式:通过松耦合提升可维护性
一、概述
依赖注入设计模式的目的是将对象依赖的创建与其使用解耦,从而实现更灵活和可测试的代码。
二、详细解释及实际示例
- 实际示例:
- 想象一家高档餐厅,厨师需要各种食材来准备菜肴。厨师不是亲自去不同的供应商那里获取每种食材,而是由一个可信的供应商每天提供所有所需的新鲜食材。这使得厨师可以专注于烹饪,而无需担心食材的采购。
- 在依赖注入设计模式中,可信的供应商充当“注入器”,为厨师(对象)提供必要的依赖(食材)。厨师可以使用这些依赖,而无需知道它们来自哪里,确保了依赖的创建和使用之间的清晰分离。这种设置提高了厨房的效率、灵活性和可维护性,就像在软件系统中一样。
- 通俗解释:
- 依赖注入将客户端依赖的创建与其自身行为分离。
- 维基百科解释:
- 在软件工程中,依赖注入是一种技术,其中一个对象接收它所依赖的其他对象。这些其他对象称为依赖。
三、Java中依赖注入模式的编程示例
老巫师喜欢偶尔装满他的烟斗并抽抽烟斗丝。然而,他不想只依赖于一个单一的烟斗丝品牌,而是喜欢能够互换地享受它们。
首先,我们介绍Tobacco
接口和具体的品牌。
@Slf4j
public abstract class Tobacco {
public void smoke(Wizard wizard) {
LOGGER.info("{} smoking {}", wizard.getClass().getSimpleName(),
this.getClass().getSimpleName());
}
}
public class SecondBreakfastTobacco extends Tobacco {
}
public class RivendellTobacco extends Tobacco {
}
public class OldTobyTobacco extends Tobacco {
}
接下来是Wizard
类的层次结构。
public interface Wizard {
void smoke();
}
public class AdvancedWizard implements Wizard {
private final Tobacco tobacco;
public AdvancedWizard(Tobacco tobacco) {
this.tobacco = tobacco;
}
@Override
public void smoke() {
tobacco.smoke(this);
}
}
最后,我们可以展示给老巫师任何品牌的烟斗丝是多么容易。
public static void main(String[] args) {
var simpleWizard = new SimpleWizard();
simpleWizard.smoke();
var advancedWizard = new AdvancedWizard(new SecondBreakfastTobacco());
advancedWizard.smoke();
var advancedSorceress = new AdvancedSorceress();
advancedSorceress.setTobacco(new SecondBreakfastTobacco());
advancedSorceress.smoke();
var injector = Guice.createInjector(new TobaccoModule());
var guiceWizard = injector.getInstance(GuiceWizard.class);
guiceWizard.smoke();
}
程序输出:
11:54:05.205 [main] INFO com.iluwatar.dependency.injection.Tobacco -- SimpleWizard smoking OldTobyTobacco
11:54:05.207 [main] INFO com.iluwatar.dependency.injection.Tobacco -- AdvancedWizard smoking SecondBreakfastTobacco
11:54:05.207 [main] INFO com.iluwatar.dependency.injection.Tobacco -- AdvancedSorceress smoking SecondBreakfastTobacco
11:54:05.308 [main] INFO com.iluwatar.dependency.injection.Tobacco -- GuiceWizard smoking RivendellTobacco
四、何时在Java中使用依赖注入模式
- 当旨在减少类之间的耦合并增加应用程序的模块化时。
- 在对象创建过程复杂或应与类的使用分离的场景中。
- 在需要通过允许模拟或存根依赖来更容易进行单元测试的应用程序中。
- 在管理对象生命周期和依赖的框架或库中,如Spring或Jakarta EE(以前的Java EE)。
五、依赖注入模式在Java中的实际应用
- 框架如Spring、Jakarta EE和Google Guice广泛使用依赖注入(DI)来管理组件生命周期和依赖。
- 需要灵活架构和可互换组件的桌面和Web应用程序。
六、依赖注入模式的优点和权衡
优点:
- 增强了模块化和关注点分离。
- 通过允许轻松模拟依赖,简化了单元测试。
- 通过促进松耦合,提高了灵活性和可维护性。
权衡:
- 可能会在配置中引入复杂性,特别是在大型项目中。
- 对于不熟悉依赖注入模式或框架的开发人员来说,可能会增加学习曲线。
- 需要仔细管理对象的生命周期和范围。