Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Реализация шаблона singleton в AS3 (http://www.flasher.ru/forum/showthread.php?t=113772)

Alexander Balaganov 08.07.2008 16:32

Реализация шаблона singleton в AS3
 
Посмотрите пожалуйста код. Вы используйте в своем коде шаблон "одиночка" или делаете это как-то подругому?

т.е. это объект, который (по-хорошему) может быть интсанциирован только один раз через метод getInstance()

Код:

public class RegistrationManagerProxy {

                static var registrationManager:RegistrationManagerProxy = null;

                var registrationManagerConnection:NetConnection=null;

                private function RegistrationManagerProxy() {
                        registrationManagerConnection = new NetConnection();
                        registrationManagerConnection.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
                        registrationManagerConnection.connect("rtmp://localhost/registration_manager");
                }
                public static function getInstance():RegistrationManagerProxy {
                        if (registrationManager==null) {
                                registrationManager = new RegistrationManagerProxy();
                        }
                        return registrationManager;
                }
                public function registerAbonent(abonent:Object) {
                        trace("registerAbonent...");
                        trace("E-mail: "+ emailTextInput.text);
                }
                public function netStatusHandler(event:NetStatusEvent):void {
                        trace("connected is: " + netConnection.connected );
                        trace("event.info.level: " + event.info.level);
                        trace("event.info.code: " + event.info.code);

                        switch (event.info.code) {
                                case "NetConnection.Connect.Success" :
                                        trace("Congratulations! you're connected");
                                        break;
                                case "NetConnection.Connect.Rejected" :
                                        trace("Connection rejected by server :(");
                                        break;
                                case "NetConnection.Connect.Failed" :
                                        trace("Oops! you weren't able to connect");
                                        break;
                                case "NetStream.Play.Stop" :
                                        trace("The stream has finished playing");
                                        break;
                                case "NetStream.Play.StreamNotFound" :
                                        trace("The server could not find the stream you specified");
                                        break;
                                case "NetStream.Publish.BadName" :
                                        trace("The stream name is already used");
                                        break;
                                case "NetStream.Publish.Start" :
                                        trace("publish starting...");
                                        break;
                                case "NetStream.Play.Start" :
                                        trace("play starting...");
                                        break;
                        }
                }
        }


wvxvw 08.07.2008 16:41

Ваш класс не должен компилироваться, конструкторы обязаны быть public. Я просто делаю у конструкртора обязательный аргумент типа, который может быть найден только в классе находящемся в одном файле с "одиночкой", но это одно из решений. А вообще, можно поискать по форуму, пару месяцев назад была дискуссия на эту тему с массой примеров.

BlooDHounD 08.07.2008 19:06

http://www.flasher.ru/forum/showthread.php?t=109596

ulik 08.07.2008 19:13

BloodHound >> Давно стало интересно, может ты сможешь объяснить. В чем необходимость использования подобной конструкции ("одиночка")??

Сколько не думал, так и не нашел применения...

BlooDHounD 08.07.2008 22:29

ulik, не понял :) это вопрос ко мне? или моя цитата?

ulik 08.07.2008 23:35

Это вопрос к тебе :)

BlooDHounD 09.07.2008 01:04

ulik, честно? это на столько редкая необходимость, что у нас в проектах пока что нигде не пригодилась. в основном мы используем мультитон. даже адоба почему-то не стала делать синлтон из всем известного класса ExternalInterface.

почему ExternalInterface должен быть всегда один?
потому что контэйнер у флэшки всегда один. пример ХТМЛ-страница.

пример использования синглтона такой:
1. допустим есть некий интерфейс IConnection, который объеденяет в некое множество классов. и ExternalInterface один из них.
Код:

public final class ExternalInterface implements IConnection {
...
}

2. предположим нам надо унаследоваться от EventDispatcher'a.
Код:

public final class ExternalInterface extends EventDispatcher {
...
}

но в данном случаи адоба выбрала вполне логичный путь:
1. колбэк тоже должен быть единсвенный, поэтому наследование от диспатчера не нужно.
2. имплементация интерфейса тоже не нужна. так как его не с чем объеденять.

ShareObject - вполне заслуженный мульти тон.


резюме по поводу данного топика: тут синглтон даже близко не нужен.

ulik 09.07.2008 13:02

Угу. Спасибо. Просто я уже не раз видел "обсуждение сингла" и даже пробовал сделать "тест" проект, чтобы его задействовать, но так и не смог найти именно тот случай, где нужен "класс-сингл". Да и на моем опыте не было пока необходимости в подобном. Другое дело - мультитон. Тут проще :)

wvxvw 09.07.2008 13:35

Вот, на мой взгляд, уместная реализация синглтона. Почему именно синглтон? - потому, что он общается не напрямую с получателем/отправителем информации, а через менеджер. У менеджера есть еще около 7-8 вариантов получения внешней информации, которая должна выглядеть одинаково для получателей. Т.е. в данном случае я посылаю картинки, но, я могу те же картинки получить не из сокета, а просто загрузив с диска или распарсив информацию получаемую из другого URLStream'a и т.п. получателей информации может быть неопределенное количество, сокет может сменить порт и ИП в процессе работы, но получателя информации это не должно волновать - поэтому менеджер создает его 1 раз и на всегда.
(упрощенный вариант)
Код:

/**
* ...
* @author wvxvw
*/
package phpconnect
{
        import flash.events.Event;
        import flash.events.IOErrorEvent;
        import flash.events.ProgressEvent;
        import flash.events.SecurityErrorEvent;
        import flash.net.Socket;
        import flash.utils.ByteArray;
        import flash.utils.Endian;
        import utilities.LoaderEvent;
        import LoadManager;
        import App;
        import player_internal;
       
        import debug;
       
        public class SocketReceiver extends Socket
        {
                public static const US_ASCII:String = 'us-ascii';
               
                private var srPort:int;
                private var srIP:String;
                private var _resourceName:String;
                private var _lm:LoadManager;
               
                public function SocketReceiver(i:Initializer)
                {
                        super();
                        if (i == null) throw new Error("SocketReciever: Argument must not be null!");
                        endian = Endian.LITTLE_ENDIAN;
                        addEventListener(Event.CONNECT, dispatchOnConnected);
                        addEventListener(ProgressEvent.SOCKET_DATA, dispatchOnData);
                        addEventListener(IOErrorEvent.IO_ERROR, handleIOError);
                        addEventListener(SecurityErrorEvent.SECURITY_ERROR, handleSecurityError);
                       
                }
                public function xconnect():void
                {
                        if (!_lm) _lm = App.getInstance().player_internal::_loader;
                        srPort = _lm.player_internal::getAvailableSocketPort();
                        srIP = _lm.player_internal::getAvailableSocketIP();
                        super.connect(srIP, srPort);
                }
                public function setResourceName(s:String):void
                {
                        _resourceName = s;
                }
                private function dispatchOnConnected(evt:Event):void
                {
                        dispatchEvent(new LoaderEvent(LoaderEvent.LOADER_CONNECTED, null, LoadManager.DRAW));
                }
                private function dispatchOnData(evt:ProgressEvent):void
                {
                        if (bytesAvailable == 0) return;
                        var ba:ByteArray = new ByteArray();
                        ba.endian = Endian.LITTLE_ENDIAN;
                        readBytes(ba);
                        ba.position = 0;
                        dispatchEvent(new LoaderEvent(LoaderEvent.LOADER_LOADED, ba, LoadManager.DRAW));
                }
                private function handleIOError(evt:IOErrorEvent):void
                {
                        debug(this, 'IO Error', evt);
                }
                private function handleSecurityError(evt:SecurityErrorEvent):void
                {
                        debug(this, 'SECURITY Error', evt);
                }
                public function sendRequest(s:String):void
                {
                        super.writeMultiByte(s, US_ASCII);
                        super.flush();
                }
                public function sendBytes(b:ByteArray):void
                {
                        super.writeBytes(b);
                        super.flush();
                }
               
                private static var _instance:SocketReceiver;
               
                public static function getInstance():SocketReceiver
                {
                        if (!_instance) {
                                _instance = new SocketReceiver(new Initializer());
                        }
                        return _instance;
                }
        }
       
}
internal final class Initializer
{
        public function Initializer(){}
}


etc 09.07.2008 13:43

wvxvw, а что с английским? :)


Часовой пояс GMT +4, время: 21:59.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.