想象一下,在Global.asax.cs文件中,我将实例类作为私有字段。我们这样说:
private MyClass _myClass = new MyClass();
我在Global上有一个名为GetMyClass()的静态方法,它获取当前的HttpApplication并返回该实例。
public static MyClass GetMyClass()
{
return ((Global)HttpContext.Current.ApplicationInstance)._myClass;
}
所以我可以通过调用Global.GetMyClass()来获取当前请求httpapplication上的实例。
请记住,有多个(全局)HttpApplication。每个请求都有一个HttpApplication,它们被合并/共享,所以在最真实的意义上它不是真正的singleton。但它确实遵循了这种模式。
所以问到这个问题,你至少会考虑这个单身模式吗?
你会说它不应该被使用吗?你会不鼓励使用它吗?你会说这是一个 可能 糟糕的做法,就像一个真正的单身人士。
您是否可以看到此类使用方案可能出现的任何问题?
或者你会说这不是一个真正的单身人士,所以没关系,也不错。你会推荐这个作为半准单身人士,每个请求需要一个实例吗?如果不是你会使用/给出什么其他模式/建议?
你曾经使用过这样的东西吗?
我在过去的项目中使用了这个,但我不确定这是否应该让我远离。我过去从未遇到任何问题。
请告诉我你对此的想法和意见。
我不是在问单身人士是什么。我认为在使用不当时会出现单身不良行为,这在很多情况下都是如此。那是我。但是,这不是我想要讨论的内容。我试着讨论我给出的这个场景。
答案 0 :(得分:4)
我不是.NET用户所以除了这部分之外我不会对此发表评论:
你会说它的坏习惯就像一个真正的单身人士。
真正的单身人士不是'坏习惯'。他们被严重过度但这不是一回事。我最近读了一些东西(不记得在哪里,唉)有人指出 - “想要或需要”与“可以”。
“我们只想要其中一个”或“我们只需要一个”:不是单身。
“我们只能拥有其中一个”:单身人士
也就是说,如果拥有两个对象的想法会以可怕而微妙的方式破坏某些东西,是的,请使用单例。这种情况比人们想象的要少得多,因此是单身人士的扩散。
答案 1 :(得分:4)
这是否符合Singleton的切割模式,它仍然遇到与Singleton相同的问题:
答案 2 :(得分:3)
Singleton是一个对象,其中只有一个。
现在恰好是一个对象的对象不是单身。
答案 3 :(得分:2)
由于您正在讨论Web应用程序,因此您需要非常小心地假设任何具有静态类或此类伪单例的内容,因为正如David B所说,它们仅在该线程中共享。如果IIS配置为使用多个工作进程(配置名称为“Web-Garden”模式,而且可以在machine.config中设置#工作进程),则会遇到麻烦。假设盒子有多个处理器,无论谁试图调整它的性能都必然会打开它。
这种事情的一个更好的模式是使用HttpCache对象。它本质上已经是线程安全的,但是仍然能够捕获大多数人的是对象也需要是线程安全的(因为你可能只是创建实例然后随着时间的推移读/写它的很多属性)。这是一些骨架代码,可以让您了解我在说什么:
public SomeClassType SomeProperty
{
get
{
if (HttpContext.Current.Cache["SomeKey"] == null)
{
HttpContext.Current.Cache.Add("SomeKey", new SomeClass(), null,
System.Web.Caching.Cache.NoAbsoluteExpiration, TimeSpan.FromDays(1),
CacheItemPriority.NotRemovable, null);
}
return (SomeClassType) HttpContext.Current.Cache["SomeKey"];
}
}
现在,如果您认为可能需要Web场(多服务器)扩展路径,那么上述操作将无法正常工作,因为不会跨机器共享应用程序缓存。
答案 4 :(得分:1)
暂时忘记单身。
您有返回应用程序状态的静态方法。你最好小心。
如果两个线程访问此共享状态...繁荣。如果你住在网络服务器上,你的代码最终将在多线程环境中运行。
答案 5 :(得分:0)
我会说它绝对不是单身人士。设计模式作为常见编码实践的定义最有用。当你谈论单身人士时,你谈论的是一个只有一个实例的对象。
正如您自己所说,有多个HttpApplications,因此您的代码不遵循Singleton的设计,并且没有相同的副作用。
例如,可以使用单身人士来更新货币汇率。如果这个人在不知不觉中使用了你的例子,那么他们会启动7个实例来完成“只有一个对象”的工作。