Есть некоторые технические различия между композицией и группировкой. В этой статье, термины "композиция" и "группировка" будут обобщены в одно понятие - "композиция".
Для многих разработчиков наследование – самая главная возможность в CFC. Наследование позволяет организовывать взаимодействия, при которых один объект расширяет возможности другого.В реальном мире полно примеров таких взаимодействий. Например, объект "Спортивная Машина" расширяет возможности объекта "Машина", который, в свою очередь, расширяет возможности объекта "Транспорт".
Производный объект принято называть "подтип" (subtype), а его базовый объект – "надтип" (supertype). Объект "Машина" одновременно является надтипом объекта "Спортивная Машина" и подтипом объекта "Транспорт". Одним из полезных использований наследовании является повторное использование одного и того же кода. Код, который предоставляет действия по отношению к надтипу может быть использован как в подтипе, так и в любом под-подтипе (т.к. наследования могут применяться к наследуемым объектам).Взаимодействие объектов при наследовании
Вы можете смоделировать взаимодействия подтипов и надтипов с помощью UML диаграммы классов, как показано ниже. Стрелка указывает направления от подтипа к надтипу.
Ключевой фразой, описывающей это взаимодействие, является фраза "относится к". Например, объект "Спортивная Машина" относится к объекту "Машина", а объект "Машина" относится к объекту "Транспорт". Приведенный ниже код создаст компоненту "Машина" (Car), которая унаследует как свойства, так и методы компоненты "Транспорт" (Vehicle): Для компоненты "Транспорт" (Vehicle) код может выглядеть так: Обратите внимание, что в компоненте Car.cfc осуществляются запросы к самой себе (контейнер this указывает на переменные в текущем объекте), хотя на самом деле запросы относятся к компоненте Vehicle.cfc. В этом и заключается принцип наследования – подтип (Car) может использовать методы надтипа (Vehicle).Также обратите внимание, что Car и Vehicle обе определяют метод stop(), который у каждой компоненты выполняет разные действия. Когда подтипы или надтипы содержат методы с одинаковыми именами, то код в подтипе имеет первоочередное положение. Другими словами, методы подтипа перекрывают одноименные методы надтипа.
Давайте протестируем код для Car и Vehicle. Создадим файл TestCar.cfm, в котором укажем вызов объекта. Вызов объекта можно осуществлять одним из двух способов (как вам больше нравится): или Теперь запросим метод stepOnGas() в компоненте Car: Далее запустим наш файл TestCar.cfm в браузере и увидим, что нам возвращает объект Car: Эй! Лучше притормозить. И сделаем мы это, добавив в конце строку: Снова запустим страницу: Даже если методы, которые осуществляют ускорение и замедление - increaseSpeed() и decreaseSpeed() – принадлежат Vehicle.cfc, то Car.cfc наследует их, поскольку является подтипом Vehicle.Обратите внимание, что когда мы запрашиваем myCar,stop(), то будет выполнен метод stop() из Car.cfc, а не из Vehicle.cfc. Это наглядный пример перекрывания одноименных методов.
Укажите следующий код в конце TestCar.cfm и снова запустите его: Вот то, что мы увидим после выполнения метода stop():Взаимодействие объектов при композиции
Наследование очень мощная штука, пока нам нужно взаимодействие "относится к" между двумя объектами. Обычно, один объект содержит другой объект для осуществления каких-то своих свойств. При таком взаимодействии, ключевой фразой будет слово "содержит". Например, объект "Человек" (Person) содержит объект "Адрес" (Address). Такие взаимодействия между объектами называются "композиция".
В случае с объектом Person без использования композиции вы может смоделировать его так: Конечно, нам понадобиться написать методы для получения и установления индивидуальных переменных. Это не сложно.Ниже приведен пример кода, позволяющий получать и устанавливать свойство address1:
Точно таким же образом, нам придется создать методы для всех остальных свойств. Теперь представим, что у нас есть еще одна компонента "Место Проживания" (Venue): Хм … Объекту Venue также нужна информация об адресе человека. Это означает, что в обоих компонентах Person и Venue вы укажите один и тот же код для получения и установки адреса. Лучшим решением этой задачи будет создание отдельной компоненты "Адрес" (Address) и отнести ее к объекту Person с помощью композиции. Следующая UML диаграмма классов показывает это взаимодействие: Компонента Address.cfc проста: Теперь, когда объекту Person (или любой другой компоненте) понадобиться установить адрес, то мы можем использовать один объект Address, выполнив в нем метод new(). Затем, полученный объект мы можем установить как свойство объекта Person.Перед тем как продемонстрировать страницу TestPerson, давайте начнем с формы для пользователя, чтобы показать как объекты подключаются к приложению.
Код для файла TestPerson.cfm следующий (обратите внимание, что на картинке выше форма аккуратно оформлена с помощью html тега <table>. В коде ниже этого тега нет, чтобы показать Вам только программный код): Атрибут action указывает на страницу ProcessUserForm.cfm, но перед тем как обратиться к коду этой страницы, давайте переработаем Person.cfc: Обратите внимание, что в методе new() аргумент address принимает тип Address, т.е. в качестве значения этого аргумента ожидается объект Address.Определив компоненты Person.cfc и Address.cfc обратимся к странице ProcessUserForm.cfm. Тут кода не много:
Когда вы заполните и отправите форму, то в результате увидите вывод тега <cfdump>: Как видим, компоненты – интригующая возможность ColdFusion. Они предоставляют мощные возможности для повторного использования кода и инкапсуляции. Используя наследование, вы можете указать код в подтипах и использовать его в подтипах. Принцип наследование отлично работает тогда, когда компоненты взаимодействуют между собой как родитель и ребенок.Существует множество ситуации, когда метафора “родитель-дитя” не подходит. В таких случаях идеальным решением будет использование композиции. Разработчики могут многократно использовать одни и те же объекты, сохраняя свой код компактным и хорошо организованным.
Понимание того, как объекты взаимодействуют друг с другом – самое важное в использовании ColdFusion компонент.
© 2002-2005 г. Вадим Пушкарев