java - 在两个简单类的上下文中掌握依赖注入
问题描述
我在掌握依赖注入时遇到了问题(或者让我说它的好处)。所以我决定写两段简单的代码,一段没有DI,另一段有DI。
所以我有一堂课A
public class A {
public void foo(){
B b = new B();
b.fooB();
}
}
如上所示,A
取决于B
,B
即
public class B {
public void fooB(){
Log.e("s", "y");
}
}
我们可以使用A
like
public void do(){
A a = new A();
a.foo();
}
但是据说不A
应该简单地初始化B
,因为它依赖于它,但是我们应该有一个在两个类之间有某种契约的服务。例如,如果我错了,请告诉我
所以让我们有一个界面BService
public interface BService {
void fooB();
}
并B
成为DiB
public class DiB implements BService {
@Override
public void fooB(){
Log.e("s", "y");
}
}
并A
成为DiA
public class DiA {
BService bService;
public DiA(BService bService){
this.bService = bService;
}
public void foo(){
bService.fooB();
}
}
我们可以使用A
like
public void dIdo(){
BService service = new diB();
diA a = new diA(service);
a.foo();
}
所以我读到 DI 的好处是:
- 可测试代码:因为我实际上可以在 JUnit 中测试这两个代码(我不想在这里发布测试以避免冗长的问题)
- 解耦:它说如果类
B
发生变化,那么A
不应该受到影响,我无法理解,因为如果我fooB()
在类中更改B
为fooB2()
,我将不得不更改覆盖方法,BService
这反过来意味着我将不得不在类中更改它A
两种代码似乎都可以正常工作,我无法理解其中一个的好处,只是另一个更复杂。所以请你能在这个简单A
和B
类的背景下更多地告诉我一些好处。我没有得到什么?
解决方案
您不需要为它创建的接口将其归类为依赖注入。这个类使用依赖注入:
public class A {
private final B b;
public A(B b) {
this.b = b;
}
public void foo(){
b.fooB();
}
}
不要想太多。当您不理解时,“依赖注入”听起来像是一个复杂的概念,但名称实际上完美而简洁地描述了该概念。让我们分解一下:
依赖性:某物所依赖的事物
注入:将外部事物放入其他事物中的行为
在上面的例子中,我们是不是把我们依赖的东西从外面放到了我们的类里面?是的,我们是,所以我们使用依赖注入。我们的类是否实现接口无关紧要。
有充分的理由说明将类实现到接口是一个好主意,但这与依赖注入无关。不要混淆这些东西,不要认为这是一个要求。
解决可测试性:是的,在您的非依赖注入版本中,我们可以测试A
和B
. 我们不能A
孤立地进行测试,B
但那又如何?谁说我们愿意?这会给我们带来什么好处?
好吧,假设B
不是那么微不足道。假设B
从数据库中读取并返回一些值。我们不希望我们的单元测试A
依赖于数据库,因为A
它不关心数据库,它只关心能够fooB
. 不幸的是,如果A
是负责创造的人,B
那么我们就无法改变这种行为。它只能做一件事,在我们的生产代码中,我们需要它来创建一个B
与数据库对话的对象,所以这就是我们所坚持的。
但是,如果我们要注入依赖项,那么我们可以在真实代码中执行此操作:
new A(new DatabaseB());
并在我们的测试中注入一个“假”或“模拟” ,就像它在与数据库交谈而不实际这样做:
new A(mockB);
new A(fakeB);
这允许我们以A
两种不同的方式使用:有和没有数据库;用于生产代码和测试代码。它给了我们选择的灵活性。
推荐阅读
- scala - java.lang.IllegalArgumentException: 'path' is not specified // Spark Consumer 问题
- html - 从ul删除填充时如何将子弹水平对齐到左侧?
- python - Python中的二维插值
- android - 如何从本机android传递数据以响应本机?
- pandas - Pandas - 分组以返回第一次出现,并且每三次出现一个值
- python - Numpy:将两个数组组合成一个矩阵,然后用一个 lambda 映射
- mongodb - 显示从 MongoDB 到 FrontEnd 的项目
- c++ - 重载 std::array 中的运算符 []
- hadoop - 在 Hadoop 集群上解决字数统计有意义吗?
- r - 如何修复 Rmarkdown 中的“yaml.load 未使用的参数”