Как-то медитируя на свой новый велосипед подумал, – А почему бы не заложить в него возможность «плагинизации» контроллеров?
Чтобы вот был, например, у нас некий базовый класс Generic.php:
А мы такие взяли и повешали бы на него пару плагинов, которые дополнят/изменят какие-либо его методы не мешая друг-другу (по принципу «кто первый встал – того и тапки»).
Вот они красавцы:
PluginFoo.php:
и PluginBar.php:
А потом мы создали бы объект родительского класса (не обращаясь к последнему потомку), вызвали метод Hello() и тот сказал бы нам:
Ниже лаконичный вариант того как описанного поведения добился ort в своём LiveStreet, а затем уже и я в своём собственном велосипеде.
Вы наверное уже заметили в коде выше, что классы плагинов PluginFoo и PluginBar наследуются от неописанных классов Generic_PluginFoo и Generic_PluginBar соответственно? Так вот их и не будет вообще. Этот финт ушами нам нужен для классалиасинга и выстраивания цепочки наследования.
Да чего резину тянуть.
Вот пример использования:
// Получим
// Dudes?
// Hello!
// O.o
Волшебный инструмент:
И вот у меня вопрос, – Как это называется на «языке паттернов»? Как бы вы это назвали?
P.S. Разумеется — этот пост является следствием первоапрельского розыгрыша с ППА :)

– Та-да!
Чтобы вот был, например, у нас некий базовый класс Generic.php:
<?php class Generic { public function Hello() { echo 'Hello!'; } } ?>
А мы такие взяли и повешали бы на него пару плагинов, которые дополнят/изменят какие-либо его методы не мешая друг-другу (по принципу «кто первый встал – того и тапки»).
Вот они красавцы:
PluginFoo.php:
<?php class PluginFoo extends Generic_PluginFoo { public function Hello() { echo 'Dudes?<br />'; parent::Hello(); } } ?>
и PluginBar.php:
<?php class PluginBar extends Generic_PluginBar { public function Hello() { parent::Hello(); echo '<br />O.o'; } } ?>
А потом мы создали бы объект родительского класса (не обращаясь к последнему потомку), вызвали метод Hello() и тот сказал бы нам:
Dudes?
Hello!
O.o
Ниже лаконичный вариант того как описанного поведения добился ort в своём LiveStreet, а затем уже и я в своём собственном велосипеде.
Вы наверное уже заметили в коде выше, что классы плагинов PluginFoo и PluginBar наследуются от неописанных классов Generic_PluginFoo и Generic_PluginBar соответственно? Так вот их и не будет вообще. Этот финт ушами нам нужен для классалиасинга и выстраивания цепочки наследования.
Да чего резину тянуть.
Вот пример использования:
// создаём объект (Ваш Капитан Очевидность) $KungFu = new KungFu(); // Регистрируем плагин PluginFoo для базового класса Generic $KungFu->RegisterPlugin('Generic', 'PluginFoo'); // Регистрируем плагин PluginBar для базового класса Generic $KungFu->RegisterPlugin('Generic', 'PluginBar'); // Загружаем <i>отплагинизированный</i> объект класса Generic $Generic = $KungFu->Load('Generic'); $Generic->Hello();
// Получим
// Dudes?
// Hello!
// O.o
Волшебный инструмент:
class KungFu { // Эээ... Конструктор public function __construct() { spl_autoload_register(array($this, '_AutoLoader')); } // Эээ... Метод автозагрузки public function _AutoLoader($sClass) { if (false == class_exists($sClass)) { include($sClass.'.php'); } } // после регистрации плагинов примет вид // Array ( [Generic] => Array ( [0] => PluginFoo [1] => PluginBar ) ) private $_aPlugins = array(); // Метод регистрации плагинов, заполняющий массив, что описан выше public function RegisterPlugin($sClass, $sPlugin) { if (false == isset($this->_aPlugins[$sClass])) { $this->_aPlugins[$sClass] = array(); } array_push($this->_aPlugins[$sClass], $sPlugin); } // Метод вернет объект указанного класса. Если для этого класса указаны плагины, то разумеется объект будет по пути плагинизирован. public function Load($sClass) { if (false == isset($this->_aPlugins[$sClass])) { return new $sClass(); } else { $aPlugins = array_reverse($this->_aPlugins[$sClass]); $sPrev = null; foreach ($aPlugins as $sPlugin) { if (null != $sPrev) { $aBranch[$sPrev] = $sPlugin; } $aBranch[$sPlugin] = null; $sPrev = $sPlugin; } $aBranch[$sPrev] = $sClass; foreach (array_reverse($aBranch) as $sPlugin => $sParent) { class_alias($sParent, $sClass.'_'.$sPlugin); } if (class_exists($sPlugin)) { return new $sPlugin; } } } }
И вот у меня вопрос, – Как это называется на «языке паттернов»? Как бы вы это назвали?
P.S. Разумеется — этот пост является следствием первоапрельского розыгрыша с ППА :)

– Та-да!
