IDisposable的Flyweight和Factory问题

Joh*_*ell 11 c# idisposable factory-pattern flyweight-pattern

我似乎在精神上陷入了Flyweight模式的困境.

首先,假设我有一次性用品DisposableFiddle和工厂FiddleFactory:

public interface DisposableFiddle : IDisposable
{
    // Implements IDisposable
}

public class FiddleFactory
{
    public DisposableFiddle CreateFiddle(SomethingThatDifferentiatesFiddles s)
    {
        // returns a newly created fiddle.
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,在我看来,客户很清楚FiddleFactory工厂声称没有创建小提琴的所有权,并且客户有责任在完成它时处理小提琴.

但是,让我们说我想通过使用Flyweight模式在客户端之间共享小提琴:

public class FiddleFactory
{
    private Dictionary<SomethingThatDifferentiatesFiddles, DisposableFiddle> fiddles = new ...;        

    public DisposableFiddle CreateFiddle(SomethingThatDifferentiatesFiddles s)
    {
        // returns an existing fiddle if a corresponding s is found,
        // or a newly created fiddle, after adding it to the dictionary,
        // if no corresponding s is found.
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我觉得道德上有义务让工厂本身是一次性的,因为它创造了小提琴,并在他们的一生中保持对它们的引用.但这会给假定他们拥有小提琴的客户带来问题,因此应该处理它们.

问题实际上是我叫工厂FiddleFactory而不是,比如说FiddlePool,和"创造"方法CreateFiddle而不是GetFiddle?像这样:

public class FiddlePool : IDisposable
{
    private Dictionary<SomethingThatDifferentiatesFiddles, DisposableFiddle> fiddles = new ...;        

    public DisposableFiddle GetFiddle(SomethingThatDifferentiatesFiddles s)
    {
        // returns an existing fiddle if a corresponding s is found,
        // or a newly created fiddle, after adding it to the dictionary,
        // if no corresponding s is found.
    }

    // Implements IDisposable
}
Run Code Online (Sandbox Code Playgroud)

然后对客户来说更清楚的是它不会拥有返回的小提琴,并且游泳池有责任处理小提琴.

或者这只能在文档方面轻松解决吗?

有没有办法摆脱困境?甚至有两难吗?:-)

Jef*_*nal 7

我可以看到两个解决这个问题的方法:

  • ThreadPool风格:重新设计类,以便FiddlePool提供一个界面来做繁琐的事情.池不会分发Fiddle实例,因为它有一个FiddlePool.PlayFiddle方法.由于池控制了生命周期,因此它负责处理它们.

  • SqlConnection的风格:修改Fiddle的公共Dispose方法,以便它真的只是返回小提琴的小提琴池(其中小提琴类封装).在内部,小提琴池负责真正释放一次性资源.