Jav*_*a P 7 java spring dependency-injection inversion-of-control strategy-pattern
我经常对这三个术语感到困惑.这三个看起来与我相似.有人可以通过示例清楚地向我解释.
我看过类似的帖子,完全不明白.
Mar*_*ers 20
依赖注入是指告诉类其依赖性是什么的模式,而不是要求类知道在哪里找到它的所有依赖项.
所以,例如,你从这里开始:
public class UserFetcher {
private final DbConnection conn =
new DbConnection("10.167.1.25", "username", "password");
public List<User> getUsers() {
return conn.fetch(...);
}
}
Run Code Online (Sandbox Code Playgroud)
这样的事情:
public class UserFetcher {
private final DbConnection conn;
public UserFetcher(DbConnection conn) {
this.conn = conn;
}
public List<User> getUsers() {
return conn.fetch(...);
}
}
Run Code Online (Sandbox Code Playgroud)
这减少了代码中的耦合,如果您想进行单元测试,这尤其有用UserFetcher.现在,您可以将a 传递给测试数据库,而不是UserFetcher 始终针对找到的数据库运行.或者,更在快速测试非常有用,可以实现或子类通过甚至不连接到一个数据库,它只是丢弃的请求!10.167.1.25DbConnectionDbConnection
但是,这种原始依赖注入使得布线(提供具有其依赖性的对象)更加困难,因为您已经使用全局变量(或本地实例化对象)替换了访问依赖性,并通过整个对象图传递依赖性.
想想UserFetcher一个依赖的情况AccountManager,它是一个依赖AdminConsole.然后AdminConsole需要传递DbConnection实例AccountManager,并AccountManager需要将其传递给UserFetcher... 即使既不需要AdminConsole也不AccountManager需要DbConnection直接使用!
一个控制反转容器(春,吉斯等)的目的是使依赖注入更容易由自动布线(提供)的依赖关系.要做到这一点,你告诉你的IoC容器一旦如何提供一个对象(在Spring中,这被称为bean),并且每当另一个对象请求该依赖项时,它将由容器提供.
因此,如果我们使用构造函数注入,我们的最后一个示例可能与Guice一样:
public class UserFetcher {
private final DbConnection conn;
@Inject //or @Autowired for Spring
public UserFetcher(DbConnection conn) {
this.conn = conn;
}
public List<User> getUsers() {
return conn.fetch(...);
}
}
Run Code Online (Sandbox Code Playgroud)
我们必须配置IoC容器.在Guice,这是通过实施Module; 在Spring中,您通常通过XML 配置应用程序上下文.
public class MyGuiceModule extends AbstractModule {
@Override
public void configure() {
bind(DbConnection.class).toInstance(
new DbConnection("localhost", "username", "password"));
}
}
Run Code Online (Sandbox Code Playgroud)
现在,当UserFetcher由Guice或Spring构建时,DbConnection会自动提供.
Guice有一篇关于依赖注入背后动机的非常好的Wiki文章,并进一步使用了IoC容器.它一直值得一读.
该策略模式是依赖注入,在那里你注入只是一种特殊情况下的逻辑,而不是一个对象(即使在Java中,逻辑将在一个对象封装).这是一种解耦独立业务逻辑的方法.
例如,您可能有这样的代码:
public Currency computeTotal(List<Product> products) {
Currency beforeTax = computeBeforeTax(products);
Currency afterTax = beforeTax.times(1.10);
}
Run Code Online (Sandbox Code Playgroud)
但是,如果您想将此代码扩展到新的司法管辖区,并使用不同的销售税计划呢?您可以注入计算税的逻辑,如下所示:
public interface TaxScheme {
public Currency applyTax(Currency beforeTax);
}
public class TenPercentTax implements TaxScheme {
public Currency applyTax(Currency beforeTax) {
return beforeTax.times(1.10);
}
}
public Currency computeTotal(List<Product> products, TaxScheme taxScheme) {
Currency beforeTax = computeBeforeTax(products);
Currency afterTax = taxScheme.applyTax(beforeTax);
return afterTax;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5681 次 |
| 最近记录: |