← All posts tagged mate

develar
love mate Flex Йхо-хо. Пишу UI. С использованием флекса. Кайфово. Потому что от флекса осталась только низкоуровневая реализация всяких штук типа собственно платформы (systemmanager, focusmanager и прочая) и реализация концепций типа datagroup/itemrenderer, layout (оставленных в силу того, что переписывание абсолютно бессмысленно — никакого профита не будет для конечного разработчика (нюансы типа памяти/cpu вообще тут не при делах) — лучше написать костыль в своей обертке, чем эстетствовать, беря на себя ответственность (maintain и первоначальные затраты времени) за то, что лишь опосредованно нужно для решения исходной задачи).

На моем новом проекте впервые удалось полностью использовать наработанные библиотеки и опыт со старых. Дописанный для более IoC mate (plexus, контейнеры, полноценное инжектирование по интерфейсу и прочая) и библиотека Cocoa позволяют мне сейчас легко и с кайфом от чистого и не омраченного ничем секса решать поставленную задачу — легко, удобно и быстро.

Вот нужно мне отскиновать TabView (опустим момент, что во флексе 4 его нет вообще, а в 3 он убогий (ленивое создание вьюшек и прочие плюшки создания на основе явной модели), тут просто пример) — во флексе 4 вы должны скопировать весь MXML скин для поправки пары строчек. А с cocoa мне никаких новых классов не нужно создавать — тупо строчку типа data["ProjectView.TabView.b"] = RectangularBorder.create(NaN, 0xb8b8b8, new Insets(1, 20 + 1, 1, 1), new FrameInsets(0, 20)); в LaF добавить (тут ProjectView это laf sub key flyti.org При этом я автоматом получаю плюшки типа легкой смены темы (в случае со скинование флекса, вам придется или еще раз дублировать ваш измененный скин в новую тему, чтобы поправить только 7 символов цвета, или же извращаться как-то с getStyle/вводить некий свой механизм).

А если мне нужно иметь скин, который через LaF отскиновать сложновато (типа разница не только в цветах, но и в идеологии), то опять же легко тупо отнаследоваться от некого базового plaf и переопределить в нем только те методы, что нужны (назначив иной item renderer class для skin part или же скин для компонента в целом). Да, низкоуровневые компоненты в основном скинуются написанием на ActionScript — потому что плюшки mxml там неочевидны — логика довольно сложна и никакого профита от выражения на xml языке (призванном быть языком лишь разметки) мы не получим. А композитные, типа Sidebar, на mxml — в отличие от порнографии во флексе, где смешивается контент и хром, никакого неудобства при поддержке/расширении таких mxml-based скинов нет — Sidebar содержит только и только labelBar + paneGroup, и при скиновании такого компонента лезть в его mxml нет никакой необходимости — paneGroup скинуется посредством item renderer, а labelBar тоже соответственно (то бишь через laf можно переопределить borders и прочие нюансы, как на примере с TabView определить border для viewStack).
develar
mate Flex Собеседовал девушку на позицию flex-разработчика. Искренне возмущалась тем, что mate каждый раз при обращении ко view (InlineInvoker — типа дернуть вызов) создает экземпляр вместо использования существующего. Такие моменты сразу показывают насколько человек слаб в теории, что его не тошнит при даже мысли "дернуть метод у view" ;)
develar
mate Воот. После работы в команде я ощутил кайф и пользу для компании от моего стремления все вокруг приукрасить; Коллега пытается использовать непатченный mate после моего форка — задает отличные вопросы ;) Ага, концепция контейнера и прочая это вам не детсад нашего убого flex.
develar
mate Касательно #450938 — абстракция не течет, удалил все cache policy и политика "Компонент кешируется там, где его дескриптор" работает отлично (+ежу понятно, что instantiationStrategy не может плавать вне единого дескриптора — обычно компонент заточен под нечто определенное, поэтому лишний способ прострелить себе ногу даром нужен). mate великолепен, а если развить его идеи, получается отличный dependency injection framework как full-fledged container для component-oriented programming. Разнес управление зависимостями на собственно данные и на собственно реализацию (компонент). Инкапсулировал cache, dispatcher и injectors в контайнер, отрефакторив EventMap и MateManager (они много на себя брали, — это проблема в архитектуре mate, что доставляло ряд проблем при расширении) и добавил концепцию дескрипторов компонентов. Сказка. Осталось решить концептуальные проблемы с nested containers и будет полная сказка.
develar
mate Mate великолепен. Внес частичку радости и удовольствия от красоты и удобства Java каркасов в наш мрачный убогий мир flex-разработки. Остается смутное чувство вопроса как стать таким уже умным и, главное, нужно ли — может все дело в -волшебных пузырьках- потребностях задачи.
develar
mate Кто-то использовал атрибут cache в Mate для целей отличных от необходимости указать в локальной карте глобальный кеш для компонента? То есть было ли так, что один и тот же компонент (+ его вариации по role hint, но это можно опустить, так как этого в mate нет) использовалься в рамках одного приложения с разной политикой кеширования?
develar
mate Plexus (java ioc) по архитектуре в разы лучше mate. В mate довольно часто при использовании компонента в локальной event map нужно ставить для него cache=global. А в plexus все гораздо логичнее и удобнее — кеш в том контейнере, в каком содержится дескриптор компонента. Форк mate постепенно превращается в юзабельный полноценный full-fledged container, который позволяет applications can utilise component-oriented programming to build modular, reusable components that can easily be assembled and reused.
develar
mate после ускорения gumbo на 10%-20% в результате нормальной политике работы с событиями lifecycle перестал работать mate — mate.asfusion.com . в нашем форке все нормально, но как бы это показатель ;)
develar
mate Вопрос на засыпку — FlexEvent.PREINITIALIZE оно с баблингом или нет? Ага, без баблинга. А как тогда работает MainEventMap mate.asfusion.com ? А почему не работает для детей application? А почему инжекторы на creationComplete, а не на preinitialize? Для большинства разработчиков очень круто думать что вот для App я могу мешать в одну кучу события приложения (баблинг или Dispatcher это единственный путь что-то кинуть так, чтобы оно было перехвачено в EventMap (не LocalEventMap, а именно глобальной)) и события lifecycle обычного компонента (но только для app ;)). Но не стоит это сомнительная и путающая фича того, что в mate GlobalDispatcher вешается два listeners — на app и systemManager c проверкой в системной слушателе — а не перехвачено ли событие в app слушателе (а это верно в 99%).

Правильным, читабельным и не путающим решением является изменение политики инжекторов — инжектирование на preinitialize — что невозможно, так как большинство, для которых пишется универсальный tool, не программируют нормально с соблюдением правил типа валидации свойств только в commitProperties, состояний только по invalidateSkinState и т. п. Инжектирование на preinitilize позволит тогда использовать ListenerInjector:

<Injectors target="{Application}">
<ListenerInjector eventType="{LoadModuleEvent.INITIAL_MODULE_LOADED}" method="initialModuleLoaderHandler"/>
<EventAnnouncer generator="{ApplicationConfigurationEvent}" constructorArguments="{ApplicationConfigurationEvent.LOAD}"/>
</Injectors>
develar
mate Вот тут был месяц назад задан риторический вопрос — "Mate — IoC ли?" develar.livejournal.com
Mate сейчас очень далек от звания полноценного IoC фреймворка (inversion-of-control (IoC) or dependency injection framework, plexus.codehaus.org но для большинства flex-приложений его хватает. Собственно, меня он полностью устраивал до того момента, как потребовалось иметь приложение в разных вариантах. Есть приложение типа iWeb — и для пользователя оно представлено как viewer, редактор сайта (web browser) и редактор темы сайта (AIR).

Доработал mate.

<?xml version="1.0" ?>
<ComponentMap xmlns="http://mate.asfusion.com/" xmlns:fx="http://ns.adobe.com/mxml/2009">
<Component role="{ElementPluginResolver}" implementation="{ElementPluginResolverImpl}"/>
<Component role="{ElementPluginManager}" implementation="{EditableElementPluginManager}"/>

<Component role="{PageViewManager}" implementation="{EditablePageViewManager}">
<Requirement role="{ThemeStyleResolver}" field="themeStyleResolver"/>
<Requirement role="{ElementStyleResolver}" field="elementStyleResolver"/>
</Component>
</ComponentMap>

Таким образом, все что я должен сделать, чтобы в AIR приложении некий менеджер исполнял некий общий контракт, но с совершенно иной реализацией, это зарегистрировать его как исполняющего некую роль — и мы избавлены от необходимости создавать для него отдельный EventMap (в EventMap мы ссылаемся на интерфейс — <MethodInvoker generator="{ElementPluginManager}" method="load" arguments="{event.pluginInfo}"/>
).

Также наши менеджеры могут стать слишком сложными, и мы вынуждены будем прибегнуть к агрегации. Или просто у двух менеджеров будет необходимость в некой вторичной по отношению к ним, но таки обязательной работе — типа как в примере выше ThemeStyleResolver и ElementStyleResolver нуждаются в StyleDataFactory. Mate нам вроде как тут помощник, но лениво писать DI как Field Injection в EventMap (к этому относится комментарий "ленивой инициализации графа зависимостей" — по умолчанию так и просится вариант, при котором вы не получаете ленивую), не говоря уже об инкапсуляции. AS как язык убог и такое же красивое решение как в Java не получится, но и custom namespace, несмотря на их фактическую непригодность к использованию, в данном варианте нормальное решение. Просто указываем Requirement (ага, как в plexus ;)).

Отстрелить себе ногу с ComponentMap очень просто — нет барьера в виде "придумать имя событию -> создать класс события -> написать обработчик", поэтому архитектору думать надо тут поосторожнее.

Но все эти *Map — чистой воды порнография. Почему? Потому что juick.com Мне, как разработчику, нужно всего лишь аннотировать метод что он отвечает за какое-то событие, Аннотировать класс, что он компонент и какую роль играет. Вручную писать все эти Map утомительно и бредово. Для одного приложения терпимо, а в реальных сложных системах у вас будет куча мелких файликов, а в Main.as будет простынка с их перечислением (и будут соотвествующие проблемы, когда вам захочется что-то поменять). Вот аннотации я еще и не реализовал. Но и реализовать их при текущем компиляторе сложно — лелею надежду на редактор базированный на MPS от Евгения Потапенко (разумеется, вряд ли он будет содержать нужный функционал, но ведь, наверное ;), их кодовая база будет расширяема и сторонних разработчиков не будет тошнить от архитектуры/кода :)). Разумеется, при review системы удобно (более чем удобно) иметь карту — ну так нам никто не мешает сгенерировать ее из аннотаций.