Десять советов для работы с Cairngorm
Sunday, November 11, 2007Эта заметка - перевод статьи 10 tips for working with cairngorm. Статья показалась мне чрезвычайно интересной и полезной в плане общих советов по применению фреймворка, особенно в первый раз. За перевод спасибо Виноделу.
Это Применимо к Flex 2.0.1 с любой версией Cairngorm. Поскольку опыт программирования во Flex у всех различен, это не факты, а только мое мнение, основанное на моем более чем двухлетнем опыте использования ARP & Cairngorm. Более того, существуют альтернативы Cairngorm, однако я не могу испытывать их столько, сколько хочу.
Поскольку я работаю именно над продуктом, я не могу по своему усмотрению «взять и попробовать эту среду на этом новом проекте». Я работаю с одним и тем же базовым кодом, поддерживая существующих клиентов, и не могу совершать резких изменений в кодировании, не рискуя быть уволенным.
1. Если Cairngorm кажется вам сложным, не волнуйтесь, это так и есть, вы не одиноки.
“Куча кода на _root вместо всех этих классов и соглашений? Это займет целую вечность!”. На самом деле к этому надо просто привыкнуть. Я почувствовал себя уверенно с Cairngorm только на четвертом проекте. Однако до сих пор я совершенствую стиль работы, пробую разные штуки. Чем больше людей приходят во Flex, тем больше кульных идей и техник появляется вокруг.
2. Вам кажется, что у вас поначалу уйдет много времени только на то, чтобы вообще что-то сделать в Cairngorm. И это правда..
OMFG… три класса для того, что во флеше заняло бы одну строку?
Генератор кода поможет, особенно на начальной стадии работы над проектом.
3. Только Commands устанавливают данные в Model; вы можете это побороть, но не стоит, если можете исправить код.
В Model View Controller, только Controller устанавливает данные в Model. В этом случае Commands выступают в качестве Controller (обычно) и в качестве таковых установка данных ModelLocator – их единственная работа. Если данные на@бываются, вам сразу понятно, что накосячил Command. Вам никогда не надо задавать вопрос «кто устанавливает мои данные, где и когда?».
4. Delegates заставляют сервер вызывать и парсить данные (иногда в Factory).
Это произошло в моей карьере лишь однажды: я работал с PHP для серверной части, которая парсит XML, в разгар проекта мы переключились на OpenAMF и Java, где пришлось парсить объекты. При использовании Delegates вам придется только поменять код Delegates, не трогая остальную часть вашего приложения. Данные Commands сохранятся.
Я пользуюсь Factories только потому, что
A) для парсинга может потребоваться много кода, а вы не хотите, чтобы Delegates выглядели более сложно, чем они есть
B) вы легко можете распределить процесс парсинга в том же классе Factory.
5. Если вы видите, что Command парсит данные, он написан неправильно.
Парсинг отличается от фильтрации, изменения и ассемблирования. Это значит, что изготавливать Value Objects из XML лучше в Delegate, а не в Command. Нормально и связывание с ArrayCollections, содержащими предустановленные значения. Помните, что если Command получает необработанные серверные данные, - вы или некорректно используете Delegates, или у вас правильно работает AMFPHP/FDS/WebOrb, хехе.
6. Существует три способа использования Commands и Delegates. Я предпочитаю А, так как он дает небольшие файлы классов и очень четкий.
A) Для каждого случая использования создается один Command и один Event. А иногда нужно сделать и один Delegate. (например LoginEvent, LoginCommand, LoginDelegate)
B) Для каждого случая использования вы можете упаковать их в один пакет.
Например, Login, ChangePassword, ForgotPassword составили бы один класс. В этом случае для определения запускаемой части используются константы. (то есть, у LoginEvent есть LOGIN, CHANGE_PASSWORD, и FORGOT_PASSWORD, являющиеся String константами. У LoginCommand есть switch, который определяет команду, которая должна быть запущена. У LoginDelegate есть три метода: login, changePassword, и forgotPassword которые может использовать Command.
C) Вариации на тему Б. Возможно существование одного Event и одной Command, но нескольких Delegates.
Этот пункт – типа обобщающий, на всякий случай. Я повидал много вариантов, которые можно назвать “В с вариациями”.
7. ViewLocators считаются «плохой практикой».
Значит, есть разработчики, которые до сих пор их любят и используют.
Однако использование верно в таком варианте: если есть View, который знает, когда в Command что-то произошло. Я использую callbacks: изменения данных в Model вызывают callbacks во Views (возможно, через setter), а некоторые используют addEventListener совместно с CairngormEventDispatcher.
8. ViewHelpers считаются плохой практикой.
То есть существуют разработчики, которым нравится идея отделения программного кода от кода разметки. Я видал соответствующие темы в блогах и в списках рассылки. Есть две общие идеи:
A) Им не нравится смешивать ActionScript & MXML.
B) Они хотят отделить View’s от “View controller code”
Некоторые используют скриптовые теги для указания на внешний файл (по моему мнению – фигня; вам придется определить контроллеры как члены-переменные а закончите вы тем, что будет в два раза больше классов View).
Некоторые используют наследование там, где вы расширяете GUI MXML.
Некоторые используют обратное и расширяют GUI MXML с ActionScript ViewHelper.
Некоторые вообще придерживаются подхода при котором Composition наследуеся от MovieClip , что я многократно видел у кодеров на Flash. Вместо ViewHelper , расширяющего класс видов, он принимает UIComponent в качестве параметра конструктора, и использует UIComponent через композицию.
Мне кажется, вы с этим разберетесь как только разберетесь во Flex. Пишите свои компоненты в MXML с кодом в скриптовых тегах. Если реально нужна эффективность или хотите начать писать на низком уровне, на классах абстрактного типа, можете писать свои компоненты на ActionScript. Если же хотите закончить «до заката» - используйте MXML.
9. Вместо flash.net.Responder используйте mx.rpc.Responder.
Да, это неудобно, так как Flex 2.0.1 не предоставляет исходников (эта информация уже устарела - прим. перев.), но, по-моему, Flex Builder не очень хорошо справляется с классами с одинаковыми названиями. Просто пользуйтесь тем, что использует Flex и бросайте работу. Если кто-то требует flash.net.Responder - напишите враппер, чтобы перевести его во Flex.
«Сэр…Вам нужен галстук чтобы войти в ресторан. У нас есть один, минутку»
10.Делайте так, чтобы View не использовали CairngormEventDispatcher (или события, которые работают с CairngormEvent, используя event.disaptch()).
Вместо этого делайте “глубоко” транслируемые события View.
Или соедините их так, чтобы контроллер View мог вызывать события Cairngorm, или постройте их «типа домино».
Обычный сценарий, когда itemRenderer - это классы в DataGrid.
Вы:
- делаете класс itemRenderer. Если есть что-нибудь «кликабельное», посылается обычное событие по «клику».
- расширьте DataGrid который использует обычный itemRenderer, и поместите обычное событие в <mx:Metadata> вверху. В противном случае классом, который содержит DataGrid и будет допущен к подключению к событиям через MXML, будет только ActionScript.
Если вы используете MXML, то компиляция не удастся, поскольку у DataGrid нету такого события в его исходном коде.
Поначалу может показаться круто иметь LoginForm чтобы транслировать LoginEvent, но будет неудобно использовать его для других целей; это «тяжело написано» для того, чтобы использовать специальный CairngormEvent. Применяется это ко всем компонентам. Инкапсулируйте ваши компоненты, и лучшее, что вы можете - сделать события всплывающими.
