你会认为这是一个单身/单身模式吗?

时间:2008-10-09 00:12:02

标签: asp.net design-patterns

想象一下,在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。但它确实遵循了这种模式。

所以问到这个问题,你至少会考虑这个单身模式吗?

你会说它不应该被使用吗?你会不鼓励使用它吗?你会说这是一个 可能 糟糕的做法,就像一个真正的单身人士。

您是否可以看到此类使用方案可能出现的任何问题?

或者你会说这不是一个真正的单身人士,所以没关系,也不错。你会推荐这个作为半准单身人士,每个请求需要一个实例吗?如果不是你会使用/给出什么其他模式/建议?

你曾经使用过这样的东西吗?

我在过去的项目中使用了这个,但我不确定这是否应该让我远离。我过去从未遇到任何问题。

请告诉我你对此的想法和意见。

我不是在问单身人士是什么。我认为在使用不当时会出现单身不良行为,这在很多情况下都是如此。那是我。但是,这不是我想要讨论的内容。我试着讨论我给出的这个场景。

6 个答案:

答案 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个实例来完成“只有一个对象”的工作。