• PHP设计模式——观察者模式


    PHP版本

    <?php
    /**
     * 观察者模式
     * 观察者模式能够便利的创建查看目标对象状态的对象,并且提供与核心对象非耦合的指定性功能。
     * 
     * 为软件添加由某个动作或状态变化激活的,但是松散耦合的新功能时,应当创建基于观察者模式的对象。
     * 
     * SPL:Standard PHP Library PHP标准库
     */
    
    class User implements SplSubject{
        public $lognum;
        public $hobby;
        protected $_observers = NULL;
        
        public function __construct($hobby) {
            $this->lognum = rand(1,10);
            $this->hobby = $hobby;
            $this->_observers = new SplObjectStorage();
        }
        
        public function login() {
            $this->notify();
        }
        
        public function attach(SplObserver $observer) {
            $this->_observers->attach($observer);
        }
        public function detach(SplObserver $observer) {
            $this->_observers->detach($observer);
        }
        public function notify() {
            $this->_observers->rewind();
            while ($this->_observers->valid()) {
                $observer = $this->_observers->current();
                $observer->update($this);
                $this->_observers->next();
            }
        }
    }
    /**
     * 功能模块
     */
    class Login implements SplObserver{
        public function update(SplSubject $subject) {
            echo "登录次数:".$subject->lognum.'<br>';
        }
    }
    //实施观察
    $user = new User('学习');
    $user->attach(new Login());
    $user->login();
    
    //添加模块
    class Hobby implements SplObserver{
        public function update(SplSubject $subject) {
            echo "爱好:".$subject->hobby;
        }
    }
    $hobby = new Hobby;
    $user->attach($hobby);
    $user->login();
    echo '<br>';
    //删除观察模块
    $user->detach($hobby);
    $user->login();

    JS版本

    <!DOCTYPE html>
    <!--
    To change this license header, choose License Headers in Project Properties.
    To change this template file, choose Tools | Templates
    and open the template in the editor.
    -->
    <html>
        <head>
            <title>观察者模式</title>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <style>
                div{border:solid gray 1px;margin-top:10px;height: 100px;width: 200px;}
            </style>
        </head>
        <body>
            <h1>观察者模式</h1>
            <select>
                <option value="1">风格1</option>
                <option value="2">风格2</option>
            </select>
            <button onclick="detachC()">不观察C</button>
            <button onclick="attachC()">观察C</button>
            <!--模块一-->
            <div id="A">A</div>
            <!--模块二-->
            <div id="B">B</div>
            <!--模块三-->
            <div id="C">C</div>
            <script>
                //观察者
                var sel = document.getElementsByTagName('select')[0];
                sel.observers = {}
                sel.attach = function(key, obj) {
                    this.observers[key] = obj;
                }
                sel.detach = function(key) {
                    delete this.observers[key];
                }
    
                sel.onchange = sel.notify = function() {
                    for (var key in this.observers) {
                        this.observers[key].update(this);
                    }
                }
                //被观察对象及操作
                var a = document.getElementById('A');
                var b = document.getElementById('B');
                a.update = function(observe) {
                    if (1 == observe.value) {
                        this.innerHTML = 'A模块:风格1';
                    }
                    if (2 == observe.value) {
                        this.innerHTML = 'A模块:风格2';
                    }
                }
                b.update = function(observe) {
                    if (1 == observe.value) {
                        this.innerHTML = 'B模块:风格1';
                    }
                    if (2 == observe.value) {
                        this.innerHTML = 'B模块:风格2';
                    }
                }
                //开启观察
                sel.attach('a', a);
                sel.attach('b', b);
                
                //添加观察C模块
                var c = document.getElementById('C');
                c.update = function(observe) {
                    if (1 == observe.value) {
                        this.innerHTML = 'C模块:风格1';
                    }
                    if (2 == observe.value) {
                        this.innerHTML = 'C模块:风格2';
                    }
                }
                sel.attach('c', c);
                
                //取消观察
                function attachC(){
                    sel.attach('c',c);
                }
                function detachC(){
                    sel.detach('c');
                }
            </script>
        </body>
    </html>
  • 相关阅读:
    C#:BackgroundWorker的简单使用
    C#:DataTable 操作
    树和二叉树
    Git下的标签
    python的高级应用
    字符串匹配的BF算法和KMP算法学习
    GitHub:多人协作下的分支处理
    Git:分支的创建、合并、管理和删除
    GitHub:创建和修改远程仓库
    Git:文件操作和历史回退
  • 原文地址:https://www.cnblogs.com/tlxma/p/5210696.html
Copyright © 2020-2023  润新知