如果我想用Java编写可测试代码并决定使用依赖注入模式来在测试环境中模拟我的依赖项。
通常我在ABAP OO中使用这种模式,并不完全知道在Java中实现相同功能的最佳方法。
以下是我在ABAP OO中所做的事情:我只针对接口实现,并确保能够从外部注入接口。实例化发生在构造函数中。或者,如果某个方法需要实例化某些内容,我会添加一个可选参数来注入依赖项。
以下是一个例子:
CLASS cl_foo DEFINITION.
PRIVATE SECTION.
DATA: gr_dependency TYPE REF to if_dependency. "if_dependency is an interface
PUBLIC SECTION.
METHODS: constructor IMPORTING iv_bar TYPE string, "this String makes it complicated in the Java world
ir_dependency TYPE REF TO if_dependency OPTIONAL.
"CLASS-METHODS: create_instance....
ENDCLASS.
CLASS cl_foo IMPLEMENTATION.
METHOD constructor.
IF ir_dependency IS BOUND.
gr_dependency = ir_dependency.
ELSE.
CREATE OBJECT gr_dependency TYPE cl_dependency_implementation EXPORTING iv_bar.
ENDIF.
ENDMETHOD.
ENDCLASS.
但是我如何在Java中实现同样的目标呢?没有光学参数。让我们说我做这样的事情:
public class Foo {
private Dependency dependency;
public Foo(String bar, Dependency dependency) {
if(dependency == null) {
this.dependency = new DependencyImplementation(bar);
}
}
//public static Foo createInstance....
}
这几乎是相同的行为(除了“IS BOUND”与“== null”不同)。但是,这并不清楚,您不必为接口Dependency提供实现。此外,如果我需要引用Foo中的其他类,我将不得不重写实例化Foo的所有位置。
答案 0 :(得分:1)
大多数情况下,当我编写Java代码时,我会在外部设置依赖项,如果它为null,则不会为类提供默认值。相反,如果它为null,则抛出IllegalArgumentException以强制设置值。通常,我会做类似以下的事情:
public class Foo {
private final Dependency dependency;
public Foo(Dependency dependency) {
if(dependency == null) {
throw new IllegalArgumentException("dependency must be set message.");
}
this.dependency = dependency;
}
// the rest of the code here.
}
将变量设置为final,它将强制在构造函数中设置值,并通过抛出异常,如果开发人员尝试传递null,您将帮助程序员帮助不要快速错过此要求,而是比以后的空指针异常。如果您使用带有应用程序上下文XML文件的spring之类的东西来执行依赖项注入,那么这也将帮助您跟踪xml文件中的拼写错误或其他问题,因为如果您未能提供参数,它将立即失败。