PDA

Просмотр полной версии : Правильно ли главный класс делать синглтоном?


zzSpirit
12.04.2013, 11:29
Правильно - я имею в виду, является ли это хорошей практикой программирования?
В общем, сабж.

FlashRus
12.04.2013, 11:42
А зачем?

caseyryan
12.04.2013, 11:46
Правильно - я имею в виду, является ли это хорошей практикой программирования?
Не правильно.

bav
12.04.2013, 11:46
Все зависит от решаемой задачи. Если вы решили, что вот в данной конкретной задаче это будет уместно и хорошо – делайте.

zzSpirit
12.04.2013, 12:25
Ан, нет. Не получается так сделать. Несколько часов назад разобрался с синглтоном только и ща пытался Main сделать им, не получается... Нельзя в статическую переменную сохранить ссылку на самого себя.

Добавлено через 2 минуты
А зачем?

Я хотел сделать так, чтобы не нужно было постоянно передавать ссылку на Main в другие классы.

Hauts
12.04.2013, 12:29
Я хотел сделать так, чтобы не нужно было постоянно передавать ссылку на Main в другие классы.
— Что-то мне подсказывает, что такая реализация весьма неправильна.

То есть я про передачу ссылки на мэйн, это неправильно.

Babylon
12.04.2013, 12:43
Синглтон подразумевает однократное создание экземпляра класса, например инициализация.

Добавлено через 4 минуты
Синглтоны задуманы, в том числе, для предотвращения повторного использования при инжекциях класса как в конструктор, так и в метод куда он инжектируется:)

Добавлено через 17 минут
Поэтому ответ правильно ли использовать синглтон в Main зависит от ответа на вопрос:" Сколько раз ты вызываешь Main?" Ответ по-моему очевиден :)

Александр Мостовой
12.04.2013, 13:29
Правильно - я имею в виду, является ли это хорошей практикой программирования?
В общем, сабж.

Нет, но как следствие использование других хорших практик и как искушение использовать некоторые плохие. Чаще всего Main вообще никому не нужен :) В любом случае способность ответить себе на вопрос зачем вам это нужно и своевременность для определенного этапа развития имхо лучше попугайства хороших практик. Поэтому что бы ответить на него, нужно узнать как были организованы ваши проекты до этого. Сделать Main синглтононом лучше получения ссылки на него через иерархию вложенности DisplayObject parent.parent, root...,но хуже более инкапсулированных решений
Нельзя в статическую переменную сохранить ссылку на самого себя.

Почему нельзя?, можно!

caseyryan
12.04.2013, 14:20
Почему нельзя?, можно!
Действительно. Не понимаю чем ссылка записанная в статическую переменную отличается от ссылки записанной в переменную экземпляра.
У автора наверное была конструкция типа этой:

public static var MAIN:Main = this;

Само собой это работать не будет. Во время вызова статического инициализатора, экземпляра еще не существует. Соответственно сразу на this сослаться нельзя. Но можно в конструкторе произвести присвоение.

iflamberg
12.04.2013, 15:35
Я в конструкторе инициализирую статичесскую ссылку на Main. И делаю то же самое для большинства классов, которые у меня гарантированно должны быть в программе в одном экземпляре и которые не получается сделать полностью статическими.
Не знаю, я считаю, что все что удобно и комфортно для работы - все правильно. А Main.instance.stage.addChild(x) довольно удобно.

Александр Мостовой
12.04.2013, 15:52
А Main.instance.stage.addChild(x) довольно удобно.
А библеотекарю удобно сбрасывать все новые книги в специальный ящик из которого все читатили смогли бы сами доставить ве что им нужно :) И удобно не создавать для каждой книги картоку, когда у книги есть обложка. Это и есть игнорирование понятие инкапсуляции. Самый сложный вопрос не как удобно положить, а как удобно найти и понять что это и зачем :)
Хотя я согласен, что нет с мысла длать что-то если это неудобно и бесполезно :) Отказ от публичных переменных и методов - это способ не усложнить себе жизнь а упростить.

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

in4core
12.04.2013, 16:25
iflamberg - и после этого, вы еще имеете совесть давать какие то советы окружающим? Срочно учите мат часть!

iflamberg
12.04.2013, 17:31
Тут вопрос в основном в том, какой масштаб проекта и "кто главный". Если я буду участвовать в разработке чужого масштабного проекта как рядовой программист, я конечно, буду писать код так, как того требует мой начальник. Я вот,скажем, не переношу { на следующую строку и не использую префиксы типа iInteger:int, sString:String. Только private _variable для приватных свойств. Но если я работаю в команде и у них сложился другой "кодекс", я буду писать, как скажут, мне не тяжело. Я легко читаю чужой код и подстраиваюсь под других, я из тех людей, что любят использовать чужие библиотеки и не изобретают велосипеды.

А если мне заказали "3д-видео-галерею", или я пишу игрушку для аукциона; я работаю один и вся программа умещается в голове, то я не вижу смысла усложнять себе жизнь. Мне важно написать код с минимальными трудозатратами, а "красивости" кода...
Программу когда пишешь - у тебя уйма разных решений может быть. Можно синглтон. Можно передать в коструктор, можно вызвать функцию и передать ей список аргументов, еще что-то. Ты просто выбираешь между удобно-быстро-читаемо и т.д. Вон, друпал6 не использует классы, а считается одним из лучших пхп-движков-фреймверков, его коммунити и авторы "плохо"кодеры?

А инкапсуляцию Main.instance не нарушает. Все приватные свойства остаются приватными, все ок.

Александр Мостовой
12.04.2013, 17:41
А инкапсуляцию Main.instance не нарушает. Все приватные свойства остаются приватными, все ок.

Main.instance в общем не нарушает, а вот это нарушает: :)
Main.instance.stage.addChild(x)

in4core
12.04.2013, 17:58
А инкапсуляцию Main.instance не нарушает. Все приватные свойства остаются приватными, все ок.
Я остаюсь при том же мнении - учите мат часть. Ни одни здравомыслящий программист , понимающий принципы ООП, знающий , что такое инкапсуляция и т.п. - не напишет даже так Main.variable .
Какое бы вы приложение не писали, простое или сложно, у вас всегда есть ОСНОВНОЙ вид и ГЛАВНЫЙ контроллер, который хранит ссылку на _host

Александр Мостовой
12.04.2013, 17:58
у них сложился другой "кодекс", я буду писать, как скажут, мне не тяжело

Мне, лично, не столько тяжело следовать тому или иному правилу, сколько напряжно перестраиваться, поэтому предпочитаю следовать лидирующим стандартам:
http://sourceforge.net/adobe/flexsdk/wiki/Coding%20Conventions/

Хотя Адоби сама их довольно часто нарушает :(

Wolsh
12.04.2013, 20:06
Просветите кто-нибудь, как плеер создает экземпляр документ-класса, если тот — синглтон? Мне просто никогда в голову такое извращение не приходило...
И что будет делать Loader другой флэшки, когда загрузит такой файл?

p.S. за stage.addChild() я бы расстреливал без компенсации.

Александр Мостовой
12.04.2013, 20:50
И что будет делать Loader другой флэшки, когда загрузит такой файл?

Зависит от loaderContext

Просветите кто-нибудь, как плеер создает экземпляр документ-класса, если тот — синглтон? Ну он же его один раз созадет :)
В смысле любой калсс запрещающий повторный вызов конструктора можно считать синглтоном.

Wolsh
12.04.2013, 21:29
А, то есть конструктор ломается только в рантайме? Зашибись удобно...
Просто для меня синглтон всегда имел конструктор с приватным ключом.. видимо, я отстал от новых веяний.

Александр Мостовой
12.04.2013, 21:47
Просто для меня синглтон всегда имел конструктор с приватным ключом
Ну это был всегда одним из способов и скорее фичей.


if (_instance)
{
throw new Error("Хватит, уже есть одни экземпляр!");
}
else
{
_instance = this;
}

А, то есть конструктор ломается только в рантайме?

Ну конечно такой способ хуже :)

Ну а по сабжу, мне кажется что при переходе с кода во фреймах любой промежуточный шаг будет в достаточной степени неверным, и сей ход есть интуитивная потребность сделать шаг навстречу к некоторому контролеру без размножения сущностей и мне кажется не столь критичным. Лишь бы использовать его по назначению: отказа от паралельных обращений между одноуровневыми блоками приложения, а не \ изменения чего угодно где угодно :)

zzSpirit
12.04.2013, 22:50
Ну, добавлять на сцену я буду все в главном классе, как положено.
Но к примеру у меня есть класс VK - синглтон, где используется конструкция stage.loaderInfo.parameters, в этот класс я передаю ссылку на Main, думал сделать так чтобы не передавать ссылку, а обращаться просто: main.stage.loaderInfo.parameters - но понял теперь что это нарушает ООП принципы, кароче самое правильное ссылкой как я понял.

Добавлено через 1 минуту

p.S. за stage.addChild() я бы расстреливал без компенсации.
Имеется ввиду, если написать так в главном классе вместо просто addChild()?

Добавлено через 3 минуты

У автора наверное была конструкция типа этой:

public static var MAIN:Main = this;

Само собой это работать не будет. Во время вызова статического инициализатора, экземпляра еще не существует. Соответственно сразу на this сослаться нельзя. Но можно в конструкторе произвести присвоение.
Да, именно так и было. Спасибо, помогло.

Wolsh
13.04.2013, 00:30
Имеется ввиду, если написать так в главном классе вместо просто addChild()?На stage должен находиться только один объект — экземпляр Документ-класса. Он является Вашим приложением. И он контейнер (не может не быть контейнером). Все, что создается приложением, должно находиться в контейнере приложения, а не шляться где-то за его пределами.
Сама по себе запись stage.addChild() является командой от потомка родителю, что так же недопустимо. Потомок не должен вызывать методы родителя напрямую. Если родитель желает слышать голос ребенка, он подписывается на события от него и сам решает, что делать когда события приходят. Но ребенок никогда не должен принимать решения за родителя и делать что-то "от его имени". Приложение без иерархии превращается в бардак, а классы, желающие управлять своими родителями, непригодны для повторного использования в других проектах. Классы, выбрасывающие своих детей на Stage — тем более.
Многие используют этот трюк для добавления всплывающих окон и подсказок (а когда-то и курсоров), вместо того чтобы просто создать структуру глубины с помощью контейнеров-"слоев" в документ-классе. Это не более чем безалаберность и лень. Не делайте так. Не понимайте слова "добавить на стейдж" буквально. Это всегда подразумевает "добавить в список отображения". Stage — это плеер. И в плеере должен показываться только один объект — Ваше приложение. И все его дети должны находиться в ЕГО списке отображения.

zzSpirit
13.04.2013, 01:12
Огромное спасибо, Wolsh! Теперь все понятно!

СлаваRa
13.04.2013, 01:31
на самом деле, дела с этим обстоят очень плохо, огромное кол-во программистов использует этот подход в промышленных масштабах... а потом, долго-долго решают проблемы... другая доля программистов не понимает, что Stage один.
Открываешь проект и видишь StageHelper.instance.activeStage, что-то-там.removeFromParent() и т.д.,.. я до сих пор не могу понять, почему\зачем люди так хотят создать себе проблем.

semenyakinVS
13.04.2013, 02:17
Если родитель желает слышать голос ребенка, он подписывается на события от него и сам решает, что делать когда события приходят.

Wolsh, спасибо за инфу по поводу синглтона. Задумался и пошёл шерстить свой код на предмет подобных случаев.

Main.instance

А где здесь нарушение инкапсуляции? Или это не вызов property (геттера), а получение указателя на статическую структуру (тогда да, тогда нарушение) ?

СлаваRa
13.04.2013, 05:55
какого фига main кому в "дереве" своей программы должен быть доступен? или должен отдавать свое? ну правда, а?

если так, любой сможет расшатать логику программы.. отловить это будет крайне сложно(

zzSpirit
13.04.2013, 06:05
какого фига main кому в "дереве" своей программы должен быть доступен? или должен отдавать свое? ну правда, а?


что ты имеешь ввиду под "отдавать свое"? то, что он передает ссылку на самого себя или что-то другое?

Psycho Tiger
13.04.2013, 10:06
Ни одни здравомыслящий программист , понимающий принципы ООП, знающий , что такое инкапсуляция и т.п. - не напишет даже так Main.variable .
Какое бы вы приложение не писали, простое или сложно, у вас всегда есть ОСНОВНОЙ вид и ГЛАВНЫЙ контроллер, который хранит ссылку на _host
Моих тем про MVC перечитал? :)
Да, действительно, так делать правильно в ряде случаев. Но главная мысль в любом приложении с отделенными частями логики – пусть данные не лезут в отображение напрямую.
К слову, интересен обмен опытом: чем для тебя фатальны статические ссылки?

По сабжу: запомните раз и навсегда. Синглтон – это только возможность создания одного экземпляра. В контексте флеша stage – это синглтон. Но к нему нету повсеместно глобального доступа.
Сколько раз создается Main (подразумеваю, что Main - base class). Один. Этот экземпляр создаёт флешплеер при запуске флешки. Если требуется вызвать где–то new Main явно – то это действительно плохо. Ну серьезно, приложение которое создаёт само себя внутри себя...

Так что мой ответ: да, делать базовый класс синглтоном – правильно. Но он настолько очевидно-синглтон, что можно не тратить времени на реализации заглушек, чтобы второй раз его не создали. И нет, синглтон и глобальный доступ – это рядом стоящее, но совсем не одно и то же.

caseyryan
13.04.2013, 12:37
На stage должен находиться только один объект — экземпляр Документ-класса. Он является Вашим приложением. И он контейнер (не может не быть контейнером). Все, что создается приложением, должно находиться в контейнере приложения, а не шляться где-то за его пределами.
Можно конечно и документ класс использовать для этого (теоритически), но лично я не вижу ничего плохого в том, чтобы различные модальные окна добавлялись на stage.
У меня часто в приложениях присутствуют менеджеры модальных окон, которые инициализируются на stage. При вызове какого-то статического метода, типа addWarningWindow(title:String) на стейдж добавляется окно, а на фон сразу под ним добавляется спрайт с прозрачной заливкой со сторонаями равными stageWidth, stageHeight, чтобы перекрыть клики. Окна полностью автономны, и приложение не имеет каких либо других ссылок на них. Так вот, почему stage а не документ класс, опять же из-за размеров спрайта заливки. Не от документ класса же получать ширину и высоту этой заливки.

Wolsh
13.04.2013, 12:57
Поверх всего лежит контейнер для модальных окон. Менеджер имеет ссылку на него, а контейнер, естественно, имеет ссылку на стейдж и знает его размеры. В чем же проблема?
Экран затемнения уж тем более так просто написать отдельным классом, который достаточно кинуть в список отображения и он, автоматически получив ссылку на стейдж, закрасит нужную область. Другое дело с центрированием модальных окон — некрасиво, когда ребенок сам задает свои координаты в родителе. Но тут уж, как говорится, смотри п.1. Контейнер для размещения окна знает стейдж и его размеры.
Если я проглядел/не понял проблему, объясните на пальцах.

Babylon
13.04.2013, 15:29
Можно конечно и документ класс использовать для этого (теоритически), но лично я не вижу ничего плохого в том, чтобы различные модальные окна добавлялись на stage.
У меня часто в приложениях присутствуют менеджеры модальных окон, которые инициализируются на stage. При вызове какого-то статического метода, типа addWarningWindow(title:String) на стейдж добавляется окно, а на фон сразу под ним добавляется спрайт с прозрачной заливкой со сторонаями равными stageWidth, stageHeight, чтобы перекрыть клики.

Перекрывать клики наложением спрайтов это надо додуматься до этого:). А чего кодом никак?

in4core
13.04.2013, 15:29
Моих тем про MVC перечитал? Веришь, нет - ни одной не читал, хотя первую помоему при создании прочел и закрыл . Мне не нужны были статьи , я разбирался в свое время сам методом проб и ошибок, брал готовые приложения и разбирал, почему так, почему эдак, а потом писал сам ))) В любом случае - все приходят к одной точки зрения, более менее общей

caseyryan
13.04.2013, 15:35
Перекрывать клики наложением спрайтов это надо додуматься до этого:). А чего кодом никак?
Зачем? Или Вы из тех, кто не ищет легких путей? Что проще, добавить временный невидимый спрайт поверх ВСЕГО, или бегать по всему и вся задавая mouseEnabled = false? Тем более что для этих манипуляций подчас потребуются танцы с бубном. Или же, получать ссылку на документ класс и ставить ему mouseEnables = false и mouseChildren = false; Тогда в чем профит? Опять ссылка, опять связанность. Stage есть у любого флеш приложения, и мой вариант менеджера можно легко перетащить из одного в другое, даже ничего не переделывая.

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

Babylon
13.04.2013, 15:54
this.mouseChildren = false только у модального окна, на которое есть ссылка в менеджере. Чем плохо?

СлаваRa
13.04.2013, 16:00
Вы не поняли, @caseyryan, все верно сказал, мы тоже так делаем,.. у меня есть локация в на ней 400 объектов, которые ловят клик, открыть окно(которое меньше чем размеры сцены) и перекрыть сцену гораздо проще чем у всех отключить мышь

caseyryan
13.04.2013, 16:06
this.mouseChildren = false только у модального окна, на которое есть ссылка в менеджере. Чем плохо?
Мм.. Вы о чем? Зачем мне отключать реакцию на мышь у дочерних элементов окна? Они то как раз должны на нее реагировать.

Babylon
13.04.2013, 16:08
а в чем тогда модальность?

caseyryan
13.04.2013, 16:13
а в чем тогда модальность?

Как-то так (http://ru.wikipedia.org/wiki/%D0%9C%D0%BE%D0%B4%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B5_%D0%BE%D0%BA%D0%BD%D0%BE)

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

Babylon
13.04.2013, 16:18
И в чем его отличие от других клипов на сцене?

caseyryan
13.04.2013, 16:22
И в чем его отличие от других клипов на сцене?
Это такой троллинг чтоли? Читайте выше.
Или Вам никогда не доводилось создавать подобных систем?
Или может у Вас есть вариант по-лучше? С удовольствием бы глянул.

Babylon
13.04.2013, 16:25
Ага,первый раз читаю. Вам модератор толково объяснил. Я пытался еще толковее. Соряйте :).

caseyryan
13.04.2013, 16:29
Я пытался еще толковее
Нет, попытка не удалась. Это лучший вариант. Самый простой в использовании и не завязанный ни на что, кроме stage.
А вопрос по поводу Вашего варианта остается в силе. Покажите свой.
Данные о том, что на stage не должно быть ничего, кроме документ класса не соответствуют действительности.
Если бы в adobe этого хотели, то ссылки на stage вообще не было бы.

Babylon
13.04.2013, 16:39
Engine.gameStage.stage.addChild(this)
Где this указатель на какой-то экземпляр вида

caseyryan
13.04.2013, 16:41
Ужас)
Уже представляю как подобное переносится в другой проект )

Babylon
13.04.2013, 16:48
Ещё вот
Engine.gameView= new MainView();

caseyryan
13.04.2013, 17:01
Чем это удобнее вызова?

ModalWindow.showWarning("какое-то предупреждение");

Окно появилось, нажали кнопку, окно удалилось. Никаких ссылок на него нет.

Александр Мостовой
13.04.2013, 17:07
Main.instance.stage.addChild(x)

У меня часто в приложениях присутствуют менеджеры модальных окон, которые инициализируются на stage. При вызове какого-то статического метода, типа addWarningWindow(title:String)

Engine.gameStage.stage.addChild(this)


Объясните о чем спор? помоему все 3 описания одинаковы.

Я правда не вижу необходимости вешить окно именно на стейдж, что мешает это сделать просто в верхний слой View? Но дело не в stage, а в том что у всего должен быть один хозяин с которого можно спросить в случае чего. Такое обращение извне мне очень не нравится прежде всего тем, что с таким же успехом это же обращение может делать кто-то другой и прийдется искать каждый раз виноватого.

ПО мне так самый простой и удобный способ что-то вроде этого:

controller.addEventListener(ControllerEvent.SHOW_ALERT, controller_showAlertHandler)

private function controller_showAlertHandler(event:ControllerEvent):void
{
drawAlertWin(event.winInfo);
}

private function drawAlertWin(info:InfoTypr):void
{
....
addChild()
}




А вот такие вещи object.object.object.AddChild(х) - неизбежно приводят к путаннице

Babylon
13.04.2013, 17:15
Ну не совсем одинаковое, учитывая, что gameStage это static var, а МainView это собственно вид где и показывается модальное окно по команде контроллера. iframe на вас нет :)

Александр Мостовой
13.04.2013, 17:20
Engine.gameView= new MainView();

Ну это то уже четвертый и он, как раз, не вызывает принципиальных возражений :)

Добавлено через 1 минуту
при условии что gameView setter :)

Babylon
13.04.2013, 17:32
не не сеттер, а тоже static

Александр Мостовой
13.04.2013, 17:33
не не сеттер, а тоже static
тогда вызывает :)

Babylon
13.04.2013, 17:41
Задача у Engine одна - наследоваться от базового класса и снабжать другие классы которые от базового класса не наследуются.

caseyryan
13.04.2013, 19:08
ПО мне так самый простой и удобный способ что-то вроде этого:

controller.addEventListener(ControllerEvent.SHOW_ALERT, controller_showAlertHandler)

private function controller_showAlertHandler(event:ControllerEvent):void
{
drawAlertWin(event.winInfo);
}

private function drawAlertWin(info:InfoTypr):void
{
....
addChild()
}




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

А по поводу stage вместо верхнего слоя view я уже написал. stageWidth, stageHeight тому причиной. Да и никакого преимущества нет в этом подходе. В любом случае для инициализации нужна какая-то ссылка. Не вижу принципиальной разницы в том будет это stage или view

Babylon
13.04.2013, 19:15
реплика: ControllerEvent.SHOW_ALERT - контроллер слушает чужие события, а не свои собственные.

caseyryan
13.04.2013, 19:31
контроллер слушает чужие события, а не свои собственные.
Как раз-таки свои собственные

Babylon
13.04.2013, 19:44
Я заметил вы любите самозацикливаться.

Александр Мостовой
13.04.2013, 19:50
реплика: ControllerEvent.SHOW_ALERT - контроллер слушает чужие события, а не свои собственные.

В примере слушателем являлся один из медиаторов view. пусть это будет ViewPopupManager.
Если view содержит ViewPopupManager то viewPopupManager - отрисовует попапы. Если содерджит виртуального персонажа проговаривающего ошибки - виртуальный персонаж проговаривает ошибки.
Это задача view отображать абстрактные данные модели в таком виде как задумано в view. Рузумнее конечно было слушать модель с ее объектом данных ошибка. Но все эти нюансы теряют значение если допускаются такие диррективные обращение извне к DisplayList объектов.

Babylon
13.04.2013, 20:23
Медиаторы ничего не отрисовывают. Они лишь группируют команды контроллера в соответствии с событиями виджируемого объекта. То же самое и для сервисов.

Psycho Tiger
14.04.2013, 13:09
Зачем? Или Вы из тех, кто не ищет легких путей? Что проще, добавить временный невидимый спрайт поверх ВСЕГО, или бегать по всему и вся задавая mouseEnabled = false? Тем более что для этих манипуляций подчас потребуются танцы с бубном. Или же, получать ссылку на документ класс и ставить ему mouseEnables = false и mouseChildren = false; Тогда в чем профит?
Профит в том, что кнопка Tab начинает вести себя правильно.

Babylon, есть такое понятие замечательное – DRY.
caseryan прав в том, что ад вроде
Engine.gameStage.stage.addChild
Просто необходимо вынести в отдельный метод. Пусть и Engine.addModal(this). А лучше вообще ModalManager.addModal
По меньшей мере, если в флешку начнут подгружаться другие, которые тоже захотят использовать ModalManager – "шарить" достаточно только его. Как и подпиливать поведение становится проще.
В остальном я ваш спор не понимаю )

caseyryan
14.04.2013, 13:25
Профит в том, что кнопка Tab начинает вести себя правильно.
Соглашусь. Но это единственный профит. Тем более он никак не противоречит добавлению прозрачного (ну или не совсем прозрачного) спрайта под модальное окно.

. А лучше вообще

ModalManager.addModal

Собственно, то, о чем я и говорил, и то, что так усердно оспаривал Babylon )

Babylon
15.04.2013, 01:05
Engine.gameStage.stage.addChild(this) лежит в конструкторе this
и на фига метод?

Александр Мостовой
15.04.2013, 01:19
и на фига метод?
ЧТо бы кто-то еще мог узнать что на сцену добавилась какая-то штуковина.

Правда я считаю что еще лучше когда компонент вью добавляет к себе в дисплей лист по событию от модели об изменении данных.

Babylon
15.04.2013, 01:51
ЧТо бы кто-то еще мог узнать что на сцену добавилась какая-то штуковина. Это бы сцена сообщила если бы могла.

Gaen
15.04.2013, 04:21
Альтернатива накрытию спрайтом - ловить клики у контейнера приложения в capture-фазе и убивать их, если они идут куда-либо кроме контейнера модельных окон. Делается реально в две строчки (assuming we're inside some ModalWindowManager class):


private function modalClick(e:MouseEvent):void{
if(!this.modalModeActive) return;
if(!this.modalContainer.contains(e.target)) e.stopPropagation();
}

caseyryan
15.04.2013, 07:45
Альтернатива накрытию спрайтом - ловить клики у контейнера приложения
Это не совсем альтернатива. Чаще спрайт ставится если нужно задний фон затемнить или размыть.

Babylon
15.04.2013, 09:22
Вот такой код ближе к правде.

wvxvw
15.04.2013, 10:53
С точки зрения других языков - синглтон в таком контексте - это скорее проблема, а не что-то желаемое. Часто проще добраться до статических свойств, и это упрощает планирование, но, например, мне недавно попалось описание автором проблем написания компилятора для языка Скала. Там он описывает первоначальный дизайн, в которм были статические поля, которые мешали создавать несколько сущностей компилятора одновременно (т.как это были мутабельные объекты - таблица символов генерируемая компилятором и т.п.). Мотивация для того чтобы так не делать, по крайней мере в Яве заключается в том, что несколько экземпляров одного и того же объекта могут быть созданы одновременно и это может значительно ускорить процесс компиляции, если возможно исходники разбить на группы. Кроме того, это так же значило, что компилятор можно было внутри Эклипса создать несколько раз - для проверки синтаксиса, для непосредственно компиляции и не знаю зачем еще - но мало ли.
И потом он еще долго описывает способы решения, и как им в итоге удалось этого избежать.

Так вот: скорее всего делать основной класс приложения синглтоном - это плохо, но иногда у этого не будет никаких негативных последствий. Сделав его синглтоном вы ничего не улучшите, но вот ухудшить можно вполне.

Psycho Tiger
15.04.2013, 11:29
Соглашусь. Но это единственный профит. Тем более он никак не противоречит добавлению прозрачного (ну или не совсем прозрачного) спрайта под модальное окно.
Если правильно разруливать – тогда шейпа. Затемнение всегда окей )
Engine.gameStage.stage.addChild(this) лежит в конструкторе this
и на фига метод?
Инкапсулировать такую жуть :) Если такая запись у Вас не вызывает зрительного отторжения – ну что же, у всех своё чувство прекрасного.
Но вот из минусов:
1) Это DRY до тех пор, пока все модальные окна наследуются только от этого, у которого в конструкторе написано то-самое.
2) Это рушит парадигму обязанностей у объектов на уровне того, с чем работаем. Поясню: если есть некоторый ModalManager, который может добавлять IModal – то вся работа заканчивается на реализации интерфейса IModal. Какие кривости использует ModalManager – никого не волнует. А вот "вшивая" его в цепочку наследования – приходится ориентироваться на родительский класс, потому что это не какой-то там IModal, который никому плохо не сделает. Можно говорить о том, что AbstractModalWindow – тоже "пофиг" как работает, мол, работаем же со спрайтом "в черную", но вам же приходится ориентироваться при разработке на него.
3) Если требуется метод очищения всех модальных окон (предположим, их может быть стек) – вообще непонятно, чья обязанность.
4) Для стороннего разработчика – если всеми правдами-неправдами можно подогнать это под single responsobility – то под KISS – никогда.
5) А как насчет модальности не для stage?
6) Реиспользуемость кода – отсутствует. Прямая связанность с каким-то Engine.
7) Для каждого показа модальное окно нужно пересоздавать.

Babylon
15.04.2013, 12:00
Кто кого куда вшивает и где вы увидели наследование в композиции? Использовать интерфейсы при наследовании запредельно оригинально.

Psycho Tiger
15.04.2013, 12:05
А, так у Вас в каждом модальном окне
Engine.gameStage.stage.addChild(this) лежит в конструкторе this
Всё стало понятней. Спасибо за дискуссию )

Babylon
15.04.2013, 12:13
Engine.gameStage.stage.addChild(this) это к вопросу о синглтоне,а не о модальных окнах. В этом топике эти два вопроса замысловато слились.

Добавлено через 47 минут
Я пытался донести простую мысль, что виджеты, имеющие интерфейс не должны получать доступ к сцене, иначе чем через экземпляр вида this. На Виде инкапсуляция ядра заканчивается. Хочешь отрендерить модель каким нибудь виджетом свяжи его с видом ядра посредством интерфейса в медиаторе.
Виджетом может быть любой клип, модальное окно и прочее.