0

これはアクションスクリプトのシングルトンとしてうまく機能しますか? つまり、注意すべき問題はありますか? この場合、AVManager のインスタンスが 1 つしか作成されないというのは本当ですか?

期待される出力が得られることに注意してください(「インスタンス化された初回」は1回だけで、数字はシーケンスに従います):

初めてインスタンス化されました!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);
        }

    }
}

それで:

File1.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);
        }

    }
}

File2.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 (DocumentClass):

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

最大の落とし穴は、状態を変更できる場合に、何かへのグローバル アクセスを許可することです。これが、コードベースが 1 週間ほど長く維持されると予想されるプロジェクトで、500 行を超えるコードが含まれる可能性が高いと思われる場合は、これを避けることを強くお勧めします。経験から言えます。大規模なプロジェクトでは、Singleton にアクセスできる何百ものクラスのうち、特定のバグの原因となっている状態への変更を行ったクラスを特定するのは困難または不可能になる可能性があります。

次に、要件には変更方法があります。突然 2 つの AVManager が必要になったらどうしますか? static への非常に多くの組み込み参照を作成したため、それを変更するとプロジェクト全体が吹き飛ばされることに気付くでしょう。繰り返しますが、私はここで経験から話します。依存性注入を使用する場合 (これは、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 に答える