Поскольку AS3 не позволяет использовать частные конструкторы, кажется, что единственный способ создать синглтон и гарантировать, что конструктор не создается явно через «новый», - это передать один параметр и проверить его.
Я слышал две рекомендации: одна - проверить вызывающего и убедиться, что это статический getInstance (), а другая - иметь частный / внутренний класс в том же пространстве имен пакета.
Частный объект, переданный конструктору, кажется предпочтительным, но не похоже, что у вас может быть частный класс в том же пакете. Это правда? И что еще более важно, это лучший способ реализовать синглтон?
Глиф - статья, на которую вы указываете, показывает, почему скрытые зависимости плохи, а не почему синглтоны плохи. У вас могут быть синглтоны без скрытых зависимостей.





Шаблон, который используется Cairngorm (который может быть не лучшим), состоит в том, чтобы генерировать исключение времени выполнения в конструкторе, если конструктор вызывается во второй раз. Например:
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;
}
}
"частный статический экземпляр Foo;" - Это даже не ActionScript
Вы можете получить частный класс так:
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
{
}
вы на самом деле не создаете синглтон здесь
Ну, да. Я думал о проблеме частного класса и неправильно понял суть проблемы. Исправлено сейчас?
Foo (CheckFoo f) должно быть Foo (f: Checkfoo) - черт возьми ActionScript в обратном направлении!
Я использую это в течение некоторого времени, что, как мне кажется, я изначально получил из Википедии всех мест.
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;
}
}
}
Вот интересное резюме проблемы, которая приводит к аналогичному решению.
Голосуйте за, потому что это правильно, в отличие от других ответов. Вы также можете использовать instance в качестве получателя, что лучше для автозавершения кода в FlashDevelop.
Я понимаю, что ты имеешь в виду, лежи. Вероятно, поэтому Даниэль (из ссылки) создает экземпляр var в объявлении свойства. Я обновлю свое (и +1 к вашему решению для геттера - хорошее!)
Это хорошо, но имеет тот недостаток, что он проверяется во время выполнения, а не во время компиляции.
Небольшая адаптация ответа enobrev - иметь экземпляр в качестве получателя. Кто-то скажет, что это более элегантно. Кроме того, ответ enobrev не будет применять Singleton, если вы вызовете конструктор перед вызовом 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{}
Этот код var x: * = {}; var multiton1: Синглтон = новый Синглтон (x); var multiton2: Синглтон = новый Синглтон (x); ... компилируется нормально.
ох, тогда это не совсем так! когда я не так занят, я проверю это до конца
Невозможно сделать это всегда ошибкой во время компиляции, просто передача null тоже работает. Я был бы удивлен, если бы побежал прошел успешно - это была бы ошибка AS3.
Передача null не сработает, он будет скомпилирован, но код его проверяет, и вы получите исключение времени выполнения. Суть моего примера кода в том, что он компилируется и обходит проверку. Чтобы исправить это, вы можете изменить тест на «enforcer is SingletonEnforcer», который проверяет как тип, так и значение null.
Синглтоны - плохая идея. Не используйте их: googletesting.blogspot.com/2008/08/…