实施依赖注入设计模式
Implementing Dependency Injection design pattern
有人告诉我可以在以下代码中两次实现依赖注入设计模式,并且允许更改方法签名:
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;
}
}
}
所以我添加依赖注入的尝试如下:
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 将依赖注入 (DI) 定义为
a set of software design principles and patterns that enables you to develop loosely coupled code. (Chapter 1, page 4)
可以在 this excerpt from chapter one of that book, or you can read the full chapter 1 online 中找到有关 DI 的介绍。
本书做出的一个重要区分是 Stable Dependencies and Volatile Dependencies. DI is concerned about abstracting and injecting Volatile Dependencies, or as the book 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
class 的角度来看,String
是 稳定的依赖关系 。因为依赖注入涉及 易失性依赖关系 的注入,所以我不认为提供名字、中间名和姓氏值是一种 DI 形式。如果构造函数用于注入 Volatile Dependency,它将变成 DI,例如使用界面。例如:
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
'component' 依赖于 PersonRepository
抽象,它通过其构造函数 注入 (使用 Constructor Injection).在运行时,PersonRepository
可能由 SqlPersonRepository
实现,而 UpdatePersonTitleHandler
可能构造如下:
var handler = new UpdatePersonTitleHandler(
new SqlPersonRepository("connection string")); // <-- constructor injection
有人告诉我可以在以下代码中两次实现依赖注入设计模式,并且允许更改方法签名:
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;
}
}
}
所以我添加依赖注入的尝试如下:
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 将依赖注入 (DI) 定义为
a set of software design principles and patterns that enables you to develop loosely coupled code. (Chapter 1, page 4)
可以在 this excerpt from chapter one of that book, or you can read the full chapter 1 online 中找到有关 DI 的介绍。
本书做出的一个重要区分是 Stable Dependencies and Volatile Dependencies. DI is concerned about abstracting and injecting Volatile Dependencies, or as the book 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
class 的角度来看,String
是 稳定的依赖关系 。因为依赖注入涉及 易失性依赖关系 的注入,所以我不认为提供名字、中间名和姓氏值是一种 DI 形式。如果构造函数用于注入 Volatile Dependency,它将变成 DI,例如使用界面。例如:
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
'component' 依赖于 PersonRepository
抽象,它通过其构造函数 注入 (使用 Constructor Injection).在运行时,PersonRepository
可能由 SqlPersonRepository
实现,而 UpdatePersonTitleHandler
可能构造如下:
var handler = new UpdatePersonTitleHandler(
new SqlPersonRepository("connection string")); // <-- constructor injection