javascript观察者模式

70 阅读3分钟

观察者模式又称“发布-订阅(Publish/Subscribe)模式”,订阅者也称为观察者,而补观察的对象称为发布者或主题。当发生了一个重要的事件时,发布者将会通知(调用)所有订阅者并且可能经常以事件对象的形式传递消息。

例如:(只做简单的说明观察者模式)
几个程序员小朋友要从某网站订阅相关书籍,js编程全解这本书
但现在没货,等有货再通知他们,去购买,其中王五同学订购后,不想买了,就退订了

代码实现:

  //发布者类
        function Publish() {
            //存储订阅者
            this.subList = [];
            //是否有货的状态
            var state =null;
            this.getState=function () {
                return state;
            };
            this.setState=function (s) {
                state = s;
            }

        };
        //订阅
        Publish.prototype.addSubscribe = function (sub) {
            var isExist = this.subList.some(function (item) {
                if(item){
                    return item === sub;
                };

            });
            if(!isExist){
                this.subList.push(sub);
            };
            return this;
        };
        //退订
        Publish.prototype.unsubscribe = function (sub) {

            this.subList = this.subList.filter(function (item) {
                if(item!==sub){
                    return true
                }else{
                    console.log(item.name+"已为您退订!");
                    return false;
                }
            });

            return this;
        };
        //通知
        Publish.prototype.notice = function (data) {
            this.subList.forEach(function (fun) {
                fun.getNotice(fun.name,data);
            })
        };
        //订阅者类
        function Subscribe() {
            //订阅
            this.setSub=function (book) {
                book.addSubscribe(this);
            };
            //获取通知信息
            this.getNotice = function (name,data) {
                console.log(name+data);
            }
        }
        
        //程序员类
        function programmer(name) {
            programmer.superclass.constructor(this);
            this.name = name;

        }
        //继承订阅类
        extend(programmer,Subscribe);
        //书籍
        function Book(name) {
            Book.superclass.constructor(this);
            this.name = name || "js编程全解";
        }
        //继承发布者类
        extend(Book,Publish);


        /*
        *
        * 测试
        * */
        //实例化书籍
        var book =new Book("编程全解");
        //实例化三位程序员童鞋
        var p1 = new programmer("张三");
        var p2 = new programmer("李四");
        var p3 = new programmer("王五");
        //三位同学订阅了这几本书
        p1.setSub(book);
        p2.setSub(book);
        p3.setSub(book);
        //买书的暂时没货
        book.setState(false);
        var d = new Date();
        console.log("当前时间:"+d.getMinutes()+"分:"+ d.getSeconds()+"秒");
        //通知订阅的童鞋没货了
        if(book.getState()){
            book.notice(",您的订购的书到了,请前往购买!");
        }else{
            book.notice(",您订购的书还没到,请耐心等待...");
        };

        //过了漫长的两秒,王五童鞋不要了,要退订
        setTimeout(function () {

            var n = new Date();
            console.log("当前时间:"+n.getMinutes()+"分:"+ n.getSeconds()+"秒");
            book.unsubscribe(p3);
        },2000);


        //又过来漫长的三秒,书终于有了
        setTimeout(function () {
            book.setState(true);
            var n = new Date();
            console.log("当前时间:"+n.getMinutes()+"分:"+ n.getSeconds()+"秒");
            if(book.getState()){
                book.notice(",您的订购的书到了,请前往购买!");
            }else{
                book.notice(",您订购的书还没到,请耐心等待...");
            }
        },5000);

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122

运行结果: