有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!


共 (6) 个答案

  1. # 1 楼答案

    依赖注入在How to explain dependency injection to a 5-year-old?中得到了很好的解释:

    When you go and get things out of the refrigerator for yourself, you can cause problems. You might leave the door open, you might get something Mommy or Daddy doesn't want you to have. You might even be looking for something we don't even have or which has expired.

    What you should be doing is stating a need, "I need something to drink with lunch," and then we will make sure you have something when you sit down to eat.

    AOP——面向方面的编程——基本上意味着您编写的源代码会根据其他地方的规则,用其他代码进行修改。这意味着,例如,你可以说“作为每个方法的第一行,我希望在一个中心位置有一个'log.debug('enteringmethod())”,然后用该规则编译的每个方法都将包含该行。“aspect”是以其他方式查看代码的名称,而不仅仅是从第一行到最后一行

    控制反转基本上意味着你没有一段控制一切的核心代码(比如main()中的一个巨大开关),而是有很多“不知怎么”被调用的代码。维基百科上讨论了这个问题:http://en.wikipedia.org/wiki/Inversion_of_control

  2. # 2 楼答案

    依赖注入和控制反转之间的区别在本文中得到了很好的解释

    http://martinfowler.com/articles/dipInTheWild.html

    (“你是说依赖倒置,对吗?”(部分)

    总结:

    DI is about how one object acquires a dependency. When a dependency is provided externally, then the system is using DI.

    IoC is about who initiates the call. If your code initiates a call, it is not IoC, if the container/system/library calls back into code that you provided it, is it IoC.

  3. # 3 楼答案

    我理解你的困惑,我花了一些时间来理解这些概念是如何联系在一起的。以下是我对这一切的解释:

    1。控制反转

    Inversion of control是一种相当通用的设计原则,指行为规范与实际执行时的分离。比如说,

    myDependency.doThis();
    

    myDependency.onEventX += doThis();
    

    在后者中,没有更灵活的直接调用。在其一般形式中,控制反转与观察者模式事件回调有关

    2。依赖倒置

    依赖倒置是另一个设计原则。粗略地说,它说高级抽象不应该直接依赖于低级抽象;这确实导致了一种设计,在这种设计中,如果没有较低级别的抽象,就无法重用较高级别的抽象

     class MyHighLevelClass {
         MyLowLevelClass dep = new MyLowLeverClass();
     }
    
     class App {
         void main() {  new HighLevelClass().doStuff(); }
     }
    

    在这里,MyHighLevelClass如果没有对MyLowLevelClass的访问权,就无法编译。为了打破这种耦合,我们需要用接口抽象低级类,并删除直接实例化

    class MyLowLevelClass implements MyUsefulAbstraction { ... }
    
    class MyHighLevelClass {
    
        MyUsefulAbstraction dep;
    
        MyHighLevelClass( MyUsefulAbstraction dep ) {
            this.dep = dep;
        }
    }
    
    class App {
         void main() {  new HighLevelClass( new LowLevelClass() ).doStuff(); }
     }
    

    请注意,您不需要任何特殊的东西,比如容器来强制执行依赖项反转,这是一个原则。鲍勃叔叔写了一本好书

    3。依赖注入

    现在是依赖注入。对我来说dependency injection = IoC + dependency inversion

    1. 依赖项是外部提供的,因此我们强制执行依赖项反转原则
    2. 容器设置依赖项(不是我们),所以我们说的是控制反转

    在我上面提供的示例中,如果使用容器来实例化对象,并在构造函数中自动注入依赖项,则可以进行依赖项注入(我们经常提到DI容器):

     class App {
         void main() {  DI.getHighLevelObject().doStuff(); }
     }
    

    请注意,有各种form of injections。还要注意的是,在这个透视图下,setter injection可以被视为回调的一种形式——DI容器创建对象,然后回调setter。控制流被有效地反转

    4。AOP

    严格来说,AOP与前面的三点几乎没有关系。这个seminal paper on AOP非常通用,它提出了将各种源代码编织在一起(可能用不同的语言表示)以生成一个工作软件的想法

    我不会在AOP上做更多的扩展。这里重要的是,依赖注入和AOP确实可以很好地协同工作,因为它使编织变得非常容易。如果使用IoC容器和依赖项注入来抽象对象的实例化,那么在注入依赖项之前,可以很容易地使用IoC容器来编织方面。否则,这将需要一个特殊的编译或一个特殊的ClassLoader

    希望这有帮助

  4. # 4 楼答案

    与Spring in Action的一个简单比较:

    Whereas DI helps you decouple your application objects from each other, AOP helps you decouple cross-cutting concerns from the objects that they affect.

  5. # 5 楼答案

    这三个概念各不相同,但它们都能很好地协同工作,因此Spring应用程序通常会同时使用所有这些概念。我给你举个例子

    假设我们有一个可以做很多不同事情的web应用程序。我们可以用多种方法构造这个应用程序,但其中一种方法是创建一个类来负责完成这些事情。我们需要从某个地方调用并创建这些类。一种选择是使用一个大的主类来创建这些服务中的一个,打开一个套接字,并在这些服务进入时将调用传递给它们。不幸的是,我们已经创建了一个god类,它有太多的逻辑,并且对我们程序中的一切工作方式知道得太多。如果我们对程序做了任何修改,我们可能需要修改这个类

    而且,它很难测试。如果一个类直接实例化和调用其他类,我们就不能单独测试它。单元测试变得越来越难编写

    解决这个问题的一种方法是使用控制反转。我们说“好吧,这些是服务类。谁提供服务?不是我。”通常,每一个都定义了一个接口,比如LoginService或BillingService。该接口可能有多个实现,但你的应用并不在乎。它只知道它可以要求某种服务或具有某种名称的服务,然后它会得到一些好的回报

    依赖注入允许我们将所有的小片段连接在一起。类具有可访问的字段、构造函数参数或setter方法,这些方法是对它们需要访问的其他组件的引用。这使得单元测试更加容易。您可以创建被测对象,向其抛出模拟或存根依赖项,然后测试该对象在隔离状态下的行为是否正确

    现在,我们真正的应用程序是一个复杂的混乱的片段,所有这些片段都需要连接在一起。有很多方法可以实现这一点,包括允许应用程序进行猜测(“这个类需要一个UserService,我负责的另一个类正好实现了UserService”),或者通过仔细解释它们如何在XML或Java中连接在一起。Spring的核心是一个服务,负责将这些类连接在一起

    现在我们来谈谈AOP。让我们假设,我们有所有这些类,它们以精心设计的方式相互连接。我们可能想用非常笼统的方式来描述一些贯穿各领域的问题。例如,您可能希望在调用任何服务时启动一个数据库事务,并提交该事务,只要该服务不引发异常。事实证明,Spring在执行这样的任务方面处于独特的位置。Spring可以动态创建代理类,实现类所需的任何接口,并将类封装在代理中。现在,IoC和依赖注入当然不是进行面向方面编程所必需的,但这是一种非常方便的实现方式

  6. # 6 楼答案

    让我告诉你一些关于AOP的事情,希望它能让你更容易理解。 AOP最基本的原则是找到返回的常见任务/方面 代码中的许多地方不属于代码的特定业务。例如 写下任何函数的每个入口,或者在创建对象时对其进行包装,或者在调用特定函数时向管理员发送电子邮件。 因此,程序员将不再处理这些非业务方面的问题,而是从他们那里获取信息 我们在幕后管理这些方面。 所有的基本AOP都在一条腿上