Поведение и события / Yii framework


Оригинал: Behaviors & events

Эти функции обеспечивают безграничные возможности и невероятную гибкость для программирования, но в имеющейся официальной документации приведено лишь несколько примеров их использования. Это создает дополнительные трудности для понимания их внутреннего строения и предъявляемых к ним требований.
Отмечу, что События и Соведение делают в основном одни и те же вещи. Вы можете прицепить Поведение и обработчик Событий к компоненту, чтобы изменить Поведение компонента.

События

Эта функция полезна в том случае, если вы хотите прервать нормальное функционирование приложения без расширения базовых классов.
Например, включение gzip сжатия на выходе может быть сделано через расширение CWebApplication. Но поскольку для обработчиков Событий предусмотрены точки входа, можно сделать следующее:
Yii::app()->onBeginRequest = create_function('$event', 'return ob_start("ob_gzhandler");');
Yii::app()->onEndRequest = create_function('$event', 'return ob_end_flush();');

Вы можете создать обработчик Событий (это просто метод в некоторых классах с определенной подписью) и прикрепить его к Событию объекта. Вы можете добавить к объектам сколько угодно обработчиков Событий.
Если обработчик Событий является статическим, то вы можете создать объект необходимого назначения:
$test_comp->onSomethingGoesOn = array(new SomeClass, 'eventHandler1');
$test_comp->onSomethingGoesOn = array(new SomeOtherClass, 'eventHandler2');
$test_comp->onSomethingGoesOn = array(new YetAnotherClass, 'eventHandler3');

До тех пор пока вы взаимодействуете с объектом, вы можете добавить обработчик Событий к нему.
Если понадобится, вы можете вызвать Событие вроде этого:
$test_comp->onSomethingGoesOn(new CEvent($this));
$test_comp->onSomethingGoesOn(new CEvent());

Получается, это позволяет создать список вызовов функций, которые в дальнейшем могут быть выполнены именно в том в порядке, в котором они были добавлены. Это будет полезно в случае, если вы работаете с большим количеством ссылочных объектов и проектируете условный код, так как вы все равно можете вызвать Событие, даже если оно ничего не делает.

Поведение

Поведение – это просто способ добавления методов к объекту.
Возьмем такой сценарий:
У вас есть 2 класса: MySuperClass1 и MySuperClass2. В обоих классах имеется множество методов. У вас может возникнуть необходимость подключить их к новому классу, скажем к MyBoringClass. Но, к сожалению, средствами языка PHP это сделать невозможно:
class MyBoringClass extends MySuperClass1, MySuperClass2 {
}

Здесь и на сцену выходит Поведение. Вот что получается:
class MyBoringClass extends MySuperClass1 {
}
 
$classInstance = new MyBoringClass();
$classInstance->attachbehavior('uniqueName', new MySuperClass2);

В результате $classInstance обладает всеми методами MySuperClass1 и MySuperClass2. Изначально MySuperClass2 используется как Поведение, которое расширяет CBehavior. Единственное ограничение состоит в том, что прикрепленное Поведение не может переопределять методы класса компонента, которому оно присвоено. Если метод уже существует или если он добавился от оригинального класса или от ранее подключенного Поведения, то он не будет перезаписан.
В объектно-ориентированном языке, таком как, например, Ruby, вполне возможно начать с совершенно пустого объекта и, постепенно двигаясь вперед, выстраивать его Поведение. В Yii-фреймворке Поведение реализовано с некоторыми особенностями. Смысл в том, что класс, к которому вы хотите добавить Поведение, должен расширять Cbehavior.
class SomeClass extends CBehavior
{
    public function add($x, $y) { return $x + $y; }
}

Тогда используйте:
$test_comp = new TestComponent(); 
$test_comp->attachbehavior('blah', new SomeClass);
$test_comp->add(2, 5);

Таким образом, вы расширяете функциональность одного объекта с помощью функций другого объекта.

После изучения данного материала можно перечитать соответствующие разделы руководства, поскольку там содержится много полезного (например, вы можете найти достаточно информации по интерфейсам, в частности, как реализовать IBehavior до расширения CBehavior).