Qual é a melhor maneira de implementar uma classe de padrão singleton em ActionScript 3?
-
02-07-2019 - |
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?
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;
}
}