简单英语什么是AOP、依赖注入和控制反转
我试图理解 AOP、依赖注入和控制反转 SPRING 相关概念,但我很难理解它。
谁能用简单的英语解释一下?
I have tried to understand AOP, Dependency Injection and Inversion of Control SPRING related concepts but I am having hard time understanding it.
Can anyone explain this in simple English ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我理解您的困惑,我花了一些时间才理解这些概念是如何相互关联的。所以这是我对这一切的(某种程度上个人的)解释:
1。控制反转
控制反转是一个相当通用的设计原则,指的是解耦实际执行时的行为规范。例如,
与
后者相比,没有直接调用,更加灵活。就其一般形式而言,控制反转与观察者模式、事件或回调相关。
2.依赖倒置
依赖倒置是另一个设计原则。粗略地说,它表示高层抽象不应该直接依赖于低层抽象;这确实会导致设计中,如果没有较低级别的抽象,就无法重用较高级别的抽象。
这里,如果不访问
MyLowLevelClass
,MyHighLevelClass
就无法编译。为了打破这种耦合,我们需要用接口抽象低级类,并删除直接实例化。请注意,您不需要任何特殊的东西(例如容器)来强制依赖倒置,这是一个原则。值得一读的是 Uncle Bob 所著的依赖倒置原理。
3.依赖注入
现在是依赖注入。对我来说,依赖注入 = IoC + 依赖倒置:
在上面我提供的示例中,如果使用容器来实例化对象并在构造函数中自动注入依赖项,则可以完成依赖项注入(我们经常谈到 DI 容器):
请注意,有各种 注入形式。另请注意,从这个角度来看, setter 注入 可以被视为回调的一种形式 - DI 容器创建对象然后回调 setter。控制流程实际上被颠倒了。
4. AOP
严格来说,AOP 和前面3点关系不大。 关于 AOP 的开创性论文非常通用且现实将各种源代码编织在一起(可能用不同的语言表达)以生成可用软件的想法。
我不会对 AOP 进行更多展开。这里重要的是,依赖注入和 AOP 确实有效地协同工作,因为它使编织变得非常容易。如果使用 IoC 容器和依赖项注入来抽象对象的实例化,则可以轻松地使用 IoC 容器在注入依赖项之前编织各个方面。否则,这将需要特殊的编译或特殊的类加载器。
希望这有帮助。
I understand your confusion and it took me some time to understand how these concepts were related together. So here is my (somehow personal) explanation of all this:
1. Inversion of Control
Inversion of control is a design principle rather generic that refers to the decoupling of the specification of a behavior from when it is actually executed. Compare for instance,
with
In the latter, there is no direct invocation which is more flexible. In its general form, inversion of control relates to the observer pattern, events, or callbacks.
2. Dependency inversion
Dependency inversion is another design principle. Roughly speaking, it says that higher-level abstraction should not depend directly on lower-level abstractions; this results indeed in a design where higher-level abstraction can not be reused without the lower-level abstractions.
Here,
MyHighLevelClass
can not compile without access toMyLowLevelClass
. To break this coupling, we need to abstract the low level class with an interface, and remove the direct instantiation.Note that you don't need anything special like a container to enforce dependency inversion, which is a principle. A good reading is The Dependency Inversion Principle by Uncle Bob.
3. Dependency injection
Now comes dependency injection. To me
dependency injection = IoC + dependency inversion
:In the example I provided above, dependency injection can be done if a container is used to instantiate objects and automatically inject the dependency in the constructor (we speak then frequently of DI container):
Note that there are various form of injections. Note also that under this perspective, setter injection can be seen as a form of callback -- the DI container creates the object then calls back the setter. The flow of control is effectively inverted.
4. AOP
Strictly speaking, AOP has little to do with the 3 previous points. The seminal paper on AOP is very generic and present the idea of weaving various sources together (possibly expressed with different languages) to produce a working software.
I won't expand more on AOP. What is important here, is that dependency injection and AOP do effectively plays nicely together because it makes the weaving very easy. If an IoC container and dependency injection is used to abstract away the instantiation of objects, the IoC container can easily be used to weave the aspects before injecting the dependencies. This would otherwise requires a special compilation or a special
ClassLoader
.Hope this helps.
依赖注入在 如何向 5 岁的孩子解释依赖注入?:
AOP - 面向方面的编程 - 基本上意味着您编写的源代码是根据位于其他地方的规则用其他代码修改的。这意味着您可以说“作为每个方法的第一行,我希望在中心位置有一个 'log.debug("entering method()")' 以及您编译的每个方法然后,该规则将包含该行。“方面”是以其他方式查看代码的名称,而不是简单地从第一个源代码行到最后一个代码行,这
基本上意味着您没有控制的核心代码段 。一切(就像 main() 中的一个巨大的开关),但有很多代码“不知何故”被调用。这个主题在维基百科上讨论:http://en.wikipedia.org/wiki/Inversion_of_control
Dependency injection was explained very well in How to explain dependency injection to a 5-year-old?:
AOP - Aspect Oriented Programming - basically means that the source you write is modified with other code, based on rules located ELSEWHERE. This means that you can e.g. say "as the first line of every method I want a 'log.debug("entering method()")' in a central place and each and every method you compile with that rule in place will then have that line included. The "aspect" is the name of looking on code in other ways than simply from first source line to last.
Inversion of Control basically means that you do not have a central piece of code controlling everything (like a giant switch in main()) but have a lot of pieces of code that "somehow" get called. The subject is discussed at Wikipedia: http://en.wikipedia.org/wiki/Inversion_of_control
这三个概念都是不同的,但它们都能很好地协同工作,因此 Spring 应用程序经常同时使用它们。我给你举个例子。
假设我们有一个可以执行许多不同操作的 Web 应用程序。我们可以通过多种方式构建这个应用程序,但一种方法是创建一个类来负责完成这些事情。我们需要从某个地方调用并创建这些类。一种选择是有一个大的主类,它创建每个服务之一,打开一个套接字,并在这些服务进入时将调用传递给它们。不幸的是,我们已经为自己创建了一个上帝类,它有方法太多的逻辑并且对我们程序中的所有内容如何工作了解太多。如果我们改变程序的任何内容,我们可能需要修改这个类。
而且,测试也很困难。如果任何类直接实例化和调用其他类,我们就无法单独测试它。单元测试变得越来越难编写。
解决这个问题的一种方法是使用控制反转。我们说“好吧,这些是服务类。谁创建了它们?不是我。”通常,每个服务都定义一个接口,例如 LoginService 或 BillingService。该接口可能有多个实现,但您的应用程序并不关心。它只知道它可以请求某种类型的服务或具有特定名称的服务,并且它会得到一些不错的回报。
依赖注入允许我们将所有的小片段连接在一起。类具有可访问的字段、构造函数参数或 setter 方法,它们是对其需要访问的其他组件的引用。这使得单元测试变得更加容易。您可以创建被测试的对象,向其抛出模拟或存根依赖项,然后测试该对象是否在隔离中正确运行。
现在,我们真正的应用程序是一个复杂的杂乱片段,所有这些片段都需要连接在一起。有很多方法可以实现这一点,包括允许应用程序进行猜测(“这个类需要一个 UserService,而我负责的另一个类则实现了 UserService”)或者仔细解释它们如何在 XML 中连接在一起或Java。 Spring 的核心是一个负责将这些类连接在一起的服务。
现在我们进入 AOP。假设我们拥有所有这些以复杂方式相互连接的类。我们可能希望以非常通用的方式描述一些跨领域的问题。例如,您可能希望在调用任何服务时启动数据库事务,并在服务不引发异常时提交该事务。事实证明,Spring 处于执行此类任务的独特位置。 Spring 可以动态创建代理类来实现您的类所需的任何接口,并且它可以将您的类包装在其代理中。现在,IoC 和依赖注入当然不是面向方面编程所必需的,但它是实现它的一种极其方便的方法。
These three are all different concepts, but they all work well together, and so Spring apps often make use of all of it at once. I'll give you an example.
Let's say that we have a web application that can do many different things. We could construct this application in many ways, but one way is to create a class that is in charge of doing each of these things. We need to invoke and create these classes from somewhere. One option is to have a big main class that creates one of each of these services, opens up a socket, and passes calls to these services as they come in. Unfortunately, we've gone and created ourselves a god class, which has way too much logic and knows way too much about how everything in our program works. If we change anything about our program, we're probably going to need to modify this class.
Also, it's difficult to test. We can't test any class in isolation if it runs around instantiating and invoking the other classes directly. Unit tests become much, much harder to write.
A way to get around this is to use inversion of control. We say "okay, these are service classes. Who instatiates them? Not me." Usually, each one defines an interface, like LoginService or BillingService. There might be more than one implementation of that interface, but your app doesn't care. It just knows that it can ask for a certain kind of a service or a service with a certain name, and it'll get something nice back.
Dependency injection allows us to wire all of our litle pieces together. Classes have accessible fields, constructor arguments, or setter methods that are references to the other components that they'll need to access. That makes unit testing much easier. You can create the object under test, throw a mock or stub dependency at it, and then test that the object behaved correctly in isolation.
Now, our real application is a complex jumble of pieces that all need to be wired together just so. There are many ways to accomplish this, including allowing the application to make guesses ("this class wants a UserService, there is exactly one other class I'm in charge of that implements UserService") or by carefully explaining how they wire together in XML or Java. Spring, at its core, is a service that takes care of wiring these classes together.
Now we get to AOP. Let us say that we have all of these classes that are wired to each other in elaborate ways. There are some cross-cutting concerns that we might want to describe in very generic ways. For instance, perhaps you'd like to start a database transaction whenever any service is invoked, and commit that transaction so long as the service doesn't throw an exception. It turns out that Spring is in a unique position to perform such a task. Spring can create proxy classes on the fly that implement whatever interface your classes need, and it can wrap your class in its proxy. Now, IoC and dependency injection certainly aren't necessary to do aspect-oriented programming, but it's an extremely convenient way to accomplish it.
中很好地解释了依赖注入和控制反转之间的区别
http://martinfowler.com/articles/dipInTheWild .html
(“你的意思是依赖倒置,对吧?”部分)
摘要:
The difference between Dependency Injection and Inversion of Control is explained very well in
http://martinfowler.com/articles/dipInTheWild.html
("You mean Dependency Inversion, Right?" section)
The summary:
让我告诉你一些关于AOP的知识,希望它能让你更容易理解。
AOP 的基本原则是找到返回的常见任务/方面
代码中的很多地方并不属于代码的具体业务。例如
写入以登录任何函数的每个入口,或者在创建对象时对其进行包装,或者在调用特定函数时向管理员发送电子邮件。
因此,我们不是由程序员来处理这些非业务方面,而是从他们那里获取并
我们在幕后管理这些方面。
AOP 的所有基本功能都在 1 条腿上......
let me tell you some word about AOP, hope it make it simplier to understand.
The very base principle of AOP is finding common tasks/aspects which returns in
many places in the code and dont belong to the concerete business of the code. For example
write to log on every entrance to any function, or when an object is created wrapp it, or send email to admin when calling to specific function.
So instead of the programmers will handle these non businuss aspect we take it from them and
we manage these aspects behond the scene.
That all the basic of AOP on 1 leg....
Spring in Action 的简单比较:
A simple comparison from Spring in Action: