普通类与带注入的类之间的区别

huangapple go评论62阅读模式
英文:

Difference between normal class and class with injection

问题

情况1:

class Student
{
   private final Subject subject;

   Student (final Subject subject)
   {
     this.subject = subject;
   }
   //做一些操作
}

情况2:

import javax.inject.Inject;

class Student
{
   private final Subject subject;

   @Inject
   Student (final Subject subject)
   {
     this.subject = subject;
   }
   //做一些操作
}

有人可以解释一下这两种情况之间的区别,以及每种情况何时使用吗?

英文:

Consider 2 classes, Student and Subject.

Case 1 :

class Student
{
   private final Subject subject;

   Student (final Subject subject)
   {
     this.subject = subject;
   }
   //do something
}

Case 2 :

import javax.inject.Inject;

class Student
{
   private final Subject subject;

   @Inject
   Student (final Subject subject)
   {
     this.subject = subject;
   }
   //do something
}

Can someone explain the difference between these two cases, and when each case is used?

答案1

得分: 2

基本上,类的行为没有任何区别(方法相同且包含相同的代码),以及这个类所维护的信息(数据字段相同)。

但是,这个类并不是“孤立”存在的,很可能它是应用程序的一部分,包含许多其他类,而且你必须以某种方式管理这些类、它们之间的依赖关系等等。因此,这里就有了区别:

区别在于如何组织应用程序,更准确地说是由谁“管理”这个类,也就是谁创建它(调用new Student),以及谁负责“找出”在正确实例化对象类型为Student的对象时必须提供的类Subject的实例的位置。

因此,在这方面有许多管理代码的方法:

你可以自己做所有的事情:

main() {
Subject subject = new Subject()
Student student = new Student(subject)

}

现在,如果有1000个类,你将不得不维护1000行代码来创建所有这些对象。虽然在这种情况下,它可能仍然看起来是可行的,因为对象是一起创建的,但有时真实的应用程序可能比那复杂得多,依赖关系的解析也可能变得更加复杂。

因此,像Guice、Spring等依赖注入(DI)容器就应运而生:

它们可以自己找出如何实例化这些类,分析类的结构以找出依赖关系,底线是为你创建类。
为了向这些容器提供“提示”,你可以使用诸如@Inject之类的注释,但总的来说,你以不同的方式来管理应用程序:

  • 你的类由依赖注入容器创建
  • 你可以为容器提供提示,让它“帮助”你创建类,通过使用这些提示,依赖注入容器能够解析实际的实例化方式(如何通过反射调用new,调用哪个构造函数,传递哪些参数,以及顺序如何等等)。
  • 因此,你不再需要维护像new Student,new Subject()这样的代码。依赖注入容器会替你完成。

基本上,这是一个非常广泛的主题,所以出于教育目的,我建议你在深入研究特定的实现技术细节(如Google Guice中的@Inject)之前,先找一个全面的关于依赖注入的教程。

英文:

Basically there is no difference in the behavior of the class (methods are the same and contain the same code) and the information that this class maintains (data fields are the same).

But this class doesn't "live" in vacuum, probably its a part of an application that contains many other classes, and you have somehow to manage the classes, dependencies between them, and so forth. So here comes the difference:

The difference is how do you organize the application, more precisely who "Manages" this class, read, who creates it (calls new Student) and who is responsible for "figuring out" where to "get" the instance of class Subject that the object of type Student obviously must be supplied with in order to get instantiated properly.

So there are many ways to manage your code in this sense:

You can do everything by yourself:

main() {
Subject subject = new Subject()
Student student = new Student(subject)

}

Now if there are say 1000 classes, you'll have to maintain 1000 lines of code to create all these objects. Although In this case, it might still seem doable, because objects are created together, but sometimes the real applications can be much more complicated than that, the dependency resolution may also become much more complicated.

Hence there were created DI containers like Guice, Spring and so forth:

They can figure out by themselves how to instantiate the classes, analyze the class's structure to figure out the dependencies and bottom line create the classes for your.
To provide the "hints" to these containers you can use annotations like @Inject but all-in-all, you manage the application in a different way:

  • your classes get created by the dependency injection container
  • you may provide hints to the container that will "help" it to create a class, by using these hints the DI container is able to resolve the actual way of instantiation (how to call new by reflection, which constructor to call, which parameters to pass, in which order, etc).
  • As a consequence you don't maintain code like new Student, new Subject(), etc. Dependency injection container does it for you.

Basically its a very broad topic, so for educational purposes I suggest you to find a comprehensive tutorial about this DI topic even before you dive into the particular implementation technicalities (like @Inject in Google Guice).

huangapple
  • 本文由 发表于 2020年10月12日 13:03:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/64311942.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定