设计模式---Observer Pattern

  • Observer Pattern
  • 观察者模式: 对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。
  • 观察者模式又叫做发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。
  • 模式分析
  • 观察者模式包含四个角色:
    (subject)目标又称为主题,它是指被观察的对象; knows its observers. 它知道它的观察者;并提供用于注册与删除的接口
    (concreteSubject)具体目标是目标类的子类,通常它包含有经常发生改变的数据,当它的状态发生改变时,向它的各个观察者发出通知;
    (observer)观察者将对观察目标的改变做出反应;
    (concreteObserver)具体观察者中维护一个指向具体目标对象的引用,它存储具体观察者的有关状态,这些状态需要和具体目标的状态保持一致。
  • 代码示例
/*
 *Observer Pattern
 */
using System;
using System.Collections.Generic;


namespace Pattern01
{
    class Program
    {
        static void Main(string[] args)
        {
           
            ConCreteSubject s = new ConCreteSubject();

            Observer observer1 = new ConcreteObserver(s, "x");
            Observer observer2 = new ConcreteObserver(s, "y");
            Observer observer3 = new ConcreteObserver(s, "z");

            s.Attach(observer1);
            s.Attach(observer2);
            s.Attach(observer3);

            // Change subject and notify observers

            s.SubjectState = "ABC";
            s.Notify();


            Console.WriteLine("------------------");
            s.Detach(observer1);


            s.SubjectState = "edf";
            s.Notify();


            Console.ReadKey();

        }
    }

    /// <summary>
    /// knows its observers. Any number of Observer objects may observe a subject
    /// provides an interface for attaching and detaching Observer objects.
    /// </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 (Observer o in _observers)
            {
                o.Update();
            }
        }
    }
    /// <summary>
    /// stores state of interest to ConcreteObserver
    /// sends a notification to its observers when its state changes
    /// </summary>
    class ConCreteSubject : Subject
    {
        private string _subjectState;
        public string SubjectState
        {
            get
            {
                return _subjectState;
            }
            set { _subjectState = value; }
        }
    }
    /// <summary>
    /// defines an updating interface for objects that should be notified of changes in a subject.
    /// </summary>
    abstract class Observer
    {
        public abstract void Update();
    }
    /// <summary>
    /// maintains a reference to a ConcreteSubject object
    /// stores state that should stay consistent with the subject's
    /// implements the Observer updating interface to keep its state consistent with the subject's
    /// </summary>
    class ConcreteObserver : Observer
    {
        private string _name;
        private string _observerState;
        private ConCreteSubject _subject;/目标
        public ConcreteObserver(ConCreteSubject subject,string name)
        {
            this._subject = subject;
            this._name =name;
        }
        public override void Update()
        {
            _observerState = _subject.SubjectState;///目标通知内容
            Console.WriteLine($"Observer {_name} new state is {_observerState}");
        }
        public ConCreteSubject subject
        {
            get { return _subject; }
            set { _subject = value; }
        }
    }

}

在这里插入图片描述

  • 代码示例2
    下面代码模拟,将IBM股票价格的变化,及时通知到订阅了IBM股票的投资者。
/*
 *Observer Pattern
 */
using System;
using System.Collections.Generic;

namespace Pattern01
{
    class Program
    {
        static void Main(string[] args)
        {
            IBM ibm = new IBM("IBM", 120.00);
            ibm.Attach(new Investor("Sorros"));
            ibm.Attach(new Investor("Berkshire"));
            IInvestor investor = new Investor("job-Stone");
            ibm.Attach(investor);

            // 股票价格有变化,则通知订阅股票的投资者
            ibm.Price = 120.10;
            ibm.Price = 121.00;
            ibm.Price = 120.50;
            ibm.Price = 120.75;

            Console.ReadKey();

        }
    }

    /// <summary>
    ///  SUBject-- knows its observers. Any number of Observer objects may observe a subject
    /// provides an interface for attaching and detaching Observer objects.
    /// </summary>
    abstract class Stock
    {
        private string _symbol;
        private double _price;

        private List<IInvestor> _invests = new List<IInvestor>();//observers
        public Stock(string symbol, double price)
        {
            _symbol = symbol;
            _price = price;
        }
        public void Attach(IInvestor investor)
        {
            _invests.Add(investor);
        }
        public void Detach(IInvestor investor)
        {
            _invests.Remove(investor);
        }
        public void Notify()
        {
            /依次通知订阅者
            foreach (IInvestor o in _invests)
            {
                o.Update(this);
            }
            Console.WriteLine();
        }

        public double Price
        {
            get { return _price; }
            set
            {
                if (_price != value)
                {
                    _price = value;//价格有变动则通知订阅者
                    Notify();
                }
            }
        }
        public string Symbol
        {
            get { return _symbol; }
        }
    }
    /// <summary>
    /// concreteSubject--- stores state of interest to ConcreteObserver
    ///   sends a notification to its observers when its state changes
    /// </summary>
    class IBM : Stock
    {
        public IBM(string symbol, double price) : base(symbol, price) { }
    }
    /// <summary>
    /// Observer-- defines an updating interface for objects that should be notified of changes in a subject.
    /// </summary>
    interface IInvestor
    {
        void Update(Stock stock);
    }
    /// <summary>
    ///  concreteObserver---maintains a reference to a ConcreteSubject object
    ///  stores state that should stay consistent with the subject's
    /// implements the Observer updating interface to keep its state consistent with the subject's
    /// </summary>
    class Investor : IInvestor
    {
        private string name;
        private Stock _stock;//maintains a reference to a ConcreteSubject object   
        public Investor(string name)
        {
            this.name = name;
        }
        public void Update(Stock stock)
        {
            _stock = stock;
            Console.WriteLine($"notify {name} of {_stock.Symbol} change to {_stock.Price}");
        }
            
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值