Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Правильное межклассовое взаимодействие (http://www.flasher.ru/forum/showthread.php?t=142230)

Jin 2 15.07.2010 21:01

Правильное межклассовое взаимодействие
 
Давно мучаюсь следующим вопросом
В экземпляре класса А создан экземпляр класса Б,
как из экземпляра класса Б обратиться к свойствам и методам класса А?

Можно просто, создавая экземпляр класса Б, передать ему ссылку на класс А, однако, тут на форуме я читал, что так делать не правильно, что нужно передавать экземпляру параметры, а получать от него события.
В таком случае, пример:
В экземпляре класса А создан экземпляр класса Б, в экземпляре Б создан экземпляр класса С.
Из класса С необходимо обратиться к методу класса А, для этого в классе С вызываю событие, обрабатываю его в классе Б, затем в классе Б вызываю событие и уже его обрабатываю в классе А. Сложновато как-то, да и громоздко.
Может я что-то неправильно понимаю?

expl 15.07.2010 23:09

Посылая события вместо прямого обращения вы просто разрываете жесткую связь с классом A, т.е. была двунаправенная - стала однонаправленная

Зачем?
Вот у вас есть компонент кнопка с названием B, по нажатию на нее должно что-то произойти в классе А,
и че, вы напрямую в классе кнопки вызываетет метод А?
Тогда вы точно нигде эту кнопку не сможете задействовать, кроме как в классе А

Тоже самое и со всем остальным - это не чтобы усложнить жизнь, а чтобы разорвать связи, мешающие повторно использовать компоненты

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

...Вообще фанатизм тоже не нужен. Часто лучше просто ссылку в конструктор передать.
Цитата:

Из класса С необходимо обратиться к методу класса А, для этого в классе С вызываю событие, обрабатываю его в классе Б, затем в классе Б вызываю событие и уже его обрабатываю в классе А. Сложновато как-то, да и громоздко.
...Вот не должно быть необходимости напрямую обращаться к методу через 2 класса
Может им 3-м создать один общий класс (медиатор), через который они будут общаться или который будет ими рулить

P.S. Лучше приведите конкретный пример, а то слишком обстрактно получается :(

mikhailk 15.07.2010 23:30

Jin 2,
События всплывают по иерархии.
Не надо их десять раз обрабатывать.

Относительно примера, когда по событию в объекте D нужно что-то делать в объекте А:
- объект А - контроллер
- объект В - локация
- объект С - перс в локации
- объект D - контекстное меню, которое всплыло по клику на перса, с кнопкой, по которой нужно закрыть текущую локацию, открыть новую и поместить туда перса

В итоге:
- обрабатываем в объекте D кнопку контекстного меню, пакуем в событие информацию для контроллера и отправляем наверх.
- объект А (контроллер) получает событие, закрывает текущую локацию, открывает новую и помещает туда перса

об этом речь?


Ну а если нужно что-то более простое и неправильное, то используйте parent.
Тут периодически проходят даже куски кода вроде
Код AS3:

parent.parent.parent.mySuperFunction();

Говорят, работает.

Jin 2 16.07.2010 01:23

В том-то и дело, хочется сделать не так как раньше, а по уму.

Цитата:

Относительно примера, когда по событию в объекте D нужно что-то делать в объекте А:
- объект А - контроллер
- объект В - локация
- объект С - перс в локации
- объект D - контекстное меню, которое всплыло по клику на перса, с кнопкой, по которой нужно закрыть текущую локацию, открыть новую и поместить туда перса
Великолепный пример,
в контекстном меню кнопка, так вот как отправить событие в класс А, если D в С, С в B а B в А? Провести событие через все классы? Или экземпляры этих классов создавать в контролере, а не друг в друге?

В итоге получается, что в контроллере должны быть обработчики почти всех событий, которые происходят в игре?

Котяра 16.07.2010 01:34

баблинг

mikhailk 16.07.2010 11:18

Jin 2,
- объекты вкладывать друг в друга через addChild()
- баблинг (пузырьковое всплытие) обеспечить установкой свойства bubbles в true http://help.adobe.com/ru_RU/AS3LCR/F...t.html#bubbles
- относительно большого количества событий беспокоиться не стоит, поскольку событий будет немного (при правильной организации процесса). Например, все возможные перемещения перса между любыми локациями - это одно событие, просто с разными параметрами.

Jin 2 16.07.2010 12:10

Получается код должен быть примерно таким?

Код AS3:

package {
    public class A {//контроллер
          public function A() {
                var classBref = addChild(new B());//Локация
                var classCref = classBref.addChild(new C());//Персонаж
                var classDref = classCref.addChild(new D());//Меню персонажа
                classDref.addEventListener("event",listener);//Обработка события меню
          }
    }
}


mikhailk 16.07.2010 12:25

нет, не совсем ))

ключевое - событие диспатчится (генерируется) на нижнем уровне, а слушается на верхнем.

Но именно так писать нельзя.

Добавлено через 21 минуту
Вот, как-то так. Работоспособность не проверял, но должно работать

1. Наверху создаем локацию и ставим слушателя. AppEvent - это собственный класс события, позволяющий передавать параметры.

Код AS3:

        public class Controller extends Sprite
        {
                private var location:Location;
 
                public function Controller() : void
                {
                        setLocation();
                }
 
                private function setLocation() : void
                {
                        location = new Location();
                        location.addEventListener("eventFromPers", eventFromPersHandler);
                        addChild(location);
                }
 
                private function eventFromPersHandler(e:AppEvent) : void
                {
                        trace("Поступило событие от перса: ", e.data);
                }
        }

2. На уровне локации ничего не делаем, просто ставим перса:

Код AS3:

        public class Location extends Sprite
        {
                private var pers:Pers;
 
                public function Location() : void
                {
                        setPers();
                }
 
                private function setPers() : void
                {
                        pers = new Pers();
                        addChild(pers);
                }
 
        }

3. На уровне перса обрабатываем нажатие на кнопку и отсылаем событие наверх

Код AS3:

        public class Pers extends Sprite
        {       
                private var persMC:PersMC; // мувик из библиотеки с кнопкой sendEvent
 
                public function Pers() : void
                {
                        initPers();
                }
 
                private function initPers() : void
                {
                        persMC = new persMC();
                        persMC.sendEvent.addEventListener(MouseEvent.CLICK, mouseClickHandler);
                        addChild(persMC);
                }
 
                private function mouseClickHandler(e:Event) : void
                {
                        var eventData:String = "с персом все в порядке";
                        var appEvent:AppEvent = new AppEvent("eventFromPers",eventData,true)
                        dispatchEvent(appEvent);
                }
 
        }

Собственный класс события для передачи параметра, как вариант:

Код AS3:

        public class AppEvent extends Event {
 
                protected var _data:Object;
 
                public function AppEvent(type:String, data:Object, bubbles:Boolean = false, cancelable:Boolean = false) {
                        _data = data;
                        super(type, bubbles, cancelable);
                }
 
                override public function clone():Event {
                        return new AppEvent(type, data, bubbles, cancelable);
                }
 
                public function get data():Object { return _data; }
        }


Jin 2 16.07.2010 12:52

Большое спасибо!


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

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