简体   繁体   English

依赖注入Java

[英]Dependency injection java

Is the following a valid example of Dependency injection. 以下是依赖关系注入的有效示例。

public class Employee {
    private String name;
    private String company;

    public Employee(String name, String company){
        this.name = name;
        this.company = company;
    }

    public String getName(){
        return name;
    }
    public void setName(String name){
        this.name = name;
    }
    public String getCompany(){
        return company;
    }
    public void setCompany(String company){
        this.company = company;
    }
}

Application class has dependency on Employee Application类依赖于Employee

public class Application {

    private static Employee emp;
    private static String name;
    private static String company;

    public Application(Employee emp){
        this.emp = emp;
    }

    public static String getApplication(){
        name = emp.getName();
        company = emp.getCompany();
        return "Name: " + name + "\nCompany: " + company;
    }
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Employee emp1 = new Employee("John", "ABC");
        Application app1 = new Application(emp1);
        System.out.println(app1.getApplication());
    }

}

You are successfully injecting a dependency here: 您已在此处成功注入依赖项:

Employee emp1 = new Employee("John", "ABC");
Application app1 = new Application(emp1);

Insomuch as the instance of Application requires an instance of Employee , and therefore advertises on its constructor that one must be supplied. 由于Application实例需要Employee实例,因此在其构造函数上广告必须提供一个实例。 This is a textbook example of inverting that dependency. 这是反转依赖关系的教科书示例。 (Or, simplified, "Require, don't instantiate.") (或者简化为“需要,不要实例化。”)

However, how you store that dependency is a bit questionable: 但是,如何存储该依赖项有点可疑:

private static Employee emp;

In the example provided this likely won't cause any problems. 在提供的示例中,这可能不会引起任何问题。 But what happens when you need to create another instance of Application which needs another dependency instance of Employee ? 但是,当您需要创建另一个需要Employee依赖实例的Application实例时,会发生什么? That second instance would be overwriting the first and breaking its dependency. 第二个实例将覆盖第一个实例并打破其依赖性。

If the instance needs the dependency, then the instance should store the dependency: 如果实例需要依赖关系,则实例应存储依赖关系:

private Employee emp;

(Might even make it final as well, unless you have reason to ever change it during the life of the instance.) (甚至还可能使其final确定,除非您有理由在实例生命期内对其进行更改。)


Granted, the semantics of the name Application implies that there would only ever be one instance. 当然,名称Application的语义意味着只有一个实例。 But a singleton instance would likely be a better approach than static members in that case. 但是在这种情况下,单例实例可能比static成员更好。 As a general rule of thumb in object-oriented programming, be somewhat judicious of your use of static members. 作为面向对象编程的一般经验法则,请谨慎使用static成员。 They have their use, but they very easily have their mis-use as well. 他们有自己的用途,但是他们也很容易滥用。

It is an example of DI. 这是DI的一个例子。 You do it here : 您在这里做:

Employee emp1 = new Employee("John", "ABC");
Application app1 = new Application(emp1);

You implement it here : 您在这里实现它:

 public Application(Employee emp){
    this.emp = emp;
}

This kind of DI is known as constructor injection. 这种DI被称为构造函数注入。

Had you had a setter of employee in your application class, and had you set the employee with that setter, then it would have been called setter injection 如果您在应用程序类中有一个员工设置工,并且用该设置工设置了员工,那么这将被称为设置工注入

First of all you might want to read about when to use dependency injection. 首先,您可能想了解何时使用依赖项注入。 Injecting an instance of a simple class with no functionality makes no sense to me. 注入没有功能的简单类的实例对我来说毫无意义。

You usually use an interface for a class that has also behaviour and it is more than a wrapper of data. 通常,对于具有行为的类使用接口,它不只是数据包装器。 Remove the static and maybe add a final and in your injection send an instance of an implementation for that interface. 删除静态对象,也许添加一个final,然后在您的注入中发送该接口的实现实例。

Like this: 像这样:

public class TextEditor {
   /*Interface SpellChecker**/
   private final SpellChecker spellChecker;
   private String text; 

   /**An implementation for the SpellChecker is provided*/
   public TextEditor(final SpellChecker spellChecker) {
      this.spellChecker = spellChecker;
   }

   public Boolean spellCheck(){
      return this.spellChecker.isSpellingCorrectForText(this.text);
   }
}

As you can see in the example above the spellchecking responsibility is delegated to an external dependency which is injected in the constructor. 如您在上面的示例中所看到的,拼写检查责任被委派给注入到构造函数中的外部依赖项。 The TextEditor does not need to know how to spellcheck, he just calls an interface with a method. TextEditor不需要知道如何进行拼写检查,他只需使用方法调用接口即可。

Why do we do this? 我们为什么要做这个? To respect SOLID (SRP): https://en.wikipedia.org/wiki/SOLID_(object-oriented_design) 要遵守SOLID(SRP): https ://en.wikipedia.org/wiki/SOLID_(面向对象的设计

More here: https://softwareengineering.stackexchange.com/questions/135971/when-is-it-not-appropriate-to-use-the-dependency-injection-pattern http://www.tutorialspoint.com/spring/spring_dependency_injection.htm 更多内容, 访问https : //softwareengineering.stackexchange.com/questions/135971/when-is-it-not-appropriate-to-use-the-dependency-injection-pattern http://www.tutorialspoint.com/spring/ spring_dependency_injection.htm

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM