• js观察者模式


    观察者模式(Publish/Subscribe),定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能自动更新自己。

    C#观察者模式:

    namespace 观察者模式
    {
        class Program
        {
            static void Main(string[] args)
            {
                //老板胡汉三
                Boss huhansan = new Boss();
    
                //看股票的同事
                StockObserver tongshi1 = new StockObserver("魏关姹", huhansan);
                //看NBA的同事
                NBAObserver tongshi2 = new NBAObserver("易管查", huhansan);
    
                huhansan.Attach(tongshi1);
                huhansan.Attach(tongshi2);
    
                huhansan.Detach(tongshi1);
    
                //老板回来
                huhansan.SubjectState = "我胡汉三回来了!";
                //发出通知
                huhansan.Notify();
    
                Console.Read();
            }
        }
    
        //通知者接口
        interface Subject
        {
            void Attach(Observer observer);
            void Detach(Observer observer);
            void Notify();
            string SubjectState
            {
                get;
                set;
            }
        }
    
        class Secretary : Subject
        {
            //同事列表
            private IList<Observer> observers = new List<Observer>();
            private string action;
    
            //增加
            public void Attach(Observer observer)
            {
                observers.Add(observer);
            }
    
            //减少
            public void Detach(Observer observer)
            {
                observers.Remove(observer);
            }
    
            //通知
            public void Notify()
            {
                foreach (Observer o in observers)
                    o.Update();
            }
    
            //前台状态
            public string SubjectState
            {
                get { return action; }
                set { action = value; }
            }
        }
    
        class Boss : Subject
        {
            //同事列表
            private IList<Observer> observers = new List<Observer>();
            private string action;
    
            //增加
            public void Attach(Observer observer)
            {
                observers.Add(observer);
            }
    
            //减少
            public void Detach(Observer observer)
            {
                observers.Remove(observer);
            }
    
            //通知
            public void Notify()
            {
                foreach (Observer o in observers)
                    o.Update();
            }
    
            //老板状态
            public string SubjectState
            {
                get { return action; }
                set { action = value; }
            }
        }
    
        //抽象观察者
        abstract class Observer
        {
            protected string name;
            protected Subject sub;
    
            public Observer(string name, Subject sub)
            {
                this.name = name;
                this.sub = sub;
            }
    
            public abstract void Update();
        }
    
        //看股票的同事
        class StockObserver : Observer
        {
            public StockObserver(string name, Subject sub)
                : base(name, sub)
            {
            }
    
            public override void Update()
            {
                Console.WriteLine("{0} {1} 关闭股票行情,继续工作!", sub.SubjectState, name);
            }
        }
    
        //看NBA的同事
        class NBAObserver : Observer
        {
            public NBAObserver(string name, Subject sub)
                : base(name, sub)
            {
            }
    
            public override void Update()
            {
                Console.WriteLine("{0} {1} 关闭NBA直播,继续工作!", sub.SubjectState, name);
            }
        }
    }

    在.NET中,我们可以使用委托与事件来简化观察者模式的实现,上面的例子用事件和委托的实现如下代码所示:

    namespace 观察者模式_委托
    {
        class Program
        {
            static void Main(string[] args)
            {
                //老板胡汉三
                Boss huhansan = new Boss();
    
                //看股票的同事
                StockObserver tongshi1 = new StockObserver("魏关姹", huhansan);
                //看NBA的同事
                NBAObserver tongshi2 = new NBAObserver("易管查", huhansan);
    
                huhansan.Update += new EventHandler(tongshi1.CloseStockMarket);
                huhansan.Update += new EventHandler(tongshi2.CloseNBADirectSeeding);
    
                //老板回来
                huhansan.SubjectState = "我胡汉三回来了!";
                //发出通知
                huhansan.Notify();
    
                Console.Read();
    
    
            }
        }
    
        //通知者接口
        interface Subject
        {
            void Notify();
            string SubjectState
            {
                get;
                set;
            }
        }
    
        //事件处理程序的委托
        delegate void EventHandler();
    
        class Secretary : Subject
        {
            //声明一事件Update,类型为委托EventHandler
            public event EventHandler Update;
    
            private string action;
    
            public void Notify()
            {
                Update();
            }
            public string SubjectState
            {
                get { return action; }
                set { action = value; }
            }
        }
    
        class Boss : Subject
        {
            //声明一事件Update,类型为委托EventHandler
            public event EventHandler Update;
    
            private string action;
    
            public void Notify()
            {
                Update();
            }
            public string SubjectState
            {
                get { return action; }
                set { action = value; }
            }
        }
    
        //看股票的同事
        class StockObserver
        {
            private string name;
            private Subject sub;
            public StockObserver(string name, Subject sub)
            {
                this.name = name;
                this.sub = sub;
            }
    
            //关闭股票行情
            public void CloseStockMarket()
            {
                Console.WriteLine("{0} {1} 关闭股票行情,继续工作!", sub.SubjectState, name);
            }
        }
    
        //看NBA的同事
        class NBAObserver
        {
            private string name;
            private Subject sub;
            public NBAObserver(string name, Subject sub)
            {
                this.name = name;
                this.sub = sub;
            }
    
            //关闭NBA直播
            public void CloseNBADirectSeeding()
            {
                Console.WriteLine("{0} {1} 关闭NBA直播,继续工作!", sub.SubjectState, name);
            }
        }
    }

    js观察者模式:

    var event = {
                clientList:[],
                listen:function(key,fn){
                    if(!this.clientList[key]){
                        this.clientList[key] = [];
                    }
                    this.clientList[key].push(fn); //订阅的消息加进缓存列表
                },
                trigger:function(){
                    var key = Array.prototype.shift.call(arguments),
                        fns = this.clientList[key];
                       
                    if(!fns || fns.length === 0){  //如果没有绑定对应的消息
                        return false;
                    }
                   
                    for(var i =0, fn; fn=fns[i++];){
                        fn.apply(this,arguments);
                    }
                },
                remove:function(key,fn){
                    var fns = this.clientList[key];
                   
                    if(!fns){   //如果key对应的消息没有被人订阅,则直接返回
                        return false;
                    }
                    if(!fn){    //如果没有传入具体的回调函数,表示需要取消key对应的所有订阅
                        fns && (fns.length = 0);
                    }else{
                        for(var i=fns.length - 1; i>=0;i--){
                            var _fn = fns[i];
                            if(_fn === fn){
                                fns.splice(i,1);  //删除订阅者的回调函数
                            }
                        }
                    }
                }
            };
    
    
    //调用:
    var salesOffices = {};
    $.extend(salesOffices,event);
    
    salesOffices.listen('squareMeter',function(price){
        alert('价格=' + price);
    });
    salesOffices.trigger('squareMeter',20000);
    
    //全局调用:
    event.listen('squareMeter',function(price){
        alert('价格=' + price);
    });
    event.trigger('squareMeter',20000);
  • 相关阅读:
    [NOI Online #3 提高组]
    Luogu P3491 [POI2009]SLW-Words
    AtCoder Grand Contest 043
    Luogu P5607 [Ynoi2013]无力回天NOI2017
    AtCoder Grand Contest 041
    Luogu P5070 [Ynoi2015]即便看不到未来
    BZOJ 4367: [IOI2014]holiday假期
    BZOJ 3571: [Hnoi2014]画框
    BZOJ 4456: [Zjoi2016]旅行者
    BZOJ 1111: [POI2007]四进制的天平Wag
  • 原文地址:https://www.cnblogs.com/gongshunkai/p/6640460.html
Copyright © 2020-2023  润新知