2011-08-10 24 views
1

我有一個網站我轉換爲Codeigniter,我想簡化和解耦。我喜歡我已經閱讀過關於Observer模式的內容,例如「創建新調查」(觸發新的幫助票據,觸發電子郵件等)。使用觀察者模式與MVC/Codeigniter網站

但我該如何在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) { ... } 
} 

我可以看到如何強大,這將是。但我不確定如何簡化所有這些監聽器/觀察者的設置和連接。

也許我應該有一個工廠來創建它們?看起來好像是,它們會脫離目前的工作方式,但似乎管理着每個控制器或方法中必須「附加」的所有不同對象將以不同的方式進行耦合。

感謝, 漢斯

回答

0

你提出的結構必須是這樣的:

$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可以通過做同樣的事情來處理它?

我認爲你最好用圖書館或模型知道它應該做什麼並且設計得很好,然後添加這個類結構。我看不到收益超過成本。

+0

是的,我喜歡應用程序核心的想法,可以指導所有這些事件,但實際上我不認爲這會很容易。我想過要去靜態方法路線,我試圖找出Kohana是如何做到的(但還沒有時間去詳細查看) – Hans

+0

Kohana從3.0中拿走了它。嗯。猜猜這意味着他們認爲這樣做效果不好?人們仍然支持它,作爲一個靜態類,但它不再是核心模塊。 – Hans