использование шаблона Observer с веб-сайтом MVC/Codeigniter

У меня есть веб-сайт, который я конвертирую в Codeigniter, и я хочу упростить и разделить его. Мне нравится то, что я читал о шаблоне Observer для таких вещей, как «создан новый опрос» (который запускает новый запрос в службу поддержки, который запускает электронное письмо и т. д.).

Но как реализовать подобное в Code Igniter? Я вижу компонент Symfony, но на данный момент меня не столько интересует понимание системы, сколько выяснение того, как использовать его в контроллерах и моделях. Я уже расширил и CI_Model, и CI_Controller по другим причинам. Было бы лучше всего поместить туда код шаблона Observer?

Я представляю такую ​​ситуацию: кто-то заходит на веб-сайт и порождает запрос, который перенаправляется на контроллер/действие: http://localhost/test/save_changes

// warning, pseudo-code!

class Test extends MY_Model
{
    public function __construct ()
    {
        // do I put this here?!? - or maybe in MY_Model?
        // Should it be a singleton?
        $this->load->library('dispatcher'); 
        // where do I attach what I want... here?
        $this->load->library('emailer');
        $this->dispatcher->attach($this->emailer); 
        // what if I have 50 possible things that might happen
        // based on any given event, from adding a user to 
        // deleting a survey or document? There has got to be a
        // way to attach a bunch of observers that trickle
        // down to each object, right?
    }

    public function save_changes ()
    {
         $this->load->model('user');
         $this->user->init($this->session->userdata('user.id'))->save();            
    }
}



class User extends MY_Model
{
    public function __construct ()
    {
        parent::__construct ();
        // do I put this here?!?
        $this->load->library('dispatcher'); // just something to call it
    }

    public function init($id)
    {
        if($this->_loadUser ($id))
        {
            $this->dispatcher->notify($this, 'user.loaded');
        }
    }

    public function save($id)
    {
        if(parent::save())
        {
            $this->dispatcher->notify($this, 'user.saved');
        }
    }



}

class Emailer
{
    public function update ($caller,$msg) 
    {
        switch ($msg)
        {
            case 'user.saved':
        // send user an email
        // re-cache some stuff
        // other things that we might want to do, including more of these:
        $this->dispatch->notify('user-saved-email-sent'); 
            break;
        }
    }
}

class Dispatcher
{
    public function notify ($caller, $msg) { ...foreach attached do $obj->update($caller,$msg) ...}
    public function attach ($obj) { ... }
    public function detach ($obj) { ... }
}

Я вижу, насколько мощным это было бы. Но я не уверен, как упростить настройку и подключение всех этих слушателей/наблюдателей.

Может быть, у меня должна быть фабрика, чтобы создавать их всех? Просто кажется, что да, они будут отделены от того, как это работает в настоящее время, но кажется, что управление всеми различными объектами, которые мне нужно «присоединить» к каждому контроллеру или методу, будет связано по-другому.

Спасибо, Ханс


person Hans    schedule 10.08.2011    source источник


Ответы (1)


Предлагаемая вами структура должна быть примерно такой:

$this->load->library('observer_factory', 'of'); // factory for creating observers
// Observer_factory would have knowledge/access to different classes which relate
// to the pattern.
$ync = $this->of->getNotifier( $some_variable ) );
$ync->attach( $this->of->getObserver( $some_other_variable ) );
$ync->attach( $this->of->getObserver( $some_final_variable ) );

$ync->someMethod(); // someMethod calls notify

Но мне интересно об этом. У вас будет фабричный класс, который постепенно станет всезнающим. Он начинает узурпировать функциональность загрузчика. Зачем загружать библиотеку, если мой Observer_factory может с ней справиться, делая то же самое?

Я думаю, вам лучше иметь библиотеку или модель, которая знает, что она должна делать, и хорошо спроектирована, а затем добавляет эту структуру классов. Я не вижу выгод, превышающих затраты.

person cwallenpoole    schedule 10.08.2011
comment
Да, мне нравится идея ядра приложения, которое могло бы управлять всеми этими событиями, но на самом деле я не думаю, что это будет так просто. Я думал о том, чтобы пойти по маршруту статического метода, и я попытался выяснить, как это делает Kohana (но еще не было времени, чтобы посмотреть подробно) - person Hans; 11.08.2011
comment
Похоже, Кохана убрала это из 3.0. Хм. Угадайте, это означает, что они думали, что это не сработало? Люди все еще поддерживают его как статический класс, но это уже не основной модуль. - person Hans; 11.08.2011