Форум 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=204193)

Fogflasher 22.10.2013 14:09

Композиция: обращение вверх по иерархии
 
Всем привет.

Вот здесь Wolsh вкратце описал принципы видимости свойств и методов.

Однако, некоторые практические следствия из этого мне неочевидны.

Рассмотрим на примере. Есть два класса ClassA (он же документ-класс), и ClassB.
ClassA содержит в себе экземпляр ClassB, то есть получаем простейший пример композиции.

ClassA.as:
Код AS3:

package
{
        import flash.display.*;
 
        //--- ClassA ---//
        public class ClassA extends Sprite
        {
                public var classA_sv1:String = "Свойство1 класса А";
 
                //--- Constructor ---//
                public function ClassA()
                {
 
                        trace("<<< Экземпляр класса ClassA создан >>>");
 
                        classB = new ClassB(); //создаем экземпляр класса B
                        trace(classB.classB_get(2)); //обращаемся к свойствам ClassB через его же метод
 
                //--- Method: classA_get() ---//
                public function classA_get()
                {
                        trace("Возвращено:");
                        return classA_sv1;
                }
 
        }
 
 
}

ClassB.as:
Код AS3:

package
{
        import flash.display.*;
 
        //--- ClassB ---//
        public class ClassB extends Sprite
        {
 
                private var classB_sv1:String = "Свойство1_класса_B";
                private var classB_sv2:String = "Свойство2_класса_B";
 
                //--- Constructor ---//
                public function ClassB()
                {
 
                        trace("((( Экземпляр класса ClassB создан )))");
 
 
                }
                //--- Method: classB_get() ---//
                public function classB_get(n:uint):String
                {
 
                        if (n == 1)
                        {
                                trace("Возвращено:");
                                return classB_sv1;
 
                        }
                        else if (n == 2)
                        {
                                trace("Возвращено:");
                                return classB_sv2;
 
                        }
                        else
                        {
                                trace("Возвращено:");
                        }
 
                        return "Cвойство неопределено";
 
                }
        }
 
}

В такой форме всё работает, и мы получаем:
Цитата:

<<< Экземпляр класса ClassA создан >>>
((( Экземпляр класса ClassB создан )))
Возвращено:
Свойство2_класса_B
А теперь, например, нужно реализовать еще две задачи, связанные с обращением "снизу вверх".

1. Обратиться из конструктора ClassB к свойству classA_sv1 (или методу classA_get()) класса ClassA.
2. Обратиться из конструктора ClassB к самому экземпляру ClassA.

1. По первой задаче, я пробовал в конструкторе ClassB вот такие строки:
Код AS3:

trace("classA_sv1 = ", classA_sv1); //ERROR: 1120: Access of undefined property classA_sv1.
trace("classA_sv1 = ", classA_get()); //ERROR: 1180: Call to a possibly undefined method classA_get.

C соответвующими результатами в комментариях.

2. По второй задаче, у меня что-то даже нет идей. Имя экземпляра документ-класса мы не знаем...
Вероятно, нужны какие-то специальные приемы, типа оператора super().

Wolsh 22.10.2013 15:17

Цитата:

А теперь, например, нужно реализовать еще две задачи, связанные с обращением "снизу вверх".
Не нужно. Нет никакой нужды экземпляру обращаться к родителям, иметь на них ссылку и дергать их методы. Такой ребенок очень плох. Ребенок не может выбирать себе родителей; ребенок должен быть спроектирован так, чтобы любой другой класс мог стать его родителем (то есть использовать его в своих целях), не создавая при этом целый завод методов и свойств для ублажения такого ребенка. Представьте, что класс Math, например, требовал бы для его использования в Ваших классах создавать специальные методы и публичные свойства для обеспечения своей работы. Смешно? Вспомните, есть ли хоть один класс во всей родной библиотеке, который бы требовал подобного — наличия определенных свойств и методов у использующего его класса.
Если же сильно приспичило обратиться к Документ-классу, и никакой нормальной архитектуры в голову не приходит, можете смело пользоваться ссылкой root из любого ДисплейОбжекта.

Fogflasher 22.10.2013 15:45

Хм, оказывается здесь я допустил концептуальную ошибку, занятно.
Благодарю также за подсказку насчет .root, поэкспериментируем, тем более что "грамотная архитектура" наверное означает знание Program Patterns.
Но на данный момент это не мой уровень, хотя некоторое самое общее представление о каждом у меня есть. Кстати, интересный вопрос: какой паттерн обычно получается у нубов (или хотя бы ближе всего по структуре), только начинающих юзать композиции и наследования? Или у тех кто пишет чисто в Main.
Наверное все-таки Singleton.

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

udaaff 22.10.2013 16:27

Код AS3:

private function this_mouseDownHandler(event:MouseEvent):void 
{
        //очищаем весь список отображения
        trace(this.parent.removeChildren());
}

Так делать не надо. Кнопка, как уже было сказано, ничего не должна знать о родителе. Иначе это связывает классы.

Akopalipsis 22.10.2013 16:31

Цитата:

Иначе это связывает классы.
Тогда у меня два вопроса -
Почему она в данном контексте связывает, ведь она не чего не знает о родителе.
И как тогда делать? Ловить в MainView клик от кнопки и обрабатывать как родителю хочется?

udaaff 22.10.2013 16:33

Цитата:

ведь она не чего не знает о родителе.
Вызывает метод родителя.
Цитата:

Ловить в MainView клик от кнопки и обрабатывать как родителю хочется?
Да.

UDP: Сможете ли вы это кнопку использовать в какой-то другой программе? Нет, потому что она завязана с другим классом, может быть и косвенно. Кнопка должна выполнять функции кнопки, не более того. По крайней мере тут.

Wolsh 22.10.2013 16:35

Цитата:

тем более что "грамотная архитектура" наверное означает знание Program Patterns
Обычно умения пользоваться Событиями достаточно.
Если родителю нужно, он подписывается на события от ребенка. Таким образом ребенок может сказать "Папа, меня Вася побил!" и папа примет решение на основании своих соображений. Создавать ситуацию, когда ребенок требует "Папа.убей(Васю)" нарушает самые примитивные представления об иерархии. Всегда родитель распоряжается ребенком, никогда наоборот. Родитель создал ребенка для решения каких-то своих задач, ребенок не должен знать ни этих задач ни своего родителя. Должен просто хорошо делать свою работу, а родитель должен предоставить ему все необходимое для этой работы при создании или, по крайней мере, до того как требовать результат.

Добавлено через 6 минут
Кнопка не может содержать в себе код, делающий что-то не с кнопкой или ее детьми. Никогда.
"Кнопка" это то, что нажимается, а не то, что удаляет все объекты со стейджа. Все, что должна уметь кнопка — нажиматься. Такую кнопку можно использовать в любом проекте, потому что она просто делает СВОЮ работу. Разносить логику, касающуюся всех, по всем мелким детишкам проекта еще хуже, чем писать код в отдельных кадрах мувиклипов.

udaaff 22.10.2013 16:53

А для чего новое событие изобретать?

Akopalipsis 22.10.2013 16:57

Цитата:

А для чего новое событие изобретать?
А как тогда? Передиспатчивать евент?

udaaff 22.10.2013 16:59

В MainView подписывайтесь на MOUSE_DOWN. Из кнопки убирите обработчик.


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

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