Статьи

Быстрый совет: шаблон Singleton

Два раза в месяц мы возвращаемся к любимым постам наших читателей на протяжении всей истории Activetuts +. Ретро-подсказка на этой неделе, впервые опубликованная в июне 2010 года, представляет собой введение в популярный (но часто неправильно используемый) шаблон дизайна.

В этом кратком совете мы поговорим о шаблоне проектирования Singleton и о том, как он может помочь вам оптимизировать код, когда вам нужен ровно один экземпляр класса.


Как программист, вы должны знать, что в некоторых случаях вы хотите использовать экземпляр класса, но вы хотите создать только один и сохранить его на протяжении всей программы. Ну, для этого и нужны Singletons.


Singleton — это объектно-ориентированный шаблон проектирования, используемый многими программистами; это позволяет вам создать своего рода «глобальный» экземпляр класса. Он создан таким образом, что может существовать только один уникальный экземпляр, так что все экземпляры этого класса находятся в абсолютно одинаковом состоянии.


Наиболее распространенным примером будет оценка — например, оценка футбола. У вас будет класс Score со свойствами homeTeamScore и awayTeamScore, а также метод, подобный increScore (команда: команда) .

Обе команды должны быть в состоянии увеличить свой счет, когда они ставят цель, но вы не можете дать каждой команде свой собственный экземпляр Score; Вы хотите, чтобы и получить доступ и изменить один и тот же.

Это тот случай, когда Singleton является идеальным решением, поскольку он может работать как глобальный экземпляр, к которому может получить доступ каждый; у вас будет только один экземпляр для всех, так что вам не нужно беспокоиться о том, что каждая команда будет изменять свой счет.


Теперь давайте начнем создавать синглтон в AS3, но сначала вспомним ключевые элементы синглтона:

  • Любой должен иметь доступ к нему.
  • Можно создать только один экземпляр.

Создайте новый класс AS3 и назовите его Singleton.as .

(Не знакомы с кодированием на основе классов? Проверьте это краткое введение .)

Вот основной код Синглтона:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package {
 
    public class Singleton {
 
        private static var instance:Singleton;
        private static var isOkayToCreate:Boolean=false;
 
        public function Singleton() {
            //If we can’t create an instance, throw an error so no instance is created
            if(!isOkayToCreate) throw new Error(this + » is a Singleton. Access using getInstance()»);
        }
 
        //With this method we will create and access the instance of the method
        public static function getInstance():Singleton
        {
            //If there’s no instance, create it
            if (!instance)
            {
                //Allow the creation of the instance, and after it is created, stop any more from being created
                isOkayToCreate = true;
                instance = new Singleton();
                isOkayToCreate = false;
                trace(«Singleton instance created!»);
            }
            return instance;
        }
    }
}

Теперь давайте протестируем Singleton, сначала создадим новый файл Flash с именем Main.fla . На панели свойств установите также класс Main .


Создайте новый класс с именем «Main» и создайте экземпляр Singleton, используя конструктор:

01
02
03
04
05
06
07
08
09
10
11
12
13
package
{
 
    import flash.display.MovieClip;
 
    public class Main extends MovieClip
    {
        public function Main()
        {
            var testSingleton:Singleton = new Singleton();
        }
    }
}

Сохраните и запустите его, вы увидите, что он выдает ошибку, говорящую нам о том, чтобы вместо этого использовать функцию getInstance (), так что сделайте это:

01
02
03
04
05
06
07
08
09
10
11
12
13
package
{
 
    import flash.display.MovieClip;
 
    public class Main extends MovieClip
    {
        public function Main()
        {
            var testSingleton:Singleton = Singleton.getInstance();
        }
    }
}

Сохраните и запустите его, сейчас ошибки нет, и вы можете увидеть в консоли текст «Создан экземпляр Singleton!», Что означает, что он был успешно создан.

Поэтому, когда вы используете класс Singleton, вы не можете использовать новый Singleton () , вместо этого вы должны использовать Singleton.getInstance () .


Синглтон не очень полезен в минуту. Давайте добавим свойство:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package {
 
    public class Singleton {
 
        private static var instance:Singleton;
        private static var isOkayToCreate:Boolean=false;
 
        //new example property:
        public var exampleProperty:String = «This is an example»;
         
        public function Singleton() {
            //If we can’t create an instance, throw an error so no instance is created
            if(!isOkayToCreate) throw new Error(this + » is a Singleton. Access using getInstance()»);
        }
 
        //With this method we will create and access the instance of the method
        public static function getInstance():Singleton
        {
            //If there’s no instance, create it
            if (!instance)
            {
                //Allow the creation of the instance, and after it is created, stop any more from being created
                isOkayToCreate = true;
                instance = new Singleton();
                isOkayToCreate = false;
                trace(«Singleton instance created!»);
            }
            return instance;
        }
    }
}

Теперь в Main.as вы можете получить доступ к testSingleton.exampleProperty, как если бы это был обычный класс. Попробуйте отследить это.


Чтобы доказать, что Singleton делает то, что должен, создайте другой singleton и измените свойство example одного из них:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
package
{
 
    import flash.display.MovieClip;
 
    public class Main extends MovieClip
    {
        public function Main()
        {
            var testSingleton:Singleton = Singleton.getInstance();
            var anotherSingleton:Singleton = Singleton.getInstance();
            anotherSingleton.exampleProperty = «This is set in anotherSingleton»;
            trace(testSingleton.exampleProperty, anotherSingleton.exampleProperty);
        }
    }
}

Как ты думаешь, что произойдет?

Это даже работает, если вы создаете переменные Singleton в разных классах.


Шаблон синглтона может использоваться в любом коде, и я настоятельно рекомендую его использовать, если вы собираетесь использовать только один экземпляр класса, поскольку он дает вам лучший контроль над ним. Надеюсь, вам понравился этот Quick Tip, спасибо за чтение!

Салудос-Эдуардо