Pergunta

Desde AS3 não permite construtores privados, parece que a única maneira de construir um singleton e garantir o construtor não é explicitamente criado através de "novo" é passar um parâmetro único e verificá-lo.

Já ouvi duas recomendações, um é para verificar o chamador e garantir que ele é o estático getInstance (), eo outro é ter uma classe privada / interna no mesmo namespace pacote.

O objeto particular repassado o construtor parece preferível, mas não parece que você pode ter uma classe privada no mesmo pacote. Isso é verdade? E o mais importante é que a melhor maneira de implementar um singleton?

Foi útil?

Solução

Uma ligeira adaptação de resposta de enobrev é ter instância como um getter. Alguns diriam que este é mais elegante. Além disso, a resposta de enobrev não vai impor uma Singleton se você chamar o construtor antes de chamar getInstance. Isto pode não ser perfeito, mas eu testei isso e ele funciona. (Há definitivamente uma outra boa maneira de fazer isso no livro "Advanced ActionScrpt3 com Design Patterns" também).

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{}

Outras dicas

Eu tenho usado isso há algum tempo, que eu acredito que originalmente tem de wikipedia de todos os lugares.

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;
        }
    }
}

Aqui está um interessante resumo do problema, o que leva a uma solução semelhante.

Você pode obter uma classe privada assim:

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
{
}

O padrão que é usado por Cairngorm (que pode não ser o melhor) é lançar uma exceção de tempo de execução no construtor se o construtor está sendo chamado uma segunda vez. Por Exemplo:

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;
  }

}    
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top