ООП во FLASH 5

Пространства имён


Классы это, конечно, всего лишь рецепты по созданию объектов. Объект - торт со взбитыми сливками, а класс - рецепт по его приготовлению. Любимые рецепты можно записывать на карточках, которые, в свою очередь, можно хранить в коробочке (пока ещё компьютерная революция не добралась до кухни!). Для торта со взбитыми сливками у вас есть только один рецепт (допустим), а вот для шоколадного их уже несколько. Один любимый рецепт найти легко, так как он обычно покрыт засохшим шоколадным тестом, а если рецептов двенадцать? Все они соответствуют шоколадному торту и, даже просматривая ингредиенты (проверяя классы), не так-то легко их отсортировать. Вероятнее всего, поначалу вы будете "помечать" их с помощью дополнительной информации. "Бабушкин шоколадный торт", "Юлин шоколадный торт для детей", "Шоколадный торт без сахара"... Вот простейшее объяснение использования пространств имён - чтобы как-то отделять друг от друга вещи с одинаковыми именами. Однако, как любит говорить ваша бабушка, за каждой лишней заморочкой кроется возможность структурирования библиотек класса способом, помогающим не загрязнять пространства имён и облегчающим многократное использование кода. Да хранит её Господь, вашу бабушку!

Взглянем на "проблему" с прямоугольником ещё раз, имеется один класс, "математически" описывающий размеры прямоугольника (x, y, w, h) от некоей точки в пространстве. И другой, описывающий объект "Прямоугольник" как форму (например, он может быть синим), в противоположность формам эллипса или треугольника. Итак, перед нами два, чётко отличимых друг от друга способа описания объекта, и если они будут одинаково называться, проблем не избежать. Мы могли бы просто переименовать один из них, но, увы, это не всегда возможно, что если используются чужие классы, или же два собственных класса из предыдущих проектов? Что, если у нас перед глазами спецификация, в которой чётко указано: rectangle? Ещё хуже, когда мы не замечаем, что происходит, а заметив, не можем понять, почему порой всё перемешивается. При использовании пространства имён решаются не только эти проблемы. Классы теперь можно организовать в стройную логическую структуру, в которой поиск данных и их использование (повторное в том числе) заметно облегчены. "Почему же не все и не всегда используют пространства имён?", - спросите вы. В большинстве случаев всё-таки используют.


Короче говоря, пространства имён упаковывают группу связанных классов в некий "ящичек". Возвращаясь к аналогии с рецептами, можно сказать, что у нас появились как бы разные ящички для разных групп рецептов и этих ящичков на одни только рецепты шоколадных тортов будет много! Один для бабушкиного, один для Юлиного... Ваши догадки верны: ящички - по сути объекты, а одни ящички могут содержать в себе другие ящички. Так что, решив однажды приготовить вкуснятины "по бабушкиным рецептам", мы берём её ящичек, открываем и находим всякую всячину. Там и ящички "кондитерские изделия", и ящички "паштеты" и ящички "пудинги"... Пространства имён то же самое. Вместо того чтобы задавать классы в _root или _level0, задавайте их внутри каждого отдельного объекта (к примеру, не _level0.ChocolateCake, а _level0.Grandma.Cake.ChocolateCake). Когда задаются эти "пространства имён" на главной линейке, в нём может одновременно присутствовать много чего: приаттаченные клипы, загружаемые клипы, и даже случайно задаваемые свойства (когда вы забываете использовать var). Так что основной линейкой сам по себе ничего не гарантирует. Легко убедиться, что при загрузке .swf-файла одновременно не перезаписывается _level0, однако запомните, если хотите, чтобы ваш класс использовали другие люди, задание пространств имён просто необходимо. Причём пользователи должны знать об этом. "Безопасное" место для хранения, это пространство имён внутри Object, потому что последний не связан с линейкой.

Давайте на мгновение оставим воображаемый мир бабушкиной кухни и вернёмся к реальности определения классов в пространствах имён. Обычно выбирается ваше собственное пространство имён верхнего уровня, где находятся определения всех классов. Если вы работаете в компании, то её название неплохой вариант для обозначения пространства имён (разумеется, если компания не называется "Object.prototype"!). Если название по тем или иным причинам не подходит, тогда за имя можно взять бренд любимых ботинок, название причёски, название какого-нибудь еженедельника. Между прочим, можно использовать собственное имя. Не имеет значения, какое название вы используете, но так будет лишь до тех пор, пока им не пользуется никто другой. В Java для обозначения пространства имён обычно используют доменное имя компании, записанное "наоборот", сей способ, несомненно, уникален (кстати, в Java пространства имён называются "пакеты" (packages)). Что ж, это неплохой вариант, если вы доменные имена меняете нечасто, да не так их и много у вас, то используйте на здоровье. Следуя этой системе, можно, например, воспользоваться системой меню "Sparkysoft" и классами кнопок "Aquamedia", и при этом не попасть на два одинаковых определения в одном месте для классов типа "container". Кроме того, свежесозданные классы всегда будут "знать", где найти классы, написанные полгода назад.



Реализуя пространства имён на верхнем уровне, можно с лёгким сердцем делиться классами с остальным миром; однако "проблема Прямоугольника" (помните ещё?) пока не разрешена. Итак, теперь можно создавать категории для других типов реализуемой функциональности внутри нашего собственного пространства имён. "Сладкое" и "жидкое" - "Торт" и "Суп". Можете попробовать рассмотреть чужие пространства имён, чтобы понять, какими причинами руководствуются другие люди, но это уже будет наука на грани искусства. Вот некоторые примеры пространств имён (и "пакетов") для начала:

<get examples>

< и снова неподражаемая робость автора лишает нас возможности познакомиться с этими, безусловно полезными, примерами :) >

Итак, общие классы входят в общие пространства имён, подобно XML, или Data, или Drawing.Drawing2D... Эти встроенные классы часто обозначаются как принадлежащие к "Каркасу" ('Framework'). У Flash чрезвычайно скудный каркас, так что многое придётся сделать самостоятельно. Классы будут использоваться многократно, так что лучше уж прямо сейчас потрудитесь сделать их устойчивыми и универсальными. Они должны безотказно работать в различных ситуациях, а не в отдельных частных случаях. Затем, когда потребуется решить определённую задачу, не совсем ту, которая предоставляется общими классами "каркаса", надо создать подкласс и добавить требуемую функциональность в нём. В ActionScript "каркас" - это встроенные объекты типа класса Color, или Movieclip, короче, всё, что начинается с заглавной буквы в словаре ActionScript. Сравните с элементами языка for или return и увидите, каким образом "каркас" наделяет приложения "индивидуальностью". Порой сложно сказать, на C++ или на VisualBasic написана программа под Windows, а вот разница между программой на C++ для KDE (Linux) и программой на C++ для Macintosh выявляется легко. Дело в том, что мы (как правило) видим на дисплее приложения, созданные на основе встроенных классов, причём таких, которые априори используются всеми приложениями данной платформы. Так как во Flash почти нет таких вот встроенных классов, можно сэкономить кучу времени, если в процессе программирования мыслить с точки зрения заполнения "каркаса".



Вот теперь, пребывая в некоем абстрактном мире совершенства, кто-то мог подумать, что каждый класс должен быть достаточно чистым и благоухающим, чтобы принадлежать каркасу. Однако задача большинства классов в том, чтобы сделать первый толчок, достаточно мощный, и тихо отойти в тень. Это не означает, что классы должны лишь банально определяться в _root, а имя их может быть некрасивым, нет, они тоже должны быть защищены от конфликтов имён и от перезаписи каким-нибудь подгруженным клипом. Итак, эти классы также войдут в пространство имён и, в конце концов, также будут заданы в пространстве имён Object, просто они будут как бы отделены от каркаса. Фактически, даже экземпляры, в конце концов, могут быть созданы в пространстве имён Object, освобождая линейку от всего, кроме мувиклипов.

Конечно, в "обычном", а не Flash-программировании, проблем с клипами, подгружаемыми в пространство, где пишется код, не возникает, поскольку там нет линейки, весь код автоматически находится в "безопасном" месте. Во Flash же постоянно приходится иметь дело с двумя "областями видимости": в объекте и в линейке. Вот почему во Flash так часто встречается слово "this", оно означает "в этом объекте", а не на линейке, как принято по умолчанию. Поэтому-то мы можем определять код как принадлежащий пространству имен Object, даже если всё должно быть прикреплено к линейке. Если сомнения в пользе вышеописанного всё ещё остаются, представьте себе загрузку класса из внешнего клипа. Если класс определяется в _root клипа, то используемый для создания экземпляров класса код будет зависеть от имени клипа и пути к нему, и будет разным чуть ли не каждый новый раз. Тем не менее, если загруженный клип дублирует определение класса где-то в пространстве имён Object, можно создавать его экземпляры каждый раз одним и тем же способом, облегчая будущее многократное использование (а также отладку!). Разумеется, вы будете уверены, что, сколько клипов ни загрузить таким образом, конфликтов имён не будет. Так, а какие же новости у нас плохие?

Плохие новости, вероятно, можно выразить в трёх словах, появится "синдром усталого запястья". Если вам не знаком секрет машинописного набора длинных префиксов классов, то скоро обнаружите, что набивать на клавиатуре длиннющие маршруты к классам в ActionScript, дело настолько тяжёлое... Вот я заканчиваю писать, а руки мои уже отваливаются.

На этом до свидания!

<<

   ООП во Flash 5 ( II )    >>


Содержание раздела