若转载教程,请注明出自SW-X框架官方文档1

    1. <?php
    2. /**
    3. * 设计模式之观察者模式
    4. * 使用场景 订阅信息,消息推送
    5. * 小黄牛
    6. */
    7. header("Content-type: text/html; charset=utf-8");
    8. /**
    9. *
    10. * 抽象出通知者类
    11. */
    12. abstract class Subject{
    13. private $observers = array(); // 用户保存观察成员
    14. # 添加观察成员
    15. public function Attach($observer){
    16. array_push($this->observers, $observer);
    17. }
    18. # 删除观察成员
    19. public function Detach($observer){
    20. foreach($this->observers as $k=>$v) {
    21. if($v==$observer) {
    22. unset($this->observers[$k]);
    23. }
    24. }
    25. }
    26. # 向观察成员群发消息
    27. function Notify(){
    28. foreach($this->observers as $v) {
    29. $v->Update();
    30. }
    31. }
    32. }
    33. //具体通知者(Boss和Secretary)
    34. class ConcreteSubject extends Subject{
    35. public $subject_state; // 推送的内容
    36. }
    37. //抽象观察者
    38. abstract class Observer{
    39. public abstract function Update();
    40. }
    41. //具体观察者
    42. class ConcreteObserver extends Observer{
    43. private $name; // 观察者名称
    44. private $observerState; // 保存通知者推送过来的内容
    45. public $subject; // 通知者实例,作用是保证大家都在同一频道内
    46. # 初始化成员属性
    47. public function __construct($_sub,$_name){
    48. $this->subject = $_sub;
    49. $this->name = $_name;
    50. }
    51. # 输出推送的内容
    52. public function Update(){
    53. $this->observerState = $this->subject->subject_state;
    54. echo "观察者:" .$this->name. "接受到的内容是:" .$this->observerState. "<br/>";
    55. }
    56. }
    57. # 实例化一个频道
    58. $A = new ConcreteSubject();
    59. # 添加两个观察者 - 并加入同一频道
    60. $zs = new ConcreteObserver($A, '张三');
    61. $ls = new ConcreteObserver($A, '李四');
    62. # 让两个观察者获得接受数据推送的权限
    63. $A->Attach($zs);
    64. $A->Attach($ls);
    65. # 注入推送内容
    66. $A->subject_state = "I Love You 小黄牛!";
    67. # 推送消息
    68. $A->Notify();

    浏览器输出

    1. 观察者:张三接受到的内容是:I Love You 小黄牛!
    2. 观察者:李四接受到的内容是:I Love You 小黄牛!

    观察者模式

    1. 抽象通知者角色(INotifier):定义了通知的接口规则。
    2. 具体通知者角色(Boss):实现抽象通知者的接口,接到状态改变立即向观察者下发通知。
    3. 抽象观察者角色(IObserver):定义接到通知后所做的操作(Update)接口规则。
    4. 具体观察者角色(JingDong):实现具体操作方法。

    应用场景

    1. 订阅信息,消息推送

    优点

    1. 1、一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这些方面封装在独立的对象中使它们可以各自独立地改变和复用。
    2. 2、一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变,可以降低对象之间的耦合度。
    3. 3、一个对象必须通知其他对象,而并不知道这些对象是谁。需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象的行为将影响C对象……,可以使用观察者模式创建一种链式触发机制。