| « Интерфейсы в actionscript 2.0. Часть 2. Одинаковое поведение - разная реализация | ООП и Flash. Часть 3. О фанатиках » |
Интерфейсы в actionscript 2.0. Часть 1. Внешние модули
Данное повествование будет интересно в первую очередь тем, кто не понимает, но хочет понять, зачем и как использовать интерфейсы или тем, кто пробовал использовать, но не получил никаких результатов. А результаты быть должны, так как интерфейсы - очень мощное средство.
Очертим некоторые, на мой взгляд, наиболее распространенные ситуации, в которых применение интерфейсов может быть полезным.
1. Внешние модули.
В приложении есть подгружаемые модули (внешние swf файлы), от внутренней реализации которых не хочется зависеть, но и нет желания общаться с этими модулями вслепую. Плюс необходимо, чтобы классы, используемые в модуле, не участвовали в компиляции главного приложения.
Например, существует галерея картинок, которая использует модуль выбора картинок имеющихся на сервере. Этот модуль является отдельным swf файлом, в котором заключена вся необходимая ему логика. Приложению же от модуля нужны только методы showPicturesList (показать пользователю список картинок) и getSelectedPicture (вернуть выбранную пользователем картинку). Смело можно делать интерфейс IPicturesSelector с данными методами.
- /**
- * Интерфейс для модуля выбора картинок.
- * @author J.Nikolaeva
- * @version 12.12.2006
- */
- interface IPicturesSelector {
- /**
- * Показ списка картинок.
- * @return ничего
- */
- public function showPicturesList():Void;
- /**
- * Возвращает выбранную пользователем картинку.
- * @param
- * @return
- */
- public function getSelectedPicture():Picture;
- }
Какие получаем плюсы при данном подходе?
- В случае неправильного обращения к модулю будет выдана ошибка на этапе компиляции, что приятно и удобно. При слепом общении с модулем можно потратить на поиск такой ошибки достаточно много времени. Конечно, стоит упомянуть об одном минусе, который существует в as2. Сама по себе подгружаемая swf не может имплементить интерфейс. Но можно пойти на разные хитрости, например, определить в главном таймлайне метод getPictureSelector, который будет возвращать объект класса с ожидаемым интерфейсом.
- При компиляции главного приложения классы модуля не участвуют. Они были бы включены в компиляцию при обращении к модулю, через класс объектом которого он является. Это особенно важно, когда в приложении большое количество модулей.
- Если необходимо будет что-то поменять в модуле или заменить весь модуль, то не будет необходимости переписывать что-то в главном приложении. Это, конечно, при условии сохранения интерфейса модуля. И более того, при изменении модуля нет необходимости перекомпилять само приложении, что является плюсом, если разработчик модуля не имеет исходников главного приложения.
Трекбек адрес этой записи
URL трекбека (щелкните правой кнопкой мыши и скопируйте ссылку)
7 комментариев
"определить в главном таймлайне метод getPictureSelector, который будет возвращать объект класса с ожидаемым интерфейсом"
Метод должен вернуть объект, предварительно создав экземпляр класса, который вынесен в отдельный модуль. Но при упоминании имени этого класса, он будет также добавлен и в главное приложение. Как быть? Или я что-то не так понял?
PS: Preview комментария не работает :/
Хм. А про Preview одно из двух. Либо баг в движке, либо в теме. Проверю на досуге.
Ну а рассказать тебе про getPictureSelector оставлю Юле
Хитрость может заключаться, например, в следующем. В главном таймлайне определяем метод getPictureSelector, который будет возвращать ссылку на нужный объект. К сожалению, полностью определить сигнатуру этого метода нельзя, то есть, вызывая этот метод у мувиклипа, нельзя быть уверенным на этапе компиляции, что вернут нужный объект. Но это можно проверить и выдать ошибку уже на этапе выполнения.
Вот пример.
Пусть у нас есть класс ConcretePicturesSelector, который имплементит интерфейс IPicturesSelector. Тогда в главном таймлайне модуля пишем примерно следующее.
var pictureSelector:IPicturesSelector = new ConcretePicturesSelector();
function getPictureSelector():IPicturesSelector {
return pictureSelector;
}
Если ConcretePicturesSelector вдруг не будет имплементить IPicturesSelector, то получим ошибку компиляции. ConcretePicturesSelector не будет включен в компиляцию главного приложения, так как его объект будут воспринимать только как нечто с интерфейсом IPicturesSelector.
В самом приложении вызываем этот метод у загруженного мувиклипа. Так как мы не можем быть полностью уверенными в том, что вернет мувиклип, то на всякий случай проверяем, то ли он вернул.
var picturesSelector:IPicturesSelector;
if (movie.getPictureSelector() instanceof IPicturesSelector) {
picturesSelector = IPicturesSelector(movie.getPictureSelector());
} else {
trace('movie.getPictureSelector() is not instanceof IPicturesSelector!');
}
Такое чувство, что я почти понял...
Нет ли у Вас тестового fla, заценить оченно хочецца.