[设计模式]观察者模式

观察者模式又叫做发布-订阅(Publish/Subscribe)模式。

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

using System;
using System.Collections.Generic;

namespace 设计模式_观察者模式
{
    /// <summary>
    /// 抽象通知者类
    /// Subject类,可翻译为主题或抽象通知者,一般用一个抽象类或者一个接口实现。
    /// 它把所有对观察者对象的引用保存在一个聚集里,每个主题都可以有任何数量的观察者。
    /// 抽象主题提供一个接口,可以增加和删除观察者对象。
    /// </summary>
    abstract class Subject
    {
        private List<Observer> observers = new List<Observer>();
        //添加观察者
       public void Attach(Observer observer )
    {
            observers.Add(observer);
    }
        //删除观察者
      public void Detach(Observer observer)
        {
            observers.Remove(observer);
        }
        //通知
        public void Notify()
        {
            foreach (var observer in observers)
            {
                observer.Update();
            }
        }
    }
    /// <summary>
    /// ConcreteSubject类,叫做具体主题或具体通知者,将有关状态存入具体观察者对象;
    /// 在具体主题的内部状态改变时,给所有登记过的观察者发出通知。
    /// 具体主题角色通常用一个具体子类实现。
    /// </summary>
    class ConcreteSubject :Subject
    {
        private string subjectState;
        //具体被观察者状态
        public string SubjectState { get => subjectState; set => subjectState = value; }
    }
    /// <summary>
    /// 抽象观察者类
    /// Observer类,抽象观察者,为所有的具体观察者定义一个接口,在得到主题的通知时更新自己。
    /// 这个接口叫做更新接口。抽象观察者一般用一个抽象类或者一个接口实现。
    /// 更新接口通常包含一个Update()方法,这个方法叫做更新方法。
    /// </summary>
    abstract class  Observer
    {
        protected string name;
        protected ConcreteSubject subject;
        public Observer (string name, ConcreteSubject subject)
        {
            this.name = name;
            this.subject = subject;
        }
      public abstract void Update();
    }
    /// <summary>
    /// 具体观察者
    /// ConcreteObserver类,具体观察者,实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态相协调。
    /// 具体观察者角色可以保存一个指向具体主题对象的引用。
    /// 具体观察者角色通常用一个具体子类实现。
    /// </summary>
    class ConcreteObserver1 : Observer
    {
        public ConcreteObserver1 (string name, ConcreteSubject subject):base(name,subject)
        {

        }
        public override void Update()
        {
            Console.WriteLine("{0}, {1}不打游戏了",subject.SubjectState,name);
        }
    }
    class ConcreteObserver2 : Observer
    {
        public ConcreteObserver2(string name, ConcreteSubject subject) : base(name, subject)
        {

        }
        public override void Update()
        {
            Console.WriteLine("{0},{1}不摸鱼了",subject.SubjectState,name);
        }
    }
    class Program
    {
        /// <summary>
        /// 客户端代码
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            ConcreteSubject subject = new ConcreteSubject();
            subject.Attach(new ConcreteObserver1("小林",subject));
            subject.Attach(new ConcreteObserver2("小周",subject));
            subject.SubjectState = "老板来了";
            subject.Notify();
        }
    }
}

结果显示

 事件委托的使用  实现观察者模式

/// <summary>
    /// 事件委托的使用  实现观察者模式
    /// 
    /// “抽象通知者”由于不希望依赖“抽象观察者”,
    /// 所以“增加”和“减少”的方法也就没有必要了(抽象观察者已经不存在了)。
    /// </summary>
    interface  Subject1
    {
        //通知
         void Notify();
       string SubjectState
        {
            get;set;
        }
    }
    //声明一个委托,名称叫“EventHandler(事件处理程序)”,无参数,无返回值。
    delegate void EventHandler();
    class Boss : Subject1
    {
        public event EventHandler Update;
        private string action;
        public string SubjectState { get => action; set => action=value; }

        public void Notify()
        {
            Update();
        }
    }
    /// <summary>
    /// “看股票观察者”类和“看NBA观察者”类,去掉了父类“抽象观察类”,
    /// 所以补上一些代码,并将“更新”方法名改为各自适合的方法名。
    /// </summary>
    class StockObserver
    {
        protected string name;
        protected Subject1 subject;
        public StockObserver(string name, Subject1 subject)
        {
            this.name = name;
            this.subject = subject;
        }
        //更改不同的方法名  现实中就是这样的,方法名本就不一定相同
        public void CloseStock()
        {
            Console.WriteLine("{0} ,{1},关闭股票",subject.SubjectState,name);
        }
    }
    class NBAObserver
    {
        protected string name;
        protected Subject1 subject;
        public NBAObserver(string name, Subject1 subject)
        {
            this.name = name;
            this.subject = subject;
        }
        //更改不同的方法名
        public void CloseNBA()
        {
            Console.WriteLine("{0} ,{1},关闭NBA",subject.SubjectState, name);
        }
    }
    class Program
    {
        /// <summary>
        /// 客户端代码
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            Boss boss = new Boss();
            StockObserver stockObserver = new StockObserver("小林", boss);
            NBAObserver nBAObserver = new NBAObserver("小周", boss);
            //将两种不同的方法委托给“老板”的“更新”
            boss.Update += new EventHandler(stockObserver.CloseStock);
            boss.Update += new EventHandler(nBAObserver.CloseNBA);
            boss.SubjectState = "老板回来了";
            boss.Notify();
        }
    }

结果显示

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DAGUNIANGZHOU

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值