Actionscript 3 でシングルトン パターン クラスを実装する最良の方法は何ですか?
-
02-07-2019 - |
質問
AS3 ではプライベート コンストラクターが許可されていないため、シングルトンを構築し、そのコンストラクターが「new」によって明示的に作成されていないことを保証する唯一の方法は、単一のパラメーターを渡してそれをチェックすることのようです。
2 つの推奨事項を聞いたことがあります。1 つは呼び出し元をチェックして静的な getInstance() であることを確認すること、もう 1 つは同じパッケージ名前空間にプライベート/内部クラスを置くことです。
コンストラクターに渡されるプライベート オブジェクトの方が望ましいように見えますが、同じパッケージ内にプライベート クラスを含めることはできないようです。これは本当ですか?そしてさらに重要なのは、それがシングルトンを実装する最良の方法なのかということです。
解決
enobrev の答えを少しアレンジしたものは、インスタンスをゲッターとして持つことです。こちらのほうがエレガントだという人もいるでしょう。また、enobrev の回答では、getInstance を呼び出す前にコンストラクターを呼び出した場合、シングルトンは強制されません。これは完璧ではないかもしれませんが、テストしたところ、うまくいきました。(これを行う別の良い方法が、『Advanced ActionScrpt3 with Design Patterns』という本にも必ず記載されています)。
package {
public class Singleton {
private static var _instance:Singleton;
public function Singleton(enforcer:SingletonEnforcer) {
if( !enforcer)
{
throw new Error( "Singleton and can only be accessed through Singleton.getInstance()" );
}
}
public static function get instance():Singleton
{
if(!Singleton._instance)
{
Singleton._instance = new Singleton(new SingletonEnforcer());
}
return Singleton._instance;
}
}
}
class SingletonEnforcer{}
他のヒント
私はしばらくこれを使ってきましたが、もともとはあらゆる場所の wikipedia から入手したものだと思います。
package {
public final class Singleton {
private static var instance:Singleton = new Singleton();
public function Singleton() {
if( Singleton.instance ) {
throw new Error( "Singleton and can only be accessed through Singleton.getInstance()" );
}
}
public static function getInstance():Singleton {
return Singleton.instance;
}
}
}
興味深いまとめがあります 同様の解決策につながります。
次のようにプライベート クラスを取得できます。
package some.pack
{
public class Foo
{
public Foo(f : CheckFoo)
{
if (f == null) throw new Exception(...);
}
}
static private inst : Foo;
static public getInstance() : Foo
{
if (inst == null)
inst = new Foo(new CheckFoo());
return inst;
}
}
class CheckFoo
{
}
Cairngorm で使用されるパターン (最良ではない可能性があります) は、コンストラクターが 2 回目に呼び出される場合に、コンストラクターで実行時例外をスローします。例えば:
public class Foo {
private static var instance : Foo;
public Foo() {
if( instance != null ) {
throw new Exception ("Singleton constructor called");
}
instance = this;
}
public static getInstance() : Foo {
if( instance == null ) {
instance = new Foo();
}
return instance;
}
}