【问题标题】:Factory class vs Spring DI工厂类 vs Spring DI
【发布时间】:2011-08-28 15:42:37
【问题描述】:

据我了解,Factory 类和 Spring DI 都遵循依赖注入。我的意思是在这两种情况下,外部实体都用于推送依赖项。 对吗? 我的问题是当我的意图只是获取对象时,我应该在工厂类和 Spring DI 之间选择哪一个。假设我不想要任何其他功能,如 aop、dao 支持等。唯一的目的是从 Factory 类或 Spring DI 获取对象。哪个更可取。

在某些网站上阅读此声明

与工厂类相比,DI 松耦合且侵入性更小

但无法理解 spring DI 如何松散耦合并且比工厂类更少侵入性? 在这两种情况下,我们都必须在核心程序中插入某种获取目标代码。

【问题讨论】:

  • “只是为了获取对象”?真的吗?对他们没有行为?然后就做new Object()。 (告诉我们更多关于正在发生的事情,以便我们知道如何提出有用的建议。Spring 广泛使用工厂模式等。)

标签: java spring design-patterns dependency-injection


【解决方案1】:

Spring DI 提倡松散耦合的代码,因为 Spring 容器会根据配置注入您的依赖项。如果您要注入接口实现,则无需更改代码即可更改注入的特定实现,除非您考虑配置代码,很多人都会这样做。

如果您使用工厂创建配置的对象供其余代码使用,那么您就是在编写代码来创建对象、配置它们等。如果您想更改工厂返回的内容,则必须进行更改实际代码,有些人会认为这是一个更具侵入性的更改。

Spring 通常用于配置应用程序的各个层如何连接在一起。例如,X 服务采用这样那样的 DAO 实现。那是应用程序级别的组织。假设您有一个场景,想要为列表中的每一行创建一个按钮——在这种情况下,您可以使用工厂来创建按钮。此方案基于运行时情况,其中 GUI 具有您无法预先配置的不同元素(因为它基于数据),因此 DI 在这里意义不大。

编辑 - 根据您的评论问题,我认为这里的主要观点是您必须考虑的是 Spring 也是一个 控制反转 容器。这意味着您无需对应用程序中的哪些组件进行编程。如果没有 IoC,你可能会做类似的事情

MyServiceImpl extends MyService {
    Dao1 = new Dao1Impl(); // you programmatically configure which components go in here
    Dao2 = new Dao2Impl();
    ....
}

相反,您会做类似的事情

MyServiceImpl extends MyService {
    public Dao1;  // you haven't specified which components, only interfaces
    public Dao2;
    ....
}

在第二个代码示例中,Spring(或您使用的任何东西)将为您注入适当的 DAO 实例。您已将使用哪些组件的控制移至更高级别。所以 IoC 和 DI 齐头并进,IoC 促进松散耦合,因为在您的组件定义(即接口)中您只指定行为。

换句话说,IoC 和 DI 不是松散耦合所必需的;您也可以与工厂进行松散耦合

MyServiceImpl extends MyService {
    public dao1 
    public dao2;

    MyServiceImpl(){
       dao1 = DaoFactory.getDao1();
       ...
    }
    ....
}

这里您的服务仍然只依赖于 DAO定义,并且您使用工厂来获取实现。需要注意的是,您的服务现在已与工厂耦合。如果需要,您可以通过将工厂传递给构造函数来使其更加松散......

另外,别忘了 Spring 提供了其他有用的功能,比如它的事务管理。这非常有用,即使您说您的应用程序不需要它。

【讨论】:

  • 感谢您的回复。我对您的解释有进一步的疑问,Para1:-in spring 如果我们要更改接口实现,那么我们必须在配置文件中进行更改,但在工厂类的情况下我们必须对工厂类本身进行更改。你是说在这里更改配置文件比工厂类更容易。但是它如何使它更加有损耦合,因为在这两种情况下,我们都在对外部组件进行更改,无论是配置文件还是工厂类......
  • continued..Para2:-如果要更改工厂返回的内容,则必须更改实际代码。希望您在说实际代码时在这里说工厂类代码。但是在弹簧的情况下di 我们还必须在配置文件中进行更改。为什么比工厂类的侵入性更小?第 3 段:-您是说这里是为了解决运行时依赖关系,我们不能使用 spring DI,而是必须使用工厂类。如果是,它将在stackoverflow.com/questions/7221615/… 回答我的另一个问题
  • @mohit 1)。 only 如果您更改类名或 Spring 构造实例需要哪些参数,则必须更改配置 2)“更改工厂返回的内容”与更改您想要的类相同,所以使用 Spring,您必须更改配置 3) 我不是说,如果您愿意,您可以很容易地获取 applicationContext 并以这种方式抓取对象,然后配置它们。
  • 非常感谢。你能帮我在stackoverflow.com/questions/7221615/…发帖吗?我急需这个基础。在此先感谢
【解决方案2】:

但无法理解 spring DI 如何松散耦合且侵入性更小 比工厂课?在这两种情况下,我们都必须插入某种 在我们的核心程序中获取目标代码。

Spring 减少了干扰,因为它使用反射来自动“注入/创建”依赖项。因此,您的代码不需要对工厂的引用。

Spring 通常用于“类单例”对象的创建。人们通常使用自定义工厂来创建临时丢弃对象(如请求对象)。 事实上,很多时候你会让 Spring 创建并注入你的自定义工厂(即工厂的工厂)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多