използвайки модел на наблюдател с уеб сайт 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

Но се чудя на това. Ще имате фабрична класа, която бавно става всезнаеща. Започва да узурпира функционалността на Loader. Защо да зареждам библиотека, когато моят Observer_factory може да се справи с това, като прави абсолютно същото?

Мисля, че е по-добре с библиотека или модел, който знае какво трябва да прави и е добре проектиран, след което да добавите тази класова структура. Не виждам печалбите да надвишават разходите.

person cwallenpoole    schedule 10.08.2011
comment
Да, харесва ми идеята за ядро ​​на приложението, което може да насочва всички тези събития, но в действителност не мисля, че ще бъде толкова лесно. Мислех да тръгна по пътя на статичния метод и се опитах да разбера как Kohana го прави (но все още нямах време да разгледам подробно) - person Hans; 11.08.2011
comment
Изглежда, че Kohana го е извадил от 3.0. Хм. Предполагам, че това означава, че са смятали, че не работи добре? Хората все още го поддържат като статичен клас, но вече не е основен модул. - person Hans; 11.08.2011