PHP物件導向進階設計模式:觀察者模式使用執行個體

來源:互聯網
上載者:User
什麼是觀察者模式?

觀察者設計模式能夠更便利地建立查看目標對象狀態的對象,並且提供與核心對象非耦合的指定功能性。

該模式非常簡單:一個對象通過添加一個方法(該方法允許另一個對象,即觀察者 註冊自己)使本身變得可觀察。當可觀察的對象更改時,它會將訊息發送到登入的觀察者。這些觀察者使用該資訊執行的操作與可觀察的對象無關。結果是對象可以相互對話,而不必瞭解原因。


UML

該圖詳細說明了一個使用觀察者設計模式的類設計:

下面是對的說明:

1.MyObject是可觀察對象,它包含一個名為observers的觀察者保護數組。公用方法addObserver()接受一個觀察者的執行個體並將其儲存在觀察者數組內。

2.doSomething()公用方法會被調用,這個方法對MyObject應用狀態變化。隨後,notify()公用方法會被調用,這個方法可遍曆迴圈觀察者數組。

3.MyObjectObserver具有一個名為change()的公用方法,該方法接受MyObject的一個執行個體。這個特定的觀察者接下來會對MyObject的內容執行某些操作。當在觀察者數組中找到特定的觀察者時,MyObject的notify()方法會直接調用change()方法。

使用執行個體:

<?php  interface Observable{      function attach( Observer $observer );      function detach( Observer $observer );      function notify();  }      class login implements Observable{      const LOGIN_USER_UNKNOW = 1;      const LOGIN_WRONG_PASS = 2;      const LOGIN_ACCESS = 3;      private $status = array();      private $observers = array();        public function setStatus( $status, $user, $ip ) {          $this->status = array( $status, $user, $ip );      }      public function getStatus() {          return $this->status;      }      public function handleLogin( $user, $pass, $ip ) {          switch ( mt_rand( 1, 3 ) ) {          case 1:              $this->setStatus( self::LOGIN_USER_UNKNOW, $user, $ip );              $ret = false;              break;          case 2:              $this->setStatus( self::LOGIN_WRONG_PASS, $user, $ip );              $ret = false;              break;          case 3:              $this->setStatus( self::LOGIN_ACCESS, $user, $ip );              $ret = true;              break;          }          $this->notify();          return $ret;      }          public function attach( Observer $observer ) {          $this->observers[] = $observer;      }        public function detach( Observer $observer ) {          $newObservers = array();          foreach ( $this->observers as $obs ) {              if ( $obs !== $observer )                  $newObservers[] = $obs;          }          $this->observers = $newObservers;      }        public function notify() {          foreach ( $this->observers as $obs ) {              $obs->update( $this );          }      }  }    interface Observer{      function update( Observable $observable );  }    class SecurityMonitor implements Observer{      function update( Observable $observable ) {          $status = $observable->getStatus();          if($status[0] == Login::LOGIN_WRONG_PASS){              echo __CLASS__.":".$status[1]."於".$status[2]."登入失敗";          }      }  }    $login = new Login();  $login->attach(new SecurityMonitor());  $login->handleLogin('XXX','XXX','127.0.0.1');  ?>  出錯時的運行結果:  SecurityMonitor:XXX於127.0.0.1登入失敗[Finished in 0.1s]

代碼中可以看到login對象主動添加SecurityMonitor對象觀察。這樣要調用Login::getStatus(),SecurityMonitor類就必須瞭解更多資訊。雖然調用發生於一個ObServable對象上,但無法保證對象也是一個Login對象。為解決這個問題,有一個辦法:斷續保持ObServable介面的通用性,由ObServer類負責保證它們的主體是正確的類型。它們甚至能將自己添加到主體上。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.