1

我正在尝试练习Dependency Injection 的原则,但我在这样做时遇到了一些困难。

我有一个函数可以定期访问我的数据库,检索产品列表,然后针对这些产品运行一系列测试以确定它们的安全性。

如果发现一种或多种产品不安全,我需要通过实例化和调度ProductRecall对象来发出召回。

该函数看起来像这样:(伪代码)

void SafteyInspector::CheckProductSaftey()
{
  database.getProducts( list_of_products )

  foreach( list_of_products as p )
  {
    if ( !runBatteryOfTests( p ) )
      unsafe_products.insert( p );
  }

  if ( !unsafe_products.empty() )
  {
    ProductRecall * recall = 
          new ProductRecall( unsafe_products );  // Oh no!
    recall->dispatch();
  }
}

问题是我在ProductRecall调用图的中间“新建”了一个对象。这违反了依赖注入的原则。如所写,我无法在CheckProductSaftey()不创建ProductRecall对象的情况下进行测试。

但是,我不能将ProductRecall对象传递给我的SafetyInspector对象,因为它SafetyInspector是确定不安全产品列表的人。

我正在对所有内容使用构造函数注入,并且我想继续这样做。另请注意,我可能ProductRecalls随时发出多个,因此我不一定只将单个ProductRecall对象传递给SafetyInspectorat 构造。

有什么建议么?谢谢!

4

2 回答 2

1

我认为您实际上需要变出某种方式ProductRecallFactory来代替。注入容器支持某种工厂风格的界面是相当普遍的,或者您可能只想让您的 SafetyInspector 容器感知。

编辑:通过“容器感知”,我指的是按照 COM 的线实现一些接口IObjectWithSite,以便您的对象可以回调其父对象。这是一种较弱的依赖注入形式,可以部分撤销控制反转。如果您手动进行依赖注入,请务必注入工厂对象。

于 2009-04-27T21:23:20.890 回答
1

我认为问题可能出在您的ProductRecall. 具体来说,如果您可以调用dispatch()新创建的对象,则意味着许多实际功能要么隐藏在ProductRecall类中,要么ProductRecall类具有静态成员和/或单例以提供它所需的一切。

我建议创建一个名为的类ProductRecallDispatcher来处理实际调度的复杂性。然后,您将创建这些对象之一,并将其​​传递给SafteyInspector. 这将使您的CheckProductSafety函数如下所示:

void SafteyInspector::CheckProductSaftey()
{
  database.getProducts( list_of_products )

  foreach( list_of_products as p )
  {
    if ( !runBatteryOfTests( p ) )
      unsafe_products.insert( p );
  }

  if ( !unsafe_products.empty() )
  {
    recallDispatcher.recall( unsafe_products );
  }
}
于 2009-04-27T21:37:04.473 回答