无需使用Singleton即可封装昂贵的资源 [英] Encapsulating an expensive resource without using a Singleton

查看:48
本文介绍了无需使用Singleton即可封装昂贵的资源的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在努力更新遗留有Singleton类的遗留应用程序.一个完美的例子是SnmpConnector类:

I am working on updating a legacy application that is absolutely rife with Singleton classes. A perfect example would be the SnmpConnector class:

public SnmpConnector
{
  public static IEnumerable<string> HostIpAddresses
  {
    ...
  }

  private static SnmpConnector instance;
  public static SnmpConnector Instance
  {
    if (instance == null)
      instance = new SnmpConnector();
    return instance;
  }

  private SnmpConnector()
  {
    foreach (string IpAddress in HostIpAddresses)
    {
      ...
    }
  }

  ...
}

此更新的目标是提高代码库的可测试性,因此,我希望摆脱Singletons.我已经提取了SnmpConnector的数据源,以便从测试数据库或查询实时服务器中获取数据:

The goal of this update is to increase testability of the codebase, and as such I want to get rid of the Singletons. I've already abstracted away the data source of the SnmpConnector to either get data from a test database or from querying a live server:

public interface ISnmpDataSource
{
  public DataTable MacTable
  {
    get;
    private set;
  }

  public DataTable PortTable
  {
    get;
    private set;
  }

  ...
}

public TestSnmpDataSource : ISnmpDataSource
{
  public FileInfo DataSource
  {
    get;
    private set;
  }

  ...
}

public SnmpDataSource : ISnmpDataSource
{
  public List<string> HostIpAddresses
  {
    get;
    private set;
  }

  ...
}

public SnmpConnector
{
  public SnmpConnector(ISnmpDataSource DataSource)
  {
    ...
  }

  ...
}

现在,我正在尝试测试这些组件,并且首先遇到了可能导致SnmpConnector成为Singleton的问题:测试SnmpDataSource花费的时间不多.事实证明,从实时交换机中获取MAC表和端口表大约需要10到20秒.我已经为该特定类编写了13个单元测试,因此仅需两分钟即可完成这些测试.令人讨厌的是,一旦这些更新发布到我们的原始代码库中,情况将变得更糟.通过这种新的重构,没有什么可以阻止程序员重复创建和丢弃SnmpDataSource的.

Now, I'm trying to test these components and running into the problem that probably caused SnmpConnector to be a Singleton in the first place: it takes an ungodly amount of time to test the SnmpDataSource. It turns out that fetching the MAC table and Port table from live switches takes somewhere between 10 and 20 seconds. I've already written 13 unit tests for this particular class, so it takes over two minutes for just these tests to complete. As annoying as this is, it gets worse once these updates get published to our original codebase. With this new refactoring, there is nothing stopping a programmer from creating and discarding an SnmpDataSource repeatedly.

现在,这些表中的数据基本上是静态的;旧的Singleton和新的SnmpDataSource都维护一个仅每四个小时更新一次的缓存.我是否必须使SnmpDataSource成为Singleton才能防止此问题?

Now, the data from these tables is largely static; the old Singleton and the new SnmpDataSource both maintain a cache that was only updated every four hours. Will I have to make SnmpDataSource a Singleton to prevent this problem?

推荐答案

使用依赖注入,或者将 SnmpDataSource 传递给需要它的任何东西,或者可能传递 Func< SnmpDataSource>; ,可以根据需要延迟创建实例.

Use dependency injection, and either pass the SnmpDataSource into anything that needs it, or potentially pass in a Func<SnmpDataSource> which can create the instance lazily as necessary.

您的目标是 SnmpDataSource 自身进行更新,还是在几个小时后调用方将获得新版本?

Is your goal that the SnmpDataSource should update itself, or that callers will get a new version after a few hours?

这篇关于无需使用Singleton即可封装昂贵的资源的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆