java - 实现依赖注入(inject)设计模式

标签 java design-patterns dependency-injection solid-principles

我被告知可以在以下代码中实现依赖注入(inject)设计模式两次,并且允许更改方法签名:

public class Person {
    String title;
    ArrayList<String> name = new ArrayList<>();

    public Person() {
        name.add("First");
        name.add("Middle");
        name.add("Last");
    }

    public void setTitle(int i) {
        switch (i) {
            case 0:
                title = "Ms.";
                break;
            case 1:
                title = "Mr.";
                break;
            case 2:
                title = "Mx.";
                break;
    }
    }
}

所以我添加依赖注入(inject)的尝试如下:

public class Person {
    String title;

    ArrayList<String> name = new ArrayList<>();


    public Person(String First,String Middle,String Last) {
        name.add(First);
        name.add(Middle);
        name.add(Last);
    }

    public void setTitle(String title) {

        this.title = title;

    }
}

这是实现设计模式的正确方法吗?或者这段代码可以用更好的方式实现吗?

最佳答案

这本书Dependency Injection Principles, Practices, and Patterns将依赖注入(inject) (DI) 定义为

a set of software design principles and patterns that enables you to develop loosely coupled code. (Chapter 1, page 4)

DI 简介可在this excerpt 中找到。从那本书的第一章,或者你可以阅读 the full chapter 1 online .

这本书的一个重要区别是Stable Dependencies之间的区别。和 Volatile Dependencies 。 DI 关心的是抽象和注入(inject) volatile 依赖项,或者如书 states 所示。 :

Volatile Dependencies are the focal point of DI. It’s for Volatile Dependencies rather than Stable Dependencies that you introduce Seams into your application. Again, this obligates you to compose them using DI.

Person 类的角度来看,String 是一个稳定依赖。由于依赖注入(inject)涉及 volatile 依赖项的注入(inject),因此我不认为提供名字、中间名和姓氏值是 DI 的一种形式。如果构造函数用于注入(inject) volatile 依赖项,例如,它将成为 DI。使用接口(interface)。例如:

public class UpdatePersonTitleHandler
{
    private PersonRepository repository;

    public UpdatePersonTitleHandler(PersonRepository repository)
    {
        this.repository = repository;
    }

    public void handle(UpdatePersonTitle command)
    {
        Person person = this.repository.getById(command.personId);

        person.setTitle(command.Title);

        this.repository.Update(person);
    }
}

在本例中,UpdatePersonTitleHandler“组件”依赖于 PersonRepository 抽象,该抽象通过其构造函数注入(inject)(使用 Constructor Injection )。在运行时,PersonRepository 可能由 SqlPersonRepository 实现,并且 UpdatePersonTitleHandler 可能按如下方式构造:

var handler = new UpdatePersonTitleHandler(
    new SqlPersonRepository("connection string")); // <-- constructor injection

关于java - 实现依赖注入(inject)设计模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59332487/

相关文章:

java - 四舍五入将其转换为 int (java)

java - 使用 SwingWorker java 在线程池中等待任务

java - 断言 JMockit 期望结果与构造的实例相同

java - 线程中的异常 "AWT-EventQueue-0"java.lang.NumberFormatException : For input string: "78 error in java

java - 设计模式建议

Java关于实现方法中运行时类型检查的问题

c# - unity 注册实例并解析

c# - 有没有办法从具有内部构造函数的类派生?

java - 在 Spring @Value 注释中省略美元占位符

typescript - 定义全局 TypeScript 配置(接口(interface)),用于 Aurelia 依赖注入(inject)