3

检查以下简化的示例代码:

public class RequestManager
{
    public RequestManager()
    {

    }

    public void ProcessRequest(byte[] data)
    {
        IRequest request = new Request(data);
        request.Send();
    }
}

当我发现自己使用此代码能够对其进行测试时,我以:

public class RequestManager
{
    private IRequestFactory requestFactory;

    public RequestManager(IRequestFactory requestFactory)
    {
        this.requestFactory = requestFactory;
    }

    public void ProcessRequest(byte[] data)
    {
        IRequest request = this.requestFactory.CreateRequest(data);
        request.Send();
    }
}

CreateRequest 方法只有新的 Request(data) 所以我可以模拟工厂并返回一个模拟。

问题是我开始有很多工厂来完成如此简单的任务,我想知道这是否正常,或者是否有模式或其他方法可以帮助我克服这个问题。

有任何想法吗?提前致谢。

4

2 回答 2

2

这不仅是正常的,而且是体面设计的标志。在正确应用 DI 的应用程序中,您不需要工厂:

  • 从依赖注入容器解析的对象
  • POCO/DTO(因为它们是简单的价值存储)
  • 在大多数情况下,.NET BCL 对象(尽管这可能会有所不同)

对于其他一切,工厂是一个不错的选择。为什么?

  • 它提供了统一的对象创建方式(让整个团队都知道当你需要IRequest实例时,你应该注入IRequestFactory
  • 它不会引发任何不必要的问题(比如“我应该SomeProperty在创建后设置吗?”“我应该使用哪个构造函数?Factory.CreateInstance()简单直观 - 无需解释任何事情,所有决定都已经做出并嵌入到工厂本身中)
  • 它与模拟结合极大地简化了单元测试(尤其是当无法轻松地用假数据创建实际对象时)

撇开单元测试不谈,当您在 3、6、12 个月后返回代码时,前两点会带来极大的好处——工厂可以开发人员不必对不应该首先做出任何决定的事情做出决定。

无需担心要使用哪个构造函数以及要传递哪些参数,您可以使用非常简单的合约来回答所有可能的问题,并且作为开发人员,您可以专注于实际问题。

于 2013-10-16T16:19:57.393 回答
1
IRequest request = new Request(data);

这条线与依赖注入完全相反。它是硬编码的依赖关系。这一行将RequestManagerRequestIRequest.

也许试试这个:

public void ProcessRequest(IRequest request)
{
   request.Send();
}

这样,就RequestManager不必了解 IRequest 实现。你可以给它一个模拟对象/存根,它甚至不会有任何感觉!当然,这意味着创建它的类RequestManager需要知道这种依赖关系。RequestManager但是,嘿,你可以用类似的方式把它交给它!

最后,所有的依赖都集中在一个点上。通常我们使用一些框架来为我们处理连接在一起的事情,例如基于 XML 文件。

依赖注入的全部意义在于通过 setter 或构造函数参数提供所需的具体对象。依赖注入框架允许您将依赖关系集中在一个地方,您可以轻松地将提供的具体类更改为需要它们的其他类。这样你也可以在测试中设置使用模拟对象——非常方便!

在这里你可以找到一篇关于依赖注入的精彩文章

于 2013-10-16T15:24:50.243 回答