0

这在 actionscript 中作为 Singleton 是否有效?即是否有任何我应该注意的问题,在这种情况下是否只会创建一个 AVManager 实例:

请注意,我确实得到了预期的输出(只有一次“实例化的第一次”并且数字遵循顺序):

第一次实例化!1

文件 1:2

文件 2:3

最后是 4

这是文件....

AV_CONFIG.as:

package {
    public class AV_CONFIG {
        public static var AVM:AVManager = new AVManager();
    }
}

AVManager.as:

package {
    import flash.events.EventDispatcher;

    public class AVManager extends EventDispatcher {
        public var someConstantData:uint = 1;

        public function AVManager() {
            trace('instantiated first time!', someConstantData);
        }

    }
}

然后:

文件1.as:

package {
    import AV_CONFIG;
    import flash.display.Sprite;

    public class File1 extends Sprite {

        public function File1() {
            AV_CONFIG.AVM.someConstantData++
            trace('FILE 1:', AV_CONFIG.AVM.someConstantData);
        }

    }
}

文件2.as:

package {
    import AV_CONFIG;
    import flash.display.Sprite;

    public class File2 extends Sprite {

        public function File2() {
            AV_CONFIG.AVM.someConstantData++
            trace('FILE 2:', AV_CONFIG.AVM.someConstantData);
        }

    }
}

Main.as(文档类):

package {
    import AV_CONFIG;
    import flash.display.Sprite;

    public class Main extends Sprite {

        public function Main() {
            var f1:File1 = new File1();
            var f2:File2 = new File2();
            AV_CONFIG.AVM.someConstantData++
            trace('and finally', AV_CONFIG.AVM.someConstantData);
        }

    }
}
4

4 回答 4

7

通常对于单身人士,您希望:

  1. 限制或取消创建该类实例的能力。
  2. 创建一种静态获取该类实例的方法。

例子:

public class AvManager
{

    private static var _instance:AvManager;
    internal static var created:Boolean = false;

    public function AvManager()
    {
        if(AvManager.created)
        {
            throw new Error("Cannot created instances of AvManager, use AvManager.instance.");
        }

        AvManager.created = true;
    }

    public static function get instance():AvManager
    {
        if(_instance == null)
        {
            _instance = new AvManager();
        }

        return _instance;
    }

    public function test():void
    {
        trace("Working.");
    }

}

您现在可以在哪里使用:

AvManager.instance.test(); // Working.
于 2012-06-26T07:45:41.783 回答
2

最大的问题是允许全局访问某个东西,如果它的状态可以改变的话。如果这是一个您希望代码库维护超过一周左右的项目,并且您认为它可能有超过 500 行代码,我强烈建议您避免这样做——我可以根据经验告诉您在一个大型项目中,很难甚至不可能弄清楚数百个可以访问您的单例的类中的哪一个对其状态进行了更改,从而导致了给定的错误。

其次,需求有一种变化的方式。如果你突然需要 2 个 AVManager 怎么办?你会发现你已经为你的静态创建了如此多的烘焙引用,以至于改变它会使整个项目崩溃。再次,我从这里的经验说起。如果您使用依赖注入(这只是一种可怕的说法,即需要 AVManager 的类具有从外部填充的属性),那么这些类型的更改变得容易......只需给它们一个不同的 AVManager,就完成了。

最后,如果您想要进行测试驱动开发,那么以这种方式使用全局变量/静态变量基本上会使所有代码无法测试。你不能提供一个替代的 AVManager 来测试,因为所有依赖它的类都是硬连线去获取那个特定的。

祝你好运!

于 2012-06-26T12:37:04.220 回答
1

是的,这很好用,另一种方法是将 AVManager 放在它自己的类文件的顶部:

private static var AVM:AVManager = new AVManager();

并在需要时使用 AVManager 类中的函数获取它,如下所示:

public static function GetInstance():AVManager {
    return AVM;
}

此设置不是必需的,但通过禁止直接访问提供了一些不错的小保护。

祝你的项目好运。

于 2012-06-26T07:42:47.370 回答
0

将此代码视为创建不同内容的尝试。

SingletonAS3 中的另一个:

首先一个Interface

package test {
public interface Foo {

    function func0():void;

    function func1(arg:String):String;


}
}

然后是Singleton

package test {
public class BASIC_FOO {
    public static const BASIC_FOO:Foo = new BasicFoo();
}
}

import test.Foo;

class BasicFoo implements Foo {

    public function func0():void {
    }

    public function func1(arg:String):String {
        return arg;
    }
}
于 2012-06-26T09:15:58.730 回答