【发布时间】:2022-01-04 11:09:39
【问题描述】:
假设我有一个基于一次性资源创建服务的工厂。 我认为第一个解决方案是最干净的,但我无法弄清楚如何在我的情况下处理“实例”。 第二个将是一个解决方案,但可以称为工厂吗?我不这么认为,因为它拥有适当的资源。 此外,“DisposableIOResource”是一种很难创建的服务,您只想躲在工厂后面。 有解决这种情况的好模式吗? 在我的两个草稿 sn-ps 下方。
// first solution
public class ServiceFactory
{
public Reader CreateReader(string configuration)
{
var instance = new DisposableIOResource(configuration);
return new Reader(instance);
}
}
// first solution - use case
var serviceFactory = new ServiceFactory();
var reader = serviceFactory.CreateReader(configuration)
reader.DoSomething(); // NOTE! How do I dispose 'instance'???
// second solution
public class ServiceFactory : IDisposable
{
private readonly DisposableIOResource _instance;
public ServiceFactory(string configuration)
{
_instance = new DisposableIOResource(configuration);
}
public Reader CreateReader()
{
return new Reader(_instance);
}
public void Dispose()
{
_instance.Dispose();
}
}
// second solution - use case
using(var serviceFactory = new ServiceFactory(configuration))
{
var reader = serviceFactory.CreateReader():
reader.DoSomething();
}
--- 编辑 我最终找到了另一种解决方案,也许是更清洁的解决方案:
public interface IDisposableIOResourceFactory
{
DisposableIOResource Create();
}
public class DisposableIOResourceFactory : IDisposableIOResourceFactory
{
private readonly string _configuration;
public DisposableIOResourceFactory(string configuration)
{
_configuration = configuration;
}
public DisposableIOResource Create()
{
return new DisposableIOResource(this._configuration);
}
}
// third solution
public class ServiceFactory
{
public Reader CreateReader(IDisposableIOResourceFactory resourceFactory)
{
return new Reader(resourceFactory);
}
}
public class Reader
{
public Reader(IDisposableIOResourceFactory resourceFactory) {}
public void DoSomething()
{
using var resource = resourceFactory.Create();
// work on resource
}
}
// first solution - use case
var serviceFactory = new ServiceFactory();
var resourceFactory = new DisposableIOResourceFactory();
var reader = serviceFactory.CreateReader(resourceFactory);
reader.DoSomething();
【问题讨论】:
-
在我看来,Reader 类应该实现 IDisposable。你想达到什么目的?
-
两者在技术上都是工厂,但您的第二个实现使用通常与工厂不重合的单例模式。我不会过多关注标签,而是代码为您做了什么,以及它解决了哪些问题。
-
using var reader = serviceFactory.CreateReader(configuration);然后Reader负责处理它的任何内部资源。 -
工厂无法猜测消费者何时使用完对象。因此,它必须是实现 IDisposable 的 Reader 类。
-
@Zoidbergseasharp 让我深入探讨我的问题。只需将“阅读器”视为 DisposableIOResource 上的适配器,它确实可以帮助您阅读该资源。现在,工厂的最终用户不知道如何构建该资源,因此您不能只要求他创建 DisposableIOResource。在这种情况下,唯一知道如何创建它的是工厂,但在这种情况下,“你如何处理这个对象 Dispose”?
标签: c# factory disposable