当前位置: 首页 > 面试题库 >

使用servicelocation而不是构造函数注入来避免编写工厂类的负载是否不好

丁曦
2023-03-14
问题内容

现在我们使用DI / IOC,当我们需要将额外的参数传递给构造函数时,我们使用工厂类,例如

public class EmailSender 
{
    internal EmailSender(string toEmail, string subject,String body, ILogger emailLogger)
    {.....} 
}

public class EmailSenderFactory
{
    ILogger emailLogger;
    public EmailSenderFactory(ILogger emailLogger)
    { 
        this.emailLogger = emailLogger;
    }
    public EmailSender Create(string toEmail, string subject, string body) 
    {
        return new EmailSender(toEmail, subject, body, emailLogger);
    }
}

现在的问题是,我们最终创建了整个lotta工厂类,而人们并不总是知道要使用它们(有时他们自己来创建它们)。像这样编写类的最大缺点是什么:

public class EmailSender 
{
    EmailLogger logger = IoC.Resolve<ILogger>();
    internal EmailSender(string toEmail, string subject,String body)
    {.....} 
}

Pro:现在,我们可以安全地使用构造函数,而无需工厂类了。Con:我们必须引用Service
Locator(我不担心可测试性,它易于使用模拟容器作为容器的后备服务)。

是否有一些令人讨厌的理由说明为什么我们不应该这样做?

编辑:经过一番思考,我想通过拥有一个私有的构造函数,并嵌套Factory类,可以使实现和工厂保持在一起,并防止人们不正确地创建类,所以这个问题有些不切实际。
关于SL脏的所有要点当然都是对的,因此以下解决方案使我感到高兴:

public class EmailSender 
{
    public class Factory
    {
        ILogger emailLogger;
        public Factory(ILogger emailLogger)
        { 
            this.emailLogger = emailLogger;
        }
        public EmailSender Create(string toEmail, string subject, string body) 
        {
            return new EmailSender(toEmail, subject, body, emailLogger);
        }
    }
    private EmailSender(string toEmail, string subject,String body, ILogger emailLogger)
    {
    } 
}

问题答案:

是的-这很糟糕。

  • 当框架可以工作时,为什么还要编写所有这些代码?所有的IoC.Resolve()调用都是多余的,您不必编写它们。
  • 另一个甚至更重要的方面是您的组件与服务定位器绑定在一起。

现在,您无法像这样实例化它们-每次需要使用组件时,都需要一个完全设置好的服务定位器。

  • 最后,但至少是机器人,您的SL代码会散布在整个代码库中,这不是一件好事,因为当您要更改某些内容时,必须在多个位置进行查找。


 类似资料:
  • 问题内容: 我在这里找不到任何合理的答案,所以我希望它不会重复。那么为什么我应该更喜欢setter或构造函数注入而不是简单注入 如果您在类初始化期间需要对注入的bean进行某些操作,则可以使用构造函数注入的用法 但是仍然,它几乎和方法一样,并且我完全不会进行setter注入,这不只是Spring和其他DI框架之后的遗物吗? 问题答案: 构造函数和属性注入使您可以轻松地在非CDI环境中(例如,单元测

  • 我需要重构现有的抽象类来实现依赖注入,但是这个类有两个接受其他参数的构造函数。 我需要注入一些接口,并避免在构造函数中传递任何其他参数,如“settingsId”和“Setting”。所以我的想法是在创建此类的实例后创建两种方法来设置这些参数。 但它看起来不是一个合适的解决方案,因为如果开发人员忘记在创建实例后运行这些方法之一,我们将来可能会得到一个异常(对象未设置为引用...)。我应该如何正确执

  • 问题内容: 类允许客户获得实例的通常方法是提供一个公共构造器。另一种方法是提供一个公共的静态工厂方法,该方法只是一个返回类实例的静态方法。使用静态工厂方法的优缺点是什么? 问题答案: 《有效Java》一书中的这一章对此进行了很好的解释:考虑使用Static Factory而不是Constructors 。它以您可以理解的最佳方式说明了它们各自的优缺点。 只是引用本书的优点和缺点: 优点 : 静态工

  • 问题内容: 为什么,,,等对象使用一个工厂方法而不是构造的? 我找到了为什么应该使用工厂方法而不是 [此处的解释。这个答案给出了很多原因,但是与Java日期/时间API相关的唯一事情是: 与构造函数不同,它们不需要在每次调用时都创建一个新对象 因为和是不可变的,所以使用工厂并重用现有对象而不是每次都创建新对象可能是有意义的。 这是为什么要使用工厂方法(例如)创建和创建对象的原因吗?还有其他原因吗?

  • 在Dart中,工厂构造函数需要编码器提供更多逻辑,但与常量构造函数没有太大区别,只是它们允许“非最终”实例变量。 与const Constructor相比,它们有哪些优点? 谢谢大家。 编辑 下面是关于Seth Ladd博客“Dart-试图理解“工厂”构造函数的价值”中工厂构造函数的用法。 恕我直言,使用通用构造函数,可以通过细微的差异实现相同的效果,但相当简单。 如上所示,尽管这两个实例 所以,

  • 问题内容: 我发现我的构造函数开始看起来像这样: 不断增加的参数列表。由于“容器”是我的依赖项注入容器,所以为什么我不能这样做: 每堂课?不利之处是什么?如果执行此操作,则感觉就像我在使用精美的静态方法。请分享你对IoC和依赖注入疯狂的想法。 问题答案: 正确的是,如果将容器用作服务定位器,则它或多或少是光荣的静态工厂。由于种种原因,我认为这是一种反模式。 构造函数注入的奇妙好处之一是,它使违反单