Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java中编写无可选参数的可测试代码的正确方法与ABAPOO中的注入_Java_Design Patterns_Dependency Injection_Abap - Fatal编程技术网

在Java中编写无可选参数的可测试代码的正确方法与ABAPOO中的注入

在Java中编写无可选参数的可测试代码的正确方法与ABAPOO中的注入,java,design-patterns,dependency-injection,abap,Java,Design Patterns,Dependency Injection,Abap,如果我想用Java编写可测试代码,并决定使用依赖项注入模式,以便能够在测试环境中模拟依赖项 通常我在ABAPOO中使用这种模式,但不知道在Java中实现同样功能的最佳方法 以下是我在ABAPOO中所做的:我只针对接口实现,并确保能够从外部注入接口。实例化发生在构造函数中。或者,如果一个方法需要实例化某些东西,我会添加一个可选参数来注入依赖项 以下是一个例子: CLASS cl_foo DEFINITION. PRIVATE SECTION. DATA: gr_dependency T

如果我想用Java编写可测试代码,并决定使用依赖项注入模式,以便能够在测试环境中模拟依赖项

通常我在ABAPOO中使用这种模式,但不知道在Java中实现同样功能的最佳方法

以下是我在ABAPOO中所做的:我只针对接口实现,并确保能够从外部注入接口。实例化发生在构造函数中。或者,如果一个方法需要实例化某些东西,我会添加一个可选参数来注入依赖项

以下是一个例子:

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”)。但是,这并没有明确说明,您不必为接口依赖关系提供实现。另外,如果我需要引用Foo中的其他类,我必须重写实例化Foo的所有位置。

大多数时候,当我编写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,您将帮助程序员快速避免错过此要求,而不是稍后出现null指针异常。如果您在应用程序上下文XML文件中使用类似spring的东西来执行依赖项注入,那么这也将帮助您跟踪XML文件中的拼写错误或其他问题,因为如果您未能提供参数,它将立即失败

但是对于非常复杂的依赖关系呢?我的意思是,你不能轻易地在外部实例化每个依赖项。到目前为止,我很少遇到这样的情况:我会被迫在一个类内部实例化一个默认依赖项,我可以在某个中央DI类中实例化,或者将其放入适当的应用程序上下文中。或者,您可以使用一个不带参数的单独构造函数来实现默认依赖项,这样开发人员就可以知道已经提供了默认依赖项。(JavaDocs可以帮助确保开发人员理解您的意图。)