1

假设您有某种工厂创建的资源在构建后仍属于工厂,如下所示:

public class Resource : IDisposable {
  public void Dispose() { /* ... */ }
}

public class ResourceManager : IDisposable {
  public Resource Load() { /* create resource and add to list */ }
  public void Dispose() { /* dispose all loaded resources in list */ }
}

现在你有一个基类,它需要Resource在其构造函数中初始化一个实例:

public class Fooificator {
  public Fooificator(Resource resource) {
    this.resource = resource;
  }
  private Resource resource;
}

从这样的基类派生的类如何在Resource不丢失对工厂的引用的情况下构造 a ?

使用静态方法的天真方法无法记住工厂(除了丑陋的黑客攻击,例如将其存储在静态字段中以便构造函数在基类构造完成后拾取,或者使用两阶段Resource初始化通过构造函数调用的Initialize()方法提供给基类​​)

public class DefaultFooificator : Fooificator {
  public DefaultFooificator() : base(loadDefaultResource()) {}

  private static Resource loadDefaultResource() {
    ResourceManager resourceManager = new ResourceManager();
    return resourceManager.Load();
    // Bad: losing reference to ResourceManager here!
  }
}

一种可能的解决方法是命名构造函数习语:

public class DefaultFooificator : Fooificator, IDisposable {

  public static DefaultFooificator Create() {
    ResourceManager resourceManager = new ResourceManager();
    DefaultFooificator fooificator = new DefaultFooificator(
      resourceManager.Load()
    );
    fooificator.resourceManager = resourceManager;

    return fooificator;
  }

  private DefaultFooificator(Resource resource) : base(resource) {}
  private ResourceManager resourceManager;
}

但是,在解决存储ResourceManager引用的问题时,这将不允许进一步的类从DefaultFooificator.

是否有任何优雅的解决方案可以让我进一步从参考中派生DefaultFooificator或以ResourceManager其他方式存储参考?

4

2 回答 2

1

为什么派生自的类Fooificator要负责构造一个Resource?为什么你不能把这个依赖注入到它的构造函数中?

public class DefaultFooificator : Fooificator
{
    public DefaultFooificator(Resource resource) : base(resource) {}
}

您可以将资源的创建推迟到FooificatorFactory.

于 2009-08-25T10:18:14.897 回答
1

我认为你应该考虑你的类是否不是太紧耦合。如果 Resource 有一个公共构造函数,那么每个人都可以创建一个实例并将其作为引用传递给 Fooificator 构造函数。这实际上是一件好事。

看起来不那么吸引人的是,您似乎有一个要求,即只有由 ResourceManager.Load 创建的资源(顺便说一句,这违反了命令/查询分离)才能合法使用。但是,API 不会强制执行此约束。

您应该通过将 Resource 构造函数设置为内部或解除 ResourceManager 约束来强制执行此约束。

内部构造函数倾向于拉紧类耦合的方向,所以我会认真考虑第二种选择。

或者,更改 Fooificator 的构造函数以获取对 ResourceManager 的引用,或者可能是Func<ResourceManager, Resource>.

我认为,如果没有更多上下文,很难给出更好的答案。

于 2009-08-25T10:27:35.207 回答