Всякие разные штуки сомнительной полезности сделанные в свободное от работы время.
Критика Presentation Model
Эта статья была написана по мотивам недавнего собеседования по приему на работу, где меня попоросили высказаться о presentation model и Parsley.
Если вы помните, год или два назад было очень модно писать архитектурные фреймворки. В то же время наметилось несколько различных направлений в этом неблагородном занятии. Неблагородном потому, что, переведя с заумного на обычный, цель написания и использования фреймворка такого рода в том, чтобы объяснить каждому конкретному программисту, что он бездарь, и не умеет строить приложение даже на минимально доступном ему уровне ответсвенности, не смотря на то, что на "вступительных" экзаменах его только и спрашивали что про архитекруру и использование шаблонов программирования.
Но цель этой статьи не в критике всех существующих фреймворков, а конкретного направления, с которым мне пришлось работать. Речь пойдет о Parsley и о presentation model, но этот фреймворк будет использован только как иллюстрация. Я надеюсь, что существующие недостатки и проблемы были логическим следствием проблем в теории, и никакая улучшенная реализация не спасет ситуацию, т.как теория в корне плохая.
В первую очередь, первоисточник: http://martinfowler.com/eaaDev/PresentationModel.html Martin Fowler - человек, с легкой руки которого мы сегодня используем термин presentation model, описал основные принципы работы в этой статье. К сожалению из документации к Parsley не понятно как именно нужно использовать эту библиотеку и большинство примеров в ней находятся на за гранью здравого смысла, но лучшего источника нет. Это так, отчасти, еще и потому, что Parsley одновременно еще и делает dependency injection - абсолютно лишнюю в AS3 вещь, и это во многом затрудняет понимание происходящего.
Для начала, если вам лень читать Мартина Фаулера, в двух словах о том, что из себя представляет presentation model. Это одновременно две разные вещи: название механизма взаимодействия между элементами интерфейса пользователя и логикой программы вцелом, и конкретной части механизма, отвественной за сохранение состояния элементов интерфейса пользователя. В дальнейшем я буду использовать presentation model (pm), понимая под этим конкретный класс, реализующий взаимодействие.
Концепция взаимодействия заключается в том, что компонент интерфейса централизовано сохраняет свое состояние в pm, и так же централизовано его оттуда восстанавливает. Это можно представить на примере чекбокса: когда вы над ним нажимаете клавишу мышки, чекбокс вызывает метод у pm, передавая ему сообщение о нажатии и ожидает от pm, что тот обработает нажатие и задаст новое значение.
Проблемы, которые возникают при детальном рассмотрении нашего примера:
Что случится, когда кроме одной возможной операции (нажатия мыши) компонент будет реагировать на другие события?
Следуя статье Фаулера - нам нужна одна функция для обновления всех значений во всех изменяемых частях компонента. Это значит, что если в нашем компоненте есть два чекбокса, при нажатии на один из них, значение для второго будет обновлятся точно так же, как и для первого, хотя это абсолютно не требовалось. Фаулер говорит в статье о разных уровнях детализации (или специфичности) обновления (coarse granularity vs fine granularity), понимая, что проблема существует, но не предлагая никакого решения. Не понятно зачем создавать проблему на пустом месте.
Кто должен зависеть от кого, или, перефразируя, кто должен знать о ком - pm о компоненте, или компонента о pm?
Следуя Фаулеру, опять же, нет универсального хорошего решения, решая в пользу одной из сторон, мы тем самым затрудняем себе тестирование другой стороны. Опять же - искусственно созданная проблема, которой могло бы не быть, если бы в принципе такой подход не использовался.
Что делать, когда компоненты не тривиальны, и состоят из других компонент, в которых тоже нужен свой pm?
Описание концепции не дает никакого ответа. Parsley предлагает для этого использовать dependency injection - т.е. неявным образом создавать глобальные переменные, и так же неявно передавать их дочерним компонентам. Естественно, такой подход превращает проект в монолитный блок кода не поддающегося тестированию, который нет возможности использовать повторно или обновлять по частям. Что еще хуже, найти то место где же действительно создаются те самые глобальные переменные, задаются очень важные настройки становится очень тяжело. Ситуация более типичная для монументальных продуктов написаных на Яве, с изобретенными по ходу написания настройками, распихаными по разным XML файлам в произвольных частях программы.
Если не использовать DI, то возможны два варианта: можно передать ссылку на дочерний pm дочерней компоненте в родительской компоненте, или спроектировать родительский pm так, чтобы он передал ссылку на дочерний компонент дочернему pm'у. Ни первый ни второй варианты не достаточно гибкие для того, чтобы позволить независимое тестирование родительской и дочерней компонент. В первом случае тестирование родительской компоненты, при наличие дочерней компоненты, не возможно без дочернего pm. Аналогично, во втором случае, нет возможности тестировать pm'ы без компонент.
На практике это выливается в то, что код просто никогда не тестируется. Вернее, он доводится до состояния, когда "вроде" работает и в этом состоянии доживает до момента, когда его полностью, со всеми потрохами, выбрасывают и пишут заново.
Реализация связывания между pm и компонентой - однообразный, механический труд. Человеку не хочется заниматься такими вещами, соответсвенно, напрашивается автоматизация. Автоматизация, очень часто, дело очень полезное, но не тогда, когда возможны исключения, и не тогда, когда автоматически сгенерированный код создает новые зависимости. На практике же, связывание (binding) создает зависимость к Flex Framework. Да и Parsley - это не генератор вашего кода, это библиотека (набор библиотек), которые вы подключаете к своему проекту, увеличивая общий размер, потребление памяти, количество окольных путей от одной точки интереса к другой (indirection layers); уменьшая при этом скорость работы.
Я думаю, что это очевидно, что альтернатива использованию presentation model и Parsley, или похожих библиотек, заключается в осознании того, что архитектурных фреймворков не бывает. Архитектура, это то, как вы строите вашу программу, и это не возможно импортировать в виде готового кода написаного другими людьми. Верить в то, что использовав архитектурный фреймворк ваш код вензапно превратится в логически правильно выстроенную, модульную, удобную в поддержке программу так же наивно, как и надеятся на то, что использовав те же краски, которыми пользовался ван Гог, ваши картины отправятся прямиком в известнейшие музеи мира
Всего комментариев 82
Комментарии
![]() ![]() |
|
взяли? =)
|
![]() ![]() |
|
Отличная статья.
Как раз задавался вопросами по целесообразности использования архитектурных фреймворков. |
![]() ![]() |
|
Пока что не известно, но судя по первым отзывам, экзаменирующий сказал что-то в духе "вы шокирующе честный человек", и, я думаю, это можно понимать как "нет"
![]() |
![]() ![]() |
|
Цитата:
связывание (binding) создает зависимость к Flex Framework
|
![]() ![]() |
|
Что до DI и отличия C# / Java - ну, если честно, то ив Java от него никому не хорошо, кроме тех, кто его написали, но не используют
![]() В более глобальном смысле: по закону подлости, с завидным постоянством, ошибки случаются именно в той части кода, которая делается автоматически, и на которую повлиять тяжелее всего. DI является именно такой частью - ведет себя непредсказуемо, требует асинхронного выполнения, там, где это абсолютно лишнее, ограничивает, например, аргументы конструктора. Пожалуй, про непредсказуемость стоит отдельно объяснить. В том же Спринге класс-реализацию, необходимую для инъекции находят по его... не поверите, пакету! (и метаданных в классе). Так что если у вас случайно оказались два таких класса в одном пакете - результат непредсказуем. Непридуманная история. ![]() Почему именно не нужен в AS3 - нет никакой необходимости это делать неявно. Т.е. в AS3 нет такого параноидального страха, как в Яве по поводу передачи ссылок с типом Object, а потом приведению их к нужному типу, или просто обращение к свойству, даже не зная какого типа объект. В Яве это все очень муторно (в том числе изза того, что существует множественный диспатч, но функции нельзя передавать по ссылке) и всякие попытки динамичности выглядят очень неуклюже. DI для Явы, это своего рода замена AS3шному Object, с возможностью что-то не типизировать, но с типичной для Явы кучей писанины и пушек специализирующихся на стрельбе по воробъям. > неправда же. Да, именно, что создает, класс Binding в каком-то месте тестирует на is IUIComponent - а этот интерфейс все остальное за собой тянет. Этот тест можно удалить, без особого вреда, особенно, если IUIComponent использовать не планируется, но это уже не то же самое. |
|
Обновил(-а) wvxvw 18.02.2012 в 22:33
|
![]() ![]() |
|
я использую биндинг и mxml - флекс не тянется. никаких особых телодвижений не делал.
|
![]() ![]() |
|
Цитата:
Т.е. в AS3 нет такого параноидального страха, как в Яве по поводу передачи ссылок с типом Object, а потом приведению их к нужному типу
![]() Да, умеешь ты обосновать "ненужность" технологии, всё, DI трогать не буду. Хорошо что твои замечания про git прочитал после того как освоил и подсадил всех на него в нашей конторе, а то так бы и мучались с SVN ![]() |
|
Обновил(-а) expl 18.02.2012 в 23:38
|
![]() ![]() |
|
Цитата:
что называется Unix-style
![]() |
![]() ![]() |
|
Хорошая статья, вы сказали о том , о чём остальные молчали.
|
![]() ![]() |
|
вобще мне все равно, что думает as3 разработчик про java разработку, но раз прочитал этот местами "бред", то тоже что нибуть проглючу
от DI в java кому то не хорошо ? ок, самый элементарный пример, есть у нас сервлет class accountServlet extends HttpServlet { .. в нем происходит разбор параметров и какая то еще работа, + у нас есть бин, для работы с базой, DBManager, даже сделаем из него EJB бин, чтобы вручную не писать кластеризацию этого бина. как нам получить ссылку на этот бин, чтобы им при этом управлял контейнер.. ? используем DI, если в том же контексте сервера приложения, то делается одним движением @EJB DBManagerBean db; .. если в другом контексте, то через jndi lookup public void init() { try { Context ctx = new InitialContext(); db= (DBManager) ctx.lookup("java:comp/env/DBManagerBean"); } catch (NamingException e) { throw new EJBException(e); } вот и все, что тут страшного и для мозга непостижимого ? причем DBManagerBean может быть одним из множества реализаций интерфейса(если требуется одна для продакшна, а другая для тестирования или для каких то еще условий использования) @Local interface DBManager { ... methods. } @Stateless(без хранения состояния) //или @Statefull(хранит состояние в течении всей сессии текущего клиента) и тд.. public class DBManagerBean implements DBManager { ... } } spring это не эталон реализации DI, посмотрите на другие варианты, например javaee, ejb3, потом возможно мнение измениться. без обид, но ваше мнение про DI в жаве, на данном этапе как мое лет 10 назад, когда нифига не осмыслив документацию, смотрел на лог ексепшнов и думал, какие там все тупые что напридумывали такую сложность, а я тут сижу такой гений и не понимаю что происходит. когда запустите серверную часть с количеством подключений(конкурентных! т.е потоковых) хотя бы 10тыс, + от ошибки в каком то потоке могут списаться финансы не туда, тогда задумаетесь, а что все эти инженеры sun(oracle) делали и зачем придумали эти "сложности". а то что передавать Object, когда имеете большую иерархию классов(в ООП никак по другому, не нравиться ООП переходите на functional style), так это отгребете при разрастании кода такой гимор. ну а этот абздец, так вобще ни понял о чем он ?! >Почему именно не нужен в AS3 - нет никакой необходимости это делать неявно. Т.е. в AS3 нет такого >параноидального страха, как в Яве по поводу передачи ссылок с типом Object, а потом приведению их к >нужному типу, или просто обращение к свойству, даже не зная какого типа объект. В Яве это все очень >муторно (в том числе изза того, что существует множественный диспатч, но функции нельзя передавать >по ссылке) и всякие попытки динамичности выглядят очень неуклюже. DI для Явы, это своего рода >замена AS3шному Object, с возможностью что-то не типизировать, но с типичной для Явы кучей >писанины и пушек специализирующихся на стрельбе по воробъям. DI для java замена чему и что там муторно, существует множественный диспатч и тд..?? уважаемый, вы под чем.. бывает я сам иногда делаю такой финт public class AnimationType { public static const NONE:AnimationType = new AnimationType(NONE); public static const MOVE:AnimationType = new AnimationType(MOVE); public static const ROTATE:AnimationType = new AnimationType(ROTATE); public static const COLOR:AnimationType = new AnimationType(COLOR); public static const EXPAND_IN:AnimationType = new AnimationType(EXPAND_IN); public static const ENTER_LEFT:AnimationType = new AnimationType(ENTER_LEFT); public static const ENTER_RIGHT:AnimationType = new AnimationType(ENTER_RIGHT); public static const ENTER_BOTTOM:AnimationType = new AnimationType(ENTER_BOTTOM); public static const ENTER_TOP:AnimationType = new AnimationType(ENTER_TOP); public static const FADE_IN:AnimationType = new AnimationType(FADE_IN); public static const TYPES:ArrayCollection = new ArrayCollection([ {animationType:"Move",animationName:ResourceManager.getInstance().getString("effects","Move"), easingType:"", state:true, runOrder:0, sXp:0, sYp:0, eXp:0, eYp:0, time:1, delay:0, isSerial:false, isParallel:true}, {animationType:"Rotate",animationName:ResourceManager.getInstance().getString("effects","Rotate"), easingType:"", state:true, runOrder:0, rotationAngle:360, rotationDirection:-1, currentRotation:0, time:1, delay:0, isSerial:false, isParallel:true}, {animationType:"Color", animationName:ResourceManager.getInstance().getString("effects","Color"),easingType:"", state:false, runOrder:0, originalColor:0, colorTrans:0, time:1, delay:0, isSerial:false, isParallel:true}, {animationType:"ExpandIn", animationName:ResourceManager.getInstance().getString("effects","ExpandIn"), easingType:"", state:true, runOrder:0, currentScaleX:1, currentScaleY:1, time:1, delay:0, isSerial:false, isParallel:true}, {animationType:"EnterLeft", animationName:ResourceManager.getInstance().getString("effects","EnterLeft"), easingType:"", state:true, runOrder:0, sXp:0, sYp:0, eXp:0, eYp:0, time:1, delay:0, isSerial:false, isParallel:true}, {animationType:"EnterRight", animationName:ResourceManager.getInstance().getString("effects","EnterRight"), easingType:"", state:true, runOrder:0, sXp:0, sYp:0, eXp:0, eYp:0, time:1, delay:0, isSerial:false, isParallel:true}, {animationType:"EnterBottom", animationName:ResourceManager.getInstance().getString("effects","EnterBottom"), easingType:"", state:true, runOrder:0, sXp:0, sYp:0, eXp:0, eYp:0, time:1, delay:0, isSerial:false, isParallel:true}, {animationType:"EnterTop", animationName:ResourceManager.getInstance().getString("effects","EnterTop"), easingType:"", state:true, runOrder:0, sXp:0, sYp:0, eXp:0, eYp:0, time:1, delay:0, isSerial:false, isParallel:true}, {animationType:"FadeIn", animationName:ResourceManager.getInstance().getString("effects","FadeIn"), easingType:"", state:true, runOrder:0, currentAlpha:0, time:1, delay:0, isSerial:false, isParallel:true} ]); public function AnimationType(type:AnimationType) { } public function toString():String { switch (this) { case AnimationType.MOVE : return "Move"; case AnimationType.ROTATE : return "Rotate"; case AnimationType.COLOR : return "Color"; case AnimationType.EXPAND_IN : return "ExpandIn"; case AnimationType.ENTER_LEFT : return "EnterLeft"; case AnimationType.ENTER_RIGHT : return "EnterRight"; case AnimationType.ENTER_BOTTOM : return "EnterBottom"; case AnimationType.ENTER_TOP : return "EnterTop"; case AnimationType.FADE_IN : return "FadeIn"; default : return "None"; } } public static function createAnimationObjectByType(aType:String):Object { for each(var type:Object in TYPES) { if (aType == type.animationType) return ObjectUtil.clone(type); } return "None"; } и потом по свойству полученного объекта, ojb[name] вытаскиваю нужную инфу, но для большой системы это не подход, значит не хватает ума разработать нужную иерархию классов. видел сайт на флеше из 4 страниц, где юзается во всю puremvc, сказал афтору нафига тебе это, на что он обиделся.. к тому что каждой задаче свой подход, что кажется лишним на флеш клиенте, абсолютно может быть не лишним java серваке |
|
Обновил(-а) jaa_breath 10.03.2012 в 13:23
|
![]() ![]() |
|
Ну и что? Это все было бы проще сделать в коде явно, чем делать это через задний проход, и потом получать море удовольствия от бесконечных ошибок, которые невозможно дебажить - потому что код находится хз. где, и непонятно как работает.
Если уже и использовать ваш пример с тысячами подключений (почему-то в Яве всегда очень любят рассказывать о миллиардах транзакций и тысячах подключений, которых в реальности никогда не бывает, но не суть), так вот обычный Ява код понятен, доступен каждому программисту, не вызывает сложностей при отладке и сопровождении. Код зарытый в какие-то хз. кем написанные библиотеки, прикрученные непонятно как, соответствующие поставленной задаче хорошо если на 50% сопровождать гораздо труднее. Изза этого любой нетривиальный проект на Яве это море багов, ненужных зависимостей, разного рода заплаток, костылей и т.п. которые только еще больше запутывают ситуацию пробуя следовать тем же принципам. ПС. Ваш AS3 код - очень плохой, безотносительно DI, он просто плохой потому, что используются "самодельные" null, "антипаттерн" string-programming, отсуствие типизации и т.п. Типичный второсортный код, который пишут для задач без претензий на длительную поддрежку, быструю работу и т.п. В этом контексте, я могу согласится, если задача ставилась как "write once, run away", тогда, да DI вполне соответствует требованиям: быстро склепать какую-то хрень, которая не развалится пока разработчика еще можно найти - да, но использовать в проектах, которые рассчитаны на длительную поддержку, развитие, или просто быструю безотказную работу - категорически нет. |
|
Обновил(-а) wvxvw 10.03.2012 в 17:13
|
![]() ![]() |
|
У всех яверов с кем я сталкивался Оопухоль головного мозга и наркоманская зависимость к паттернам и фрэйворкам.
Не знаю из-за чего так получается. |
![]() ![]() |
|
>Если уже и использовать ваш пример с тысячами подключений (почему-то в Яве всегда очень любят рассказывать о миллиардах транзакций и тысячах подключений, которых в реальности никогда не бывает, но не суть),
всмысле не суть и как это не бывает ?! что нибуть писали по сервачной части сами, например сервис по бронированию авиа/жд билетов, или по туристическому сервису ? потом, >Ну и что? Это все было бы проще сделать в коде явно, чем делать это через задний проход, и потом >получать море удовольствия от бесконечных ошибок, которые невозможно дебажить - потому что код >находится хз. где, и непонятно как работает. а что именно было бы проще сделать ? кластер написать самому, написать самому аналог ejb бинов c автоматическим распределеним по кластеру.. если бы вы могли это сделать, не думаю что искали бы работу, скорее вы были бы на расхват.. и где эти ваши мифические непонятные ошибки ? все очень понятно если вдумчиво изучить стек javaee >ПС. Ваш AS3 код - очень плохой, безотносительно DI, он просто плохой потому, что используются "самодельные" null, "антипаттерн" string-programming, отсуствие типизации и т.п. Типичный второсортный код, который пишут для задач без претензий на длительную поддрежку, быструю работу и т.п. В этом контексте, я могу согласится, если задача ставилась как "write once, run away", тогда, да DI вполне соответствует требованиям: быстро склепать какую-то хрень, которая не развалится пока разработчика еще можно найти - да, но использовать в проектах, которые рассчитаны на длительную поддержку, развитие, или просто быструю безотказную работу - категорически нет. лол )) о какой типизации речь, если сами выше писали что в яве боятся передавать Object, вот тут как раз такой случай, а код очень даже хорош(скажем так, аналог emum + mini factory типов анимаций), поддержка отличная и безотказная работа тоже, вы похоже вобще не поняли его суть, и DI в этом куске кода вообще нету |
|
Обновил(-а) jaa_breath 10.03.2012 в 19:01
|
![]() ![]() |
|
Да, писал, веб-морда к системе составления бюджетов (XS / BTOE / FPA). Ее HP делают для British Airways и еще для кого-то. Я там конечно очень маленький винтик в машине прикручивал, но тем не менее знаком немножко.
Т.е. ситуация когда Glassfish запускается около 5 минут на выделенной серверной машине и ему выделяют около 3 гиг памяти, а в итоге все, что он делает имитируется httpd + cgi скриптом, которые вообще ни памяти ни процессорного времени практически не занимают - выглядит очень смешно. Кстати, непридуманная история. Т.как по ТЗ нужно было использовать хайбернейт, а его никак нельзя было приладить делать по-человечески запросы, их даже за него переписать нельзя. И так и эдак целый отдел опытных программистов судил и рядил, и в итоге только на логин делалось 50 запросов к базе. Ну и вся машина в том же духе. Не нужен аналог EJB бинов - они просто не нужны, и не нужно их писать. Это бестолковая трата времени на абстракции, которые не нужны. Это примерно как каждый начинающий флешер считает своим долгом написать XMLLoader в то время как можно просто использовать URLLoader с абсолютно таким же эффектом. Нужно понимать разницу, между ситуациями, когда типизация полезна - увеличивает производительность, уменьшает потребление памяти (доступ к нетипизированым свойствам заставлят выделять память в куче), от ситуаций, когда речь идет об интерфейсе общения между модулями программы - когда лучше потерять производительность, но сохранить модульность. Ваше утверждение звучит примерно так: "вот вы говорите, что насыпать десять ложек соли в чашку чая - не вкусно будет, а сами-то соль в суп сыпите!". |
|
Обновил(-а) wvxvw 10.03.2012 в 22:56
|
![]() ![]() |
|
jaa_breath, серверлет, аха. (Люблю сервелат!) А зачем в вашем примере стоко енумов? Штобы все поняли, что вы серьезно настроены? Ок, я уже приготовился выслушать очередную вашу ахинею.
Не! Я целых джва года ждал, пока вы тут это напишите. Аминь! |
|
Обновил(-а) dimarik 10.03.2012 в 23:14
|
![]() ![]() |
|
>Т.е. ситуация когда Glassfish запускается около 5 минут на выделенной серверной машине и ему выделяют около 3 гиг памяти, а в итоге все, что он делает имитируется httpd + cgi скриптом, которые вообще ни памяти ни процессорного времени практически не занимают - выглядит очень смешно.
Кстати, непридуманная история. Т.как по ТЗ нужно было использовать хайбернейт, а его никак нельзя было приладить делать по-человечески запросы, их даже за него переписать нельзя. И так и эдак целый отдел опытных программистов судил и рядил, и в итоге только на логин делалось 50 запросов к базе. Ну и вся машина в том же духе. ну глассфиш это ee5-6 реализация, где из коробки идет jsf2, ejb3.1, jpa2, jms, jsp, servlet и тд.. и он построен на osgi шине, то есть если все это не нужно то можно отключить, тем самым ускорив запуск в разы. нужен только http, юзайте tomcat, jetty, netty и тд.. тем более что в глассфише идет eclipselink, зачем туда сувать хибернейт ? ну, возможно нужно было, тогда запросы которые генерит хибернейт и эклипселинк(если не устраивает, а такое часто бывает), можно тюнить(отключать лишнии джойны) либо вообще писать nativeQuery, проблем никаких. все ваше мнение строится на том, что вы + кто то не смогли разобраться.. не серьезно, сами подумайте. >Не нужен аналог EJB бинов - они просто не нужны, и не нужно их писать. Это бестолковая трата времени на абстракции, которые не нужны вам возможно не нужны(или вы опять не поняли суть их использоваения), но есть очень много огромных прожектов где они юзаются, в этих бинах очень много сделано за програмиста, транзакции, секюрити на уровне классов - методов, расспаралеливание, вызов удаленных бинов как своих, если они работают на другой jvm и тд.. конечно можно все это реализовать самому с нуля, но вряд ли получиться лучше, а главное быстрее >ой, я чет погарячисля - самого главного и не заметил. Это выражение равносильно: нужен, и оно не равносильно, откомпильте и поймете, ну нету в as3 enum, а мне захотелось с ним, пришлось симулировать.. >Нужно понимать разницу, между ситуациями, когда типизация полезна - увеличивает производительность, уменьшает потребление памяти (доступ к нетипизированым свойствам заставлят выделять память в куче), от ситуаций, когда речь идет об интерфейсе общения между модулями программы - когда лучше потерять производительность, но сохранить модульность. Ваше утверждение звучит примерно так: "вот вы говорите, что насыпать десять ложек соли в чашку чая - не вкусно будет, а сами-то соль в суп сыпите!". была ситуация, в существующий онлайн конструктор сайтов, нужно было добавить анимацию к визуальным компонентам(прикол да, онлайн флеш конструктов сайтов, а анимации компонент нету!), сохранялось там все в xml, base64. анимаций в итоге оказалось мало, 9. писать иерархию классов вобще не хотелось, чтобы потом еще делать для них сериализотор в base64 и обратно, вот и придумал такой быстрый, а главно работающий способ. как уже писал, для большого прожекта такой подход не подходит, например если бы анимаций было бы больше 100, тогда, раз as3 это жесткий ООП, не смотря на все передачи функций как значение, пришлось бы фигачить по полной в стиле ООП. если отойти от темы спора немного в сторону, сейчас во всю использую на jvm, clojure(это реализация lisp), изучаю scheme и тд.. в этих парадигмах, большенство паттернов из ООП не нужно, и вобще меня лично тоже тошнит от чистой java и as3, но когда приходиться писать большие системы именно на них, то лучше потратить время изначально на архитектурное продумывание использования паттернов, чем потом самому думать, а что это я хотел сказать.. паттерны это не что то чисто академическое табу, а просто люди имеющие огромный опыт, поделились с другими, всего то. to durimarik >jaa_breath, серверлет, аха. (Люблю сервелат!) А зачем в вашем примере стоко енумов? Штобы все поняли, что вы серьезно настроены? Ок, я уже приготовился выслушать очередную вашу ахинею. Не! Я целых джва года ждал, пока вы тут это напишите. Аминь! нечего сказать по делу так ждите молча дальше, умнее будет казаться |
|
Обновил(-а) jaa_breath 11.03.2012 в 13:18
|
![]() ![]() |
|
Смотрите, если вы в Яве что-то и понимаете, то в AS3, я вас должен разочаровать, - не очень ориентируетесь. Ваши заявления о вашем коде не правильные, а мои - правильные.
Вы понимаете разницу между техническим заданием, и тем "что можно сделать"? В ТЗ было написано, что требуется - так и было сделано. Самая большая проблема с запуском Глассфиша была не в наличии каких-то библиотек, а в том, что нужно было выделить очень много памяти, которую он никогда не использовал. Этот пример - иллюстрация страсти Явистов к "миллионам транзакций в секунду" - т.е. 99% того, что делал этот сервер - он просто занимал память "на всякий случай", которую не использовал. Еще раз прочитайте то, что я вам ответил про EJB - его не нужно ни с нуля, ни с двух с половиной реализовывать. Его вообще не нужно ни реализовывать ни использовать. Кстати, ваш код на AS3 может быть хорошей иллюстрацией - создание ненужных сущностей и просто лишних конструкций в коде руководствуясь неправильно понятыми архитектурными принципами. Я не особо и разбирался с хайбернейтом - это не моя работа. С этим разбирались 5 отделов в HP Software. Я их, понятное дело не экзаменировал, но это люди с большим опытом работы (как правило > 10 лет), с академическим образованием и т.п. Проблема была, на сколько я мог понять в том, что ОРМ был спланирован так, что один запрос рождал кучу дополнительных запросов, таблицы нельзя переписывать, т.как в то время, как я там работал, это уже была версия 9.3 продукта - т.е. настоящие данные были у заказчика, и их было очень много. Именно поэтому я и сказал, что можно было рабочую версию заменить очень минималистичной программой - результаты использования библиотек, которые навязывали свой стиль оказались не просто плохими, а катастрофически плохими. Это еще иногда называют энтропией абстракций (или "слоеный пирог"), когда на одну абстракцию накладывается другая, потом чтобы их совместить пишут адаптеры, фасады и т.д. И в итоге полезного кода оказывается 1% от всего проекта, и, оглядываясь назад понимаешь, что если бы не использовал "вспомогательные" инструменты, то давным давно уже бы и проект закончил, и багов было бы меньше и в целом программа бы лучше работала. |
|
Обновил(-а) wvxvw 11.03.2012 в 22:05
|
![]() ![]() |
|
![]() ![]() |
|
expl, первый вариант не очень человекочитаемый енум. Второй классический енум, который можно сделать человекочитаемым через Enum#toString();
Ой, кажется я Кэп ) |
![]() ![]() |
|
Цитата:
wvxvw, расскажи, пожалуйста подробнее про Unix-стайл.
Интересно как определяется размер модуля и технические подробности реализации |
![]() ![]() |
|
А я всё-таки добавлю немного ссылочек.
http://outcoldman.ru/ru/blog/show/184 http://rsdn.ru/article/patterns/ModelViewPresenter.xml http://msdn.microsoft.com/ru-ru/magazine/dd419663.aspx http://www.martinfowler.com/eaaDev/P...tionModel.html http://blogs.adobe.com/paulw/archive...tion_pa_3.html http://examples.pmwilliams.co.uk/ado...tionModel.html (сырцы по правой кнопке) |
|
Обновил(-а) Котяра 26.09.2012 в 17:22
|
![]() ![]() |
|
Котяра, три последние ссылки не работают.
|
![]() ![]() |
|
FIXED
Криво скопировались из-за сокращений |
![]() ![]() |
|
Вообще немного оффтоп но:
Цитата:
Если не использовать DI, то возможны два варианта: можно передать ссылку на дочерний pm дочерней компоненте в родительской компоненте, или спроектировать родительский pm так, чтобы он передал ссылку на дочерний компонент дочернему pm'у.
1 - Передавать ссылки вручную каждый раз. 2 - Организавать передачу через какую ни будь структуру (например http://www.flasher.ru/forum/showpost...54&postcount=2 ) 3 - дэпенденси инжекшен. 4 - статика и синглтоны. Я так понимаю, что в статье осуждаются первые 3 варианта, ну, а 4-й и так понятно, что не гуд. Так, а как тогда организовать приложение то? Просто больше вариантов не вижу... Я не о ПМ, а вообще. |
![]() ![]() |
|
Я использую 4. Только у меня статика конфигурируемая)
По сути тот же DI только вручную. |
![]() ![]() |
|
просто у меня все нуждающиеся юзают Config.model
а инициализация происходит в главном апп Config.init(PromoConfig); |
![]() ![]() |
|
Код:
DI, правда, с первого взгляда удобным не кажется. Т.е. надо втянутся чтобы использовать. Вот поэтому есть сомнения. С одной стороны - ну реально бред А с другой - люди освоили неочевидно удобную вешь и говорят что это клёво - может интервьюэр прав? (сам я на DI так и не подсел - не понимаю приимуществ) когда вы передаёте готовый инстанс чего-либо в конструкор или сеттер это и есть инверсия контроля. преимуществa DI: 1 позволяет модулю сфокусироваться на своей задаче 2 ослабляется связанность модулей между собой 3 обеспечивает простоту замены модулей 4 упрощает тестирование и исправление ошибок иначе говоря, значительно добавляет гибкости, делая приложение модульным вот тут я написал про DI http://www.flasher.ru/forum/blog.php?b=555 |
Последние записи от wvxvw
- Dired - текстовый проводник по файловой системе (29.06.2013)
- Навигация по HTML с WASD (09.06.2012)
- JavaScript, все не так плохо (07.06.2012)
- Что такое tarball и чем его пакуют (11.04.2012)
- Критика Presentation Model (18.02.2012)