【发布时间】:2015-05-28 04:38:41
【问题描述】:
我正在.NET 中编写 PCL,并且我有一个围绕 HttpClient 的包装类,它以多种不同的方法从 URI 加载 HtmlAgilityPack.HtmlDocument。它是无状态,所以我真的很想将其设为静态,因为在我看来,用new 实例化某些东西给人的印象是它包含状态。但是,我有几个我希望它继承的接口,所以它不能是静态的。这就是我想让它成为单例的地方。以下是代码中的一些 sn-ps:
public class ConcurrentClient : IAsyncClient<HtmlDocument>
{
private static readonly ConcurrentClient _Instance = new ConcurrentClient();
private ConcurrentClient() { }
public static ConcurrentClient Instance
{
get { return _Instance; }
}
public HtmlDocument LoadUri(string uri)
{
return LoadUriAsync(uri).Result;
}
// ...
public async Task<HtmlDocument> LoadUriAsync(string uri,
Encoding e, NetworkCredential creds, Action<HtmlDocument> prehandler)
{
// ...
}
}
不过,我想知道是否应该将开头部分更改为:
private static readonly ConcurrentClient _SharedInstance = new ConcurrentClient();
public static ConcurrentClient SharedInstance
{
get { return _SharedInstance; }
}
原因是我不太确定是否使用 Singleton 模式,主要是因为我很少在其他库中看到它使用它(可能是 WinRT 的Application.Current?),我认为它会鼓励用户我的 PCL 来编写耦合代码,因为在任何地方都调用 ConcurrentClient.Instance 比将其作为参数传递要容易得多。
但是,我确实想鼓励使用共享实例,因为除了上述原因之外,调用new ConcurrentClient() 没有什么意义,因为它所做的只是产生更多的内存开销。另外,我想不出更好的方法来使用不真正依赖状态的方法来实现继承。
【问题讨论】:
-
你有一个陷阱:你正在使用单例。解释你的真正问题以及为什么你认为使用单例是解决方案会更好,我们可能会向你推荐一些不同的东西。
-
我看不到任何澄清。要解决的真正问题或用例是什么?为什么你认为使用单例会解决它?为什么不使用具有状态但不可变类的不同设计来保证设计线程的安全?
-
如果有一个公共构造函数,它根本就不是一个单例。是的,你有一个公开可用的共享实例,但你并没有阻止其他人被创建——所以我就把它留在那里。不要费心称它为单例。
-
是否有公共构造函数根本不是OP的问题,他只是在问单例作为模式是否是一个好的选择。如果我们说没关系,我相信他会将构造函数设为私有并使其成为适当的单例
标签: c# oop design-patterns singleton