AS3:静态类与单例模式

6

我知道Stack Overflow的朋友们不喜欢"对比"的问题,但是......即使稍微改一下标题,"对比"部分仍然存在,那么为什么要隐藏它呢。

基本上,我想知道何时以及为什么应该使用单例模式或静态类,单例模式能提供什么静态类不能提供的东西,反之亦然。

很长一段时间我都使用了两种模式,但我看不出为什么我不应该使用其中的一个。

谢谢。


1
你能详细说明一下“静态类”构造吗?因为据我所知,“public static class”在AS3中尚不支持。 - Yordan Yanakiev
1
当然,我的意思是,拥有一个具有静态方法和变量的类。 - Artemix
1个回答

8

这两者基本上都是带有注意事项的全局变量。静态类防止继承,而单例模式则不美观,且会在属性查找时增加开销。这两者都会使自动化测试变得困难。

AS3支持全局变量,那为什么不使用它们呢?

静态:

package com.example
{
    public class Config
    {
        public static var VERSION:uint = 1;
    }
}

单例模式:

package com.example
{
    public class Config
    {
        public static var instance:Config = new Config();

        public var version:uint = 1;

        public function Config()
        {
            //Boiler plate preventing multiple instances
        }
    }
}

全局变量:
package com.example
{
    public var config:Config = new Config();
}
class Config
{
    public var version:uint = 1;
}

现在,假设你的生产应用程序只需要类的单个实例,但是你需要多个实例来编写测试。你可以创建一个公共类Config,并使用com.example.config = new Config()来重置。所有引用全局变量的地方现在都使用新的实例,并且您甚至可以进行继承等高级操作。
例如:
if(inDebugMode)
{
    com.example.config = new DebugConfig();
}
{
    com.example.config = new Config();
}

1
全局变量是最终的副作用,容易出错且难以调试。它们使您的代码变得僵硬和脆弱,因为许多类都依赖于变量始终存在于同一位置。永远不要使用它们!相反,考虑使用依赖注入(例如,通过http://swiftsuspenders.org/),这也可以让您创建“单例”,允许继承并保持类之间的良好解耦。 - weltraumpirat
我同意通常情况下全局状态是不好的,但是我认为对于像日志记录器或实用程序这样的东西,全局变量比依赖注入更好。 - Sean Fujiwara
1
全局变量从来都不是最好的选择。将记录器放在全局中可能看起来更容易,代码也更少,但它也会在整个代码库中创建一个严格的依赖关系。使用ILogger接口,注入实现 - 您可以通过修改配置随时交换记录器,而无需重新编译所有库。 - weltraumpirat
2
你可以使用全局变量来实现,就像我回答的最后一部分所示。在每个类中注入ILogger并不是非常优雅或易读的方式。 - Sean Fujiwara
不,你不能这样做。使用全局变量将导致所有类都依赖于Logger的二进制文件,以及记录器实例存储的具体地址空间。假设你有一个客户端希望稍微不同的设置,出于任何原因 - 现在你必须去改变你的所有类。注入ILogger可能看起来不太优雅,但如果你需要改变任何东西,你会注意到什么是真正的优雅:保持你的类良好解耦和封装。我拒绝可读性部分:每个类多一行代码。 - weltraumpirat
我是说, [Inject] public var log:ILogger; 怎么可能不易读呢? - weltraumpirat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接