この記事では、PHP デザインパターンの Observer パターン (Observer) の詳細な紹介とコード例を主に紹介しますので、必要な方は参考にしてください。
【意図】
オブジェクト間の 1 対多の依存関係を定義します。オブジェクトのステータスが変化すると、それに依存するすべてのオブジェクトが通知され、自動的に更新されます [GOF95]。パブリッシュ-サブスクライブ (パブリッシュ-サブスクライブ) パターン、モデルとも呼ばれます。 -View(Model-View)パターン、Source-Listener(Source-Listener)パターン、またはDependents(依存関係)パターン
【オブザーバーパターン構造図】
【観察者モードの主な役割】
1. 抽象サブジェクト (Subject) ロール: サブジェクト ロールは、オブザーバー オブジェクトへのすべての参照をコレクションに保存し、各サブジェクトは必要な数のオブザーバーを持つことができます。 抽象テーマは、オブザーバー オブジェクトを追加および削除するためのインターフェイスを提供します。
2. 抽象オブザーバー (オブザーバー) の役割: すべての特定のオブザーバーのインターフェイスを定義し、観察の対象が変更されたときに自身を更新します。
3. 具象サブジェクト (ConcreteSubject) ロール: 特定のオブザーバー オブジェクトに関連する状態を保存し、特定のサブジェクトの内部状態が変化すると、登録されているすべてのオブザーバーに通知が送信されます。具体的なテーマの役割は、通常、具体的なサブクラスを使用して実装されます。
4. 具象オブザーバー ロール: 特定のサブジェクト オブジェクトを保存し、関連する状態を保存し、抽象オブザーバー ロールが自身の状態をサブジェクトの状態と一致させるために必要な更新インターフェイスを実装します。
【オブザーバーモードのメリットとデメリット】
オブザーバー パターンの利点:
1. 観察者と被験者の間の結合は小さいです。
2.ブロードキャスト通信をサポートします。
オブザーバー パターンの欠点:
オブザーバーは他のオブザーバーの存在に気づかないため、ターゲットを変更する最終的なコストがわからない可能性があります。これにより、予期しない更新が発生する可能性があります。
【オブザーバーモードの適用シナリオ】
抽象モデルに 2 つの側面がある場合、そのうちの 1 つは他方に依存します。
1 つのオブジェクトを変更するために他のオブジェクトも同時に変更する必要がある場合、変更する必要があるオブジェクトの数がわかりません。
オブジェクトが他のオブジェクトに通知する必要がある場合、他のオブジェクトが誰であるかを想定することはできません。言い換えれば、これらのオブジェクトを密結合にする必要はありません。
【オブザーバーモードとその他のモード】
1. メディエーター パターン (メディエーター): 複雑な更新セマンティクスをカプセル化することで、ChangeManager はターゲットとオブザーバーの間のメディエーターとして機能します。
2. シングルトン モード (シングルトン モード): ChangeManager はシングルトン モードを使用して、一意でグローバルにアクセスできるようにします。
【オブザーバーパターンのPHP例】
コードは次のとおりです:
/**
* オブザーバーモード
* @パッケージデザインパターン
*/
/**
* 抽象的なテーマのキャラクター
*/
インターフェースの件名 {
/**
* 新しいオブザーバーオブジェクトを追加します
* @param オブザーバー $observer
*/
パブリック関数attach(Observer $observer);
/**
* 登録されたオブザーバーオブジェクトを削除します
* @param オブザーバー $observer
*/
パブリック関数 detach(Observer $observer);
/**
* 登録されているすべてのオブザーバー オブジェクトに通知します
*/
パブリック関数notifyObservers();
}
/**
* 特定のテーマの役割
*/
クラス ConcreteSubject は Subject {
を実装します
プライベート $_observers;
パブリック関数 __construct() {
$this->_observers = array();
}
/**
* 新しいオブザーバーオブジェクトを追加します
* @param オブザーバー $observer
*/
パブリック関数attach(Observer $observer) {
array_push($this->_observers, $observer) を返す;
}
/**
* 登録されたオブザーバーオブジェクトを削除します
* @param オブザーバー $observer
*/
パブリック関数 detach(Observer $observer) {
$index = array_search($observer, $this->_observers);
if ($index === FALSE || ! array_key_exists($index, $this->_observers)) {
FALSE を返します;
}
unset($this->_observers[$index]);
TRUE を返します;
}
/**
* 登録されているすべてのオブザーバー オブジェクトに通知します
*/
パブリック関数notifyObservers() {
if (!is_array($this->_observers)) {
FALSE を返します;
}
foreach ($this->_observers as $observer) {
$observer->update();
}
TRUE を返します;
}
}
/**
* 抽象的な観察者の役割
*/
インターフェースオブザーバー{
/**
*アップデート方法
*/
パブリック関数 update();
}
クラス ConcreteObserver は Observer {
を実装します
/**
* 観察者の名前
* @var
*/
プライベート $_name;
パブリック関数 __construct($name) {
$this->_name = $name;
}
/**
*アップデート方法
*/
パブリック関数 update() {
echo 'Observer', $this->_name, ' が通知しました。
';
}
}
实例化类:
$subject = 新しい ConcreteSubject();
/* 追加第一个観察者 */
$observer1 = 新しい ConcreteObserver('Martin');
$subject->attach($observer1);
エコー'
最初の通知:
';
$subject->notifyObservers();
/* 追加二番目の観察者 */
$observer2 = 新しい ConcreteObserver('phppan');
$subject->attach($observer2);
エコー'
2 番目の通知:
';
$subject->notifyObservers();
/* 删除第一个观観察者 */
$subject->detach($observer1);
エコー'
3 番目の通知:
';
$subject->notifyObservers();
具体例:
/**
* 3.1php设计モード-观测者モード
* 3.1.1 概念: これは、簡単に理解できる 1 つのモードです。これは、イベント系の 1 つです。
* 着这一様式允许ある特定の種類の状態を観察する、当被観察される種類の状態が変化する時期、
* 観察者は通知に到達し、関連するアクションを実行できます。観察者モードは、回避構成要素間を提供します
* 紧密耦結合的另一方法
* 3.1.2关键ポイント:
* 1.被观観察者->追加观観察者;->一处观観察者;->满足条件時通知观観察者;->观観察条件
* 2.観察者 -> 受け取り観察方法
* 3.1.3 のポイント:
* 3.1.4 PHP での観察者モードの用途の組み合わせ:Web 公開における観察者の用途の側面が多数
* 典型的:用户注册(验证邮件,用户信息激活),购物网站下单時邮件/短信通知等
* 3.1.5php内部のサポート
* SplSubject インターフェイス、被監視対象オブジェクトを表す、
* 其结构:
* インターフェイス SplSubject
* {
* public functionattach(SplObserver $observer);
* public function detach(SplObserver $observer);
* パブリック関数notify();
* }
* SplObserver インターフェイス、着当観察者の代表オブジェクト、
* 其结构:
* インターフェイスSplObserver
* {
* public function update(SplSubject $subject);
* }
*/
/**
* ユーザーログイン - オブザーバーモードの解釈
*/
クラス ユーザーが SplSubject を実装する {
//注册観察者
public $observers = array();
//アニメーション作类型
CONST OBSERVER_TYPE_REGISTER = 1;//注册
CONST OBSERVER_TYPE_EDIT = 2;//编辑
/**
*オブザーバーを追加
* @param SplObserver $observer オブザーバー
* @param int $type 観測タイプ
*/
public functionattach(SplObserver $observer, $type)
{
$this->observers[$type][] = $observer;
}
/**
* オブザーバーを削除します
* @param SplObserver $observer オブザーバー
* @param int $type 観測タイプ
*/
public function detach(SplObserver $observer, $type)
{
if($idx = array_search($observer, $this->observers[$type], true))
{
unset($this->observers[$type][$idx]);
}
}
/**
* 条件が満たされた場合にオブザーバーに通知します
* @param int $type 観測タイプ
*/
パブリック関数notify($type)
{
if(!empty($this->observers[$type]))
{
foreach($this->observers[$type] as $observer)
{
$observer->update($this);
}
}
}
/**
* ユーザーを追加します
* @param str $username ユーザー名
* @param str $password パスワード
* @param str $email メール
* @return bool
*/
パブリック関数 addUser()
{
//実行SQL
//データ库插入成功
$res = true;
//调用通知观観察者
$this->notify(self::OBSERVER_TYPE_REGISTER);
$res; を返す
}
/**
* ユーザー情報編集
* @param str $username ユーザー名
* @param str $password パスワード
* @param str $email メール
* @return bool
*/
パブリック関数 editUser()
{
//実行SQL
//データ库更新成功
$res = true;
//调用通知观観察者
$this->notify(self::OBSERVER_TYPE_EDIT);
$res; を返す
}
}
/**
* オブザーバーがメールを送信
*/
Send_Mail クラスは SplObserver を実装します
{
/**
* 該当する観測者の変更情報
* @param SplSubject $subject
*/
パブリック関数の更新(SplSubject $subject)
{
$this->sendMail($subject->email, $title, $content);
}
/**
*メールを送信
*@param str $email メールアドレス
*@param str $title メールのタイトル
*@param str $content メールの内容
*/
パブリック関数 sendEmail($email, $title, $content)
{
出て出て
出て出て出て出て出て出て出て出て出て出て出て出て出て
}
}
?>この記事では主にPHPデザインパターンにおけるObserverパターン(Observer)の詳細な紹介とコード例を紹介していますので、必要な方は[Intent]を参照してオブジェクト間の1対多の依存関係を定義してください...。 🎜🎜