Как структурировать мои классы, чтобы избежать использования статических функций - PullRequest
0 голосов
/ 16 ноября 2011

У меня есть приложение Flash, которое создает презентацию PowerPoint.
Все «слайды» хранятся в файлах XML, которые читаются и обрабатываются.

Я пытаюсь создать презентацию, используя этот файл XML.

На данный момент у моего основного класса есть начальная функция main и статическая функция processXML
main инициирует мой database класс с функцией initDB. Одна из моих проблем заключается в том, что initDB отказывается от обработки, поскольку зависит от прослушивателя событий. По завершении загрузки файлов XML прослушиватель событий запускает мою статическую функцию на моем main для создания объектов из этого файла.

Проблема заключается в том, что, поскольку прослушиватель событий продолжает обработку (через неопределенное время), функции больше не управляются классом main.
Обычно в этой ситуации я бы избегал использования статики, потому что управлял бы обработкой из основной функции, используя returns при обработке - то есть функцию, которая возвращает значение, чтобы вернуть управление обратно в класс вызывающего.

Теперь все это имеет эффект стука, и я не могу использовать вызовы addChild или любые другие подобные вызовы, потому что функция статическая.

Если бы вы могли уделить немного времени, мне действительно нужно переосмыслить работу моих файлов.

Основной класс

public static var databaseXML:XML;
public var database:ContentDatabase = new ContentDatabase();

public function main()
{
    database.initDB();
}

public static function processXML()
{
    //Get First Slide
    var introSlide:SlideLayout = new SlideLayout();
    var allSlides:XMLList = main.databaseXML.children();
    var introSlideXML:XML;
    for each (var slide:XML in allSlides)
    {
        introSlideXML = slide;
        break;
    }
    var theSlide:MovieClip = introSlide.createSlide(introSlideXML);
    addChild(theSlide); //Fails, Obviously
}

Класс ContentDatabase

private var xmlLoader:URLLoader;

public function initDB()
{
    xmlLoader = new URLLoader();
    xmlLoader.addEventListener(Event.COMPLETE, onComplete, false, 0, true);
    xmlLoader.addEventListener(IOErrorEvent.IO_ERROR, onIOError, false, 0, true);
    xmlLoader.load(new URLRequest("resources/slides.xml"));
}

private function onComplete(e:Event):void
{
    try
    {
        main.databaseXML = new XML(e.target.data);
        xmlLoader.removeEventListener(Event.COMPLETE, onComplete);
        xmlLoader.removeEventListener(IOErrorEvent.IO_ERROR, onIOError);
        main.processXML();
    }
    catch (err:Error)
    {
        trace('broke: ' + err.message);
    }
}
private function onIOError(e:IOErrorEvent):void
{
    trace('broke: ' + e.text);
}

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

В идеале я бы хотел, чтобы класс ContentDatabase не содержал ничего, кроме обработки XML.

1 Ответ

2 голосов
/ 16 ноября 2011

Ваши классы Main и ContentDatabase слишком связаны!

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

Я не согласен с Sr.Ричи, Синглтон действительно здесь не нужен.

ContentDatabase должна просто заботиться о загрузке XML, в идеале исходный URL не должен быть жестко задан в классе.

Например, вы можете передать URL-адрес в качестве параметра методу initDb

     database.initDB("resources/slides.xml");

После загрузки данных эффективная практика заключается в отправке события для информирования основного класса о том, что данные готовы.Вы можете использовать CustomEvent или Signal и передавать данные как объект.Таким образом, у вас не будет ненужных зависимостей между классами Main и ContentDatabase.

    private function onComplete(e:Event):void
    {
        try
        {
            main.databaseXML = new XML(e.target.data);
            xmlLoader.removeEventListener(Event.COMPLETE, onComplete);
            xmlLoader.removeEventListener(IOErrorEvent.IO_ERROR, onIOError);

            //better process the XML data here...
            processXML();

        }
        catch (err:Error)
        {
            trace('broke: ' + err.message);
        }
    }

    private function processXML():void
    {
         // process the data...
         // inform the Main class by dispatching an Event
         // and pass the data as a parameter
         // use a CustomEvent or a Signal
     }

Тогда в вашем классе Main

     //If you use a CustomEvent
     private function xmlLoadComplete( event:XMLCustomEvent ):void
     {
         var introSlideXML:XML = event.introSlideXML;
         var theSlide:MovieClip = introSlide.createSlide(introSlideXML);  
     }

Существует несколько способов отправки и прослушиванияСобытия между основным классом и базой данных ContentDatabase.Как уже упоминалось выше, вы можете использовать сигналы.Вы также можете создать легкую зависимость, передав диспетчер событий в ContentDatabase.Это делается для того, чтобы тот же диспетчер прослушивал и отправлял событие.

     public var database:ContentDatabase = new ContentDatabase(dispatcher);

Затем в contstructor ContentDatabase ...

       this.dispatcher = dispatcher;

, затем в processXML ()

    private function processXML():void
    {
          // after all the processing
          dispatcher.dispatchEvent( new XMLCustomEvent (introSlideXML ) );
     }

И, конечно же, в вашем основном классе

   //In case of CustomEvent
   public function main()
   {
       //the same dispatcher listens
       dispatcher.addEventListener( XMLCustomEvent.XML_LOADED , 
                                        xmlLoadComplete );
       database.initDB();
   }

Хотя возможно использовать XML в качестве нативного объекта AS3, я часто предпочитаю создавать свой собственный объект или класс, заполняя егоXML-данные, чтобы я мог вызывать их свойства напрямую, вместо того, чтобы запрашивать XML, но это личный вкус ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...