If I want to write testable Code in Java and decided to use a dependency injection pattern to be able to mock my dependencys in the test environment.
Normally I use this pattern in ABAP OO and don't know exactly the best way to achieve the same thing in Java.
Here is what I do in ABAP OO: I only implement against interfaces and make sure to be able to inject the interfaces from the outside. The instantiation happens in the constructor. Or if a method needs to instantiate something I add an optional parameter to inject the dependency.
Here is an example:
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.
But how do I achive the same thing in Java? There are no optinal parameters. Lets say I do something like this:
public class Foo {
private Dependency dependency;
public Foo(String bar, Dependency dependency) {
if(dependency == null) {
this.dependency = new DependencyImplementation(bar);
}
}
//public static Foo createInstance....
}
This is nearly the same behavior (except that "IS BOUND" is different than "== null"). However this does not make it clear, that you don't have to provide an implementation for the interface Dependency. Also if I need references to other classes within Foo I would have to rewrite everything location that instantiates Foo.