5. 观察者模式(Observer Pattern)

 

一、介绍

 
        话说啊,我们公司小王上班期间总爱玩游戏,当然是在老板不在的时候了;但是呀,这家伙运气不好,总被老板抓,这天呢老板又出去了,他想到个好主意,我看到老板回来后立即在扣扣中提前震动他一下(由于我的座位更靠近门,老板来了我会第一个发现),让他知道老板要来,以免被抓。你会说这小王很聪明啊,是啊他刚好用到了我们设计模式中的一种  —— 观察者模式。观察者模式,又叫发布-订阅(Publish/Subscribe)模式,大家仔细回想小王这件事,抽象开来,“老板回来”这是一件事,我呢是受委托人,小王是委托人,这里又要用到面向对象的两个技术 委托和事件,对着俩个家伙还不了解,出门左转见这两篇文章附录一 面向对象基础 以及 C# 中的委托和事件 ,接下来我们说一下 观察者模式。
 
二、UML图
 
三、总结
1. 定义:观察者模式定义了一种一对多的关系,让多个观察者对象同时监听某一个主体对象,当主题对象的状态发生变化时,    会通知所有观察者,使得他们能做出相应的更新。
2. 实现:
    Subject 是主题或者统治者,他把所有观察者的引用保存到一个聚集里,当自身状态发生改变时,方便通知所有的观察者。
    Observer 为观察者,一般为抽象类或者接口,通常包含一个类似 Update() 方法。
3. 使用场景
        ⑴ 当一个对象的改变,需要同时改变其他对象时,而且他不知道有多少对象有待改变时,可以考虑使用观察者模式
        ⑵ 一个抽象模型有两方面,其中一方面依赖于另一方面,这时可以考虑使用观察者模式,将二者封装到独立的对象中
4. 委托与事件:
        委托可以看做是声明了一个特殊的类,事件可以看做是声明了一个委托的变量
        委托所搭载的所有方法必须具有原型和返回形式,也就是拥有相同的参数和返回值类型
5. 不足:(这只是观察者模式的一种实现,具体场景可能需要变形,但万变不离其宗)
 
四、附录
    Subject 类:
 public class Subject
    {
        /// <summary>
        /// 声明一个特殊的“类”(委托类)
        /// </summary>
        public delegate void EventHandler();

        /// <summary>
        /// 声明一个事件委托变量
        /// </summary>
        private event EventHandler Update;

        /// <summary>
        /// 绑定观察者
        /// </summary>
        /// <param name="handler">操作</param>
        public void Attach(EventHandler handler)
        {
            Update += handler;
        }

        /// <summary>
        /// 移除绑定
        /// </summary>
        /// <param name="handler">操作</param>
        public void DeAttach(EventHandler handler)
        {
            Update -= handler;
        }

        /// <summary>
        /// 通知观察者
        /// </summary>
        public void Notify()
        {
            if (null != Update)
                Update();
        }
    }

 

  Observer 类:
public abstract class Observer
    {
        /// <summary>
        /// 名字
        /// </summary>
        protected string Name { get; set; }

        /// <summary>
        /// 构造初始化
        /// </summary>
        /// <param name="name"></param>
        protected Observer(string name)
        {
            this.Name = name;
        }

        /// <summary>
        /// 观察者采取行动
        /// </summary>
        public abstract void Update();
    }

 

Observer 具体类1:
 public class GamePlayerObserver:Observer
    {
        public GamePlayerObserver(string name)
            : base(name)
        {
        }

        /// <inheritdoc />
        public override void Update()
        {
            Console.WriteLine("我是"+this.Name+"老板来了,不玩游戏了,我要工作了");
        }
    }

 

Observer 具体类2:
    public class NbaWatcherObserver:Observer
    {
        public NbaWatcherObserver(string name)
            : base(name)
        {
        }

        public override void Update()
        {
            Console.WriteLine("我是"+this.Name+"老板来了,不看NBA了,我要工作了");
        }
    }

 

客户端:
internal class Program
    {
        private static void Main(string[] args)
        {
            //委托人
            var xiaozhang = new Subject();
            xiaozhang.Attach(new GamePlayerObserver("小王").Update);
            xiaozhang.Attach(new NbaWatcherObserver("小赵").Update);

            //时间在一分一秒的故去
            for (int i = 0; i < 100; i++)
            {
                Thread.Sleep(100);
                if (i < 75)
                {
                    Console.WriteLine("现在时刻" + i);
                }
                //老板来了
                else if (i == 75)
                {
                    xiaozhang.Notify();
                }
            }
        }
    }

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
posted @ 2019-05-01 07:56  NCat  阅读(142)  评论(0)    收藏  举报