Observer mode (delegations and events)-I don’t know if the boss is coming

  Observer (Publish/Subscribe) mode definition: also known as publish-subscribe mode, which defines a one-to-many dependency relationship, allowing multiple observer objects to monitor a certain subject object at the same time. When the subject object changes, it will be notified All observer objects enable them to update themselves automatically.

  advantage:

  • Decoupling allows both parties to be coupled to rely on abstraction instead of concrete, so that their changes will not affect the changes on the other side, which conforms to the principle of inversion of dependence.

  Disadvantages:

  • The abstract informer still relies on the abstract observer and cannot be further decoupled. The improvement method is to use delegation.

  Usage scenario : When the change of an object needs to change other objects at the same time, it cannot assume who the other objects are. In other words, you don't want these objects to be tightly coupled.

  Code background : The two employees of the company always monitor whether the boss is back, because they want to take advantage of the boss's absence to do their own things. If someone informs them that the boss is back, they will put aside the things in their hands and continue working. Unfortunately, this time the two employees notified by the boss himself-he is here.
  Notifier: Boss.
  Observer: Two employees act differently according to the content of the notice.


Abstract notifier : All references to observer objects (Attach, Detach, Notify) are stored in a collection. Each topic can have any number of observers. The abstract topic provides an interface to add and delete observer objects. , And there is no need to know who the specific observer is, and any specific observer does not need to know the existence of other observers.

    interface Subject   //通知者接口
    {
    
    
        void Attach(Observer observer);
        void Detach(Observer observer);
        void Notify();
        string SubjectState 	//通知者状态
        {
    
    
            get;
            set;
        }
    }

Abstract observer : Observer can be any object, use abstraction to increase code scalability (or use interface)

    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();
    }

Boss category: specific topics

    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);
        }
        //通知(包含了员工的Update方法,一旦被通知,员工就执行Update方法)
        public void Notify ()
        {
    
    
            foreach (Observer o in observers)//遍历所有要通知的对象,然他们依次执行Update方法
                o.Update();
        }
        //老板状态(重写接口)
        public string SubjectState 
        {
    
    
            get {
    
    return action;}
            set {
    
    action = value;}
        }
    }

Employee category: specific observer

    class StockObserver:Observer    ///看股票的员工
    {
    
    
        public StockObserver(string name, Subject sub) : base(name, sub)//抽象观察者,观察者本来就可以是任何人
        {
    
     }
        public override void Update()   //重写更新方法
        {
    
    
            Console.WriteLine("{0}{1}关闭股票行情,继续工作!", sub.SubjectState , name);

        }
    }

    class NBAobserver : Observer    //看NBA的员工
    {
    
    
        public NBAobserver(string name, Subject sub) : base(name, sub)
        {
    
     }
        public override void Update()   //重写更新方法
        {
    
    
            Console.WriteLine("{0}{1}关闭NBA直播,继续工作!", sub.SubjectState, name);
        }
    }

Client:

        static void Main(string[] args)
        {
    
    
			//老板
            Boss bazong = new Boss();

            //摸鱼的同事
            StockObserver tongshi1 = new StockObserver("江小鱼",bazong);
            NBAobserver tongshi2 = new NBAobserver ("李建刚", bazong);
            //老板默默记下要通知的两位同事
            bazong.Attach(tongshi1);
            bazong.Attach(tongshi2);
            //老板大意了,江小鱼没听见,没被通知到,所以减去这个人
            bazong.Detach(tongshi1);
            //老板状态改变
            bazong.SubjectState = "我霸道总裁回来了!";
            //发出通知,员工执行Update方法
            bazong.Notify();
            Console.Read();
        }
    }

Insert picture description here
In the example, there is no notification about data and state changes, but simply notify each observer, telling them that the observer has an action.
There are two versions of the observer mode in the specific realization of the communication between the target role and the observer role.

  • One situation is that after the target role changes, it only tells the observer role "I have changed". If the observer role wants to know the specific details of the change, it has to get it from the target role's interface. This mode is vividly called: pull mode—that is, the changing information is actively "pulled" from the target role by the observer role.
  • There is another way, that is, my target role "service one-stop", when notifying you that there is a change, the details of the change are passed to the observer role through a parameter. This is the "push mode"-whether you want it or not, I will give it to you first.
    The use of these two modes depends on the needs of the system design. If the target role is more complex, and the observer role must get some specific changes when updating, the "push mode" is more appropriate. If the target role is relatively simple, the "pull mode" is appropriate.


   Delegate (delegate) definition : A delegate is a class that defines the type of a method, so that the method can be passed as a parameter of another method. This method of dynamically assigning a method to a parameter can be avoided in the program Use If-Else (Switch) statements extensively, and at the same time make the program have better scalability.
  The delegate is a type of reference method. Once the method is assigned by the delegate, the delegate will have the same behavior as the method.

//Update是事件,EventHandler是委托类型,tongshi1.CloseGameMarket是被委托的方法
//表示将tongshi1的CloseGameMarket方法通过实例化委托EventHandler登记到laoban的事件Update当中。
//+=表示add_CatShout,增加委托实例对象
laoban.Update += new EventHandler(tongshi1.CloseGameMarket );

  Delegates are the encapsulation of functions, and a name can be given to the characteristics of the method ("EventHandler" in the following example).

  The event is a special form of delegation. When an event occurs (the "Boss to inspect" in the following example), the type of delegation (the event processing object, that is, the "EventHandler" in the following example) notification process (tongshi1.CloseGameMarket in the following example) , Tongshi2.CloseZbObserver).


Colleagues playing games:

    class GameObserver
    {
    
    
        private string name;
        private Subject sub;
        public GameObserver(string name,Subject sub)
        {
    
    
            this.name = name;
            this.sub = sub;
        }
        //关闭游戏
        public void CloseGameMarket()
        {
    
    
            Console.WriteLine("{0}{1}关闭王者荣耀,继续工作!",sub.SubjectState,name);
        }
    }

Colleagues watching the live broadcast

    class ZbObserver
    {
    
    
        private string name;
        private Subject sub;
        public ZbObserver (string name,Subject sub)
        {
    
    
            this.name = name;
            this.sub = sub;
        }
        //关闭直播
        public void CloseZbObserver()
        {
    
    
            Console.WriteLine("{0}{1}关闭直播,继续工作!",sub.SubjectState,name);
        }
    }

Notifier status interface:

    interface Subject
    {
    
    
        void Notify();
        string SubjectState     //通知者状态
        {
    
    
            get;
            set;
        }
    }

boss:

    delegate void EventHandler();
    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; }
        }
    }

Client:

        static void Main(string[] args)
        {
    
    
            Boss laoban = new Boss();

            //玩游戏的同事
            GameObserver tongshi1 = new GameObserver("秦霜",laoban);
            //看直播的同事
            ZbObserver tongshi2 = new ZbObserver("楚楚",laoban);

			//实例化一个委托,委托的实例是tongshi1的CloseGameMarket
            laoban.Update += new EventHandler(tongshi1.CloseGameMarket );
            laoban.Update += new EventHandler(tongshi2.CloseZbObserver );

            //老板回来
            laoban.SubjectState = "老板:我来视察工作了\n";
            //发出通知
            laoban.Notify();//Notify()方法一运行,里面的Update事件就运行,Notify()方法就委托EventHandler去通知方法tongshi1.CloseGameMarket运行。

        }

Guess you like

Origin blog.csdn.net/CharmaineXia/article/details/110753104