次のように、建設後もファクトリーに属している何らかの種類のファクトリー作成リソースがあると仮定します。
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 を構築するにはどうすればよいでしょうか?
静的メソッドを使用する素朴なアプローチには、ファクトリを記憶する方法がありません (基本クラスの構築が終了した後にコンストラクターが取得できるように静的フィールドに格納する、または 2 段階の初期化を使用するなどの醜いハックを除く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!
}
}
考えられる回避策の 1 つは、名前付きコンストラクターのイディオムです。
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