* add state and callback pattern * add command and template-method pattern * add iterator pattern * add bridege and DI pattern * fix issue #1600 * add converter,proxy,visitor pattern * add caching,composite,delegation,dirty-flag,interpreter patterns * add dao and producer-consumer * add dto and provate class data pattern * fix #1646 png path problems * fix #1646 composite png path case problem * add abstract document pattern and version-number pattern * add ambassador pattern * add acyclic-visitor and api-gateway pattern * add abstract-factory pattern * add active-object pattern * add aggregator-microservices and arrange-act-assert pattern * update async-method-invocation pattern * add balking and business-delegate pattern * add bytecode and circuit-break pattern * update arrange/act/assert pattern problems * add csch pattern * add language code, correct pic path * #1805 update permalink Co-authored-by: Subhrodip Mohanta <subhrodipmohanta@gmail.com> Co-authored-by: Mike <admin@xiaod.info> Co-authored-by: Ilkka Seppälä <iluwatar@users.noreply.github.com>
layout, title, folder, permalink, categories, language, tags
layout | title | folder | permalink | categories | language | tags | |
---|---|---|---|---|---|---|---|
pattern | Dependency Injection | dependency-injection | /patterns/dependency-injection/ | Creational | zh |
|
目的
依赖注入是一种软件设计模式,其中一个或多个依赖项(或服务)被注入或通过引用传递到一个依赖对象(或客户端)中,并成为客户端状态的一部分。该模式将客户的依赖关系的创建与其自身的行为分开,这使程序设计可以松散耦合,并遵循控制反转和单一职责原则。
解释
真实世界例子
老巫师喜欢不时地装满烟斗抽烟。 但是,他不想只依赖一个烟草品牌,而是希望能够互换使用它们。
通俗的说
依赖注入将客户端依赖的创建与其自身行为分开。
维基百科说
在软件工程中,依赖注入是一种对象接收其依赖的其他对象的技术。 这些其他对象称为依赖项。
程序示例
先介绍一下烟草接口和具体的品牌。
public abstract class Tobacco {
private static final Logger LOGGER = LoggerFactory.getLogger(Tobacco.class);
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 {
}
下面是老巫师的类的层次结构。
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);
}
}
最后我们可以看到给老巫师任意品牌的烟草是多么的简单。
var advancedWizard = new AdvancedWizard(new SecondBreakfastTobacco());
advancedWizard.smoke();
类图
适用性
使用依赖注入当:
- 当你需要从对象中移除掉具体的实现内容时
- 使用模拟对象或存根隔离地启用类的单元测试