• 观察者模式的一个例子


    观察者模式(有时又被称为发布-订阅模式、模型-视图模式、源-收听者

    模式或从属者模式)是软件设计模式的一种。在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实作事件处理系统。

    观察者模式(Observer)完美的将观察者和被观察的对象分离开。举个例子,用户界面可以作为一个观察者,业务数据是被观察者,用户界面观察业务数据的变化,发现数据变化后,就显示在界面上。面向对象设计的一个原则是:系统中的每个类将重点放在某一个功能上,而不是其他方面。一个对象只做一件事情,并且将他做好。观察者模式在模块之间划定了清晰的界限,提高了应用程序的可维护性和重用性。
    下面,我是在他人基础上做的一个封装以及简单继承。
    <!DOCTYPE html>
    <html>
    <head>
        <title></title>
        <meta charset="utf-8"/>
    </head>
    <body>
    <button id="sendWeekly">发送周报</button>
    <button id="sendDaily">发送日报</button>
    <script>
        var inherits = function (ctor, superCtor) {
            // 显式的指定父类
            ctor.super_ = superCtor;
            superCtor = typeof superCtor === "function" ? superCtor.prototype : superCtor;
            // ECMAScript 5  原型式继承并解除引用
            if (Object.create) {
                ctor.prototype = Object.create(superCtor, {
                    constructor:{
                        value:ctor,
                        enumerable:false,
                        writable:true,
                        configurable:true
                    }
                });
            } else {
                // 无Object.create方法的平稳退化
                function F() {
                };
                F.prototype = superCtor;
                ctor.prototype = new F();
                ctor.prototype.constructor = ctor;
            }
        };
    
        var Observer = (function (W) {
            var pubsub = function () {
                this.topics = {};
                this.subUid = -1;
            };
    
            // 发布方法
            pubsub.prototype.fire = function (type) {
                var args = [].slice.call(arguments, 1),
                        that = this;
                if (!this.topics[type]) {
                    return false;
                }
                (function () {
                    var subscribers = that.topics[type],
                            len = subscribers ? subscribers.length : 0;
    
                    while (len--) {
                        subscribers[len].func.apply(that, args);
                    }
                })();
    
                return true;
            };
            //订阅方法
            pubsub.prototype.on = function (type, fn) {
                if (!this.topics[type]) {
                    this.topics[type] = [];
                }
    
                var token = (++this.subUid).toString();
                this.topics[type].push({
                    token:token,
                    func:fn
                });
                return token;
            };
            //退订方法
            pubsub.prototype.off = function (type, token) {
                var evT;
                if (type === void 0) {
                    return this.topics = {}
                }
    
                if (arguments.length == 1) {
                    if (!this.topics[type]) {
                        return;
                    }
                    return delete this.topics[type];
                }
                evT = this.topics[type];
                for (var i = 0, j = evT.length; i < j; i++) {
                    if (evT[i].token === token) {
                        evT.splice(i, 1);
                        return token;
                    }
                }
                return false;
            };
            return pubsub;
        }(window));
    
    
        function Paper(name, pages, price) {
            this.name = name;
            this.pages = pages;
            this.price = price;
        }
    
        inherits(Paper, new Observer);
    
        Paper.prototype.send = function (topic) {
            this.fire(topic, {
                name:this.name,
                pages:this.pages,
                price:this.price
            });
        };
    
        function Person(name) {
            var that = this;
            this.name = name;
            this.recive = function (paper) {
                console.log(that.name + ' recive Pager detail:\n' + 'name:' + paper.name + '\npages:' + paper.pages + '\nprice:' + paper.price)
            }
        }
    
        var person = new Person('Lucy'),
                person1 = new Person('Tom');
        var Weekly = new Paper('weekly', 298, '$6'),
                Daily = new Paper('daily', 7, '$0.8');
    
        var pr = Weekly.on('weekly', person.recive),
                pr1 = Weekly.on('weekly', person1.recive);
        var pr2 = Daily.on('daily', person.recive);
    
        var $ = function (id) {
            return document.getElementById(id);
        }
    
        $('sendWeekly').onclick = function () {
            Weekly.send('weekly');
        }
    
        $('sendDaily').onclick = function () {
            Daily.send('daily');
        }
    </script>
    </body>
    </html>
  • 相关阅读:
    消息中间件 kafka rabbitmq 选型差异
    kafka生产部署
    logback不同业务的日志打印到不同文件
    Java并发编程核心概念一览
    大数据分析常用去重算法分析『Bitmap 篇』
    java 堆调优
    大规模使用 Apache Kafka 的20个最佳实践
    es定期删除数据
    HTTP协议中源端口和目标端口的问题
    How to duplicate the records in a MongoDB collection
  • 原文地址:https://www.cnblogs.com/pigtail/p/2995592.html
Copyright © 2020-2023  润新知