观察者模式

目录

一、观察者模式

二、观察者模式角色

1、抽象主题

2、抽象观察者

3、具体主题

4、具体观察者

四、应用

五、代码实例一

六、代码实例二

七、C#中的委托事件机制


一、观察者模式

观察者模式实现了观察者与目标之间的抽象耦合、动态联动。

例如 知乎、微博、外卖等软件,当有新的热门信息、我们经常浏览的信息更新时,手机上经常会受到信息。我们就是观察者,而这些软件就像是目标。当信息更新时,我们会接受到提示信息,当我们取消一些订阅时,一些信息就不会被推送。

本质是触发联动

别名:

1、发布-订阅模式

2、模型-视图模式

3、源-监听器模式

4、从属者模式

模式如其名。

二、观察者模式角色

1、抽象主题

一个目标可以被多个观察者观察,下面的例子中的员工--老板就是n--1;

目标提供对观察者的增加和删除,如下文中的subject。

当目标的状态发生变化时,目标负责通知所有现存的观察者。

2、抽象观察者

为所有的具体观察者提供一个接口。

有一个更新接口,方便更新新的信息。

3、具体主题

将有关状态存入具体观察者对象。在状态发生变化时,负责给所有所属的观察者发送消息。

因此又被叫做具体被观察者角色。

4、具体观察者

要实现具体更新接口。

还可以有一个指向具体主题对象的引用。

如下文中的Stock和Dba。

四、应用

使系统耦合度降低,便于复用。

要使低耦合度的对象能协调工作。

五、代码实例一

同事间帮忙。

第一个类:抽象主题类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 观察者模式__通知信息
{
    interface  Subject
    {
        void Attach(Observer obs);
        void Detach(Observer obs);
        void Notify();
        String SubjectState 
        {
            get;
            set;
        }

    }
}

第二个类:抽象观察者

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 观察者模式__通知信息
{
    abstract class Observer
    {
        protected string name;
        protected Subject sub;

        protected Observer(string name, Subject sub)
        {
            this.name = name;
            this.sub = sub;
        }
        public abstract void update();
    }
}

 第三个类:具体主题类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 观察者模式__通知信息
{
    class Subject_Secretary : Subject
    {
        private IList<Observer> observers = new List<Observer>();
        private string action;
        public string SubjectState
        {
            get { return action; }
            set { action = value; }
        }
        public void Attach(Observer obs)
        {
            observers.Add(obs);
        }

        public void Detach(Observer obs)
        {
            observers.Remove(obs);
        }

        public void Notify()
        {
            foreach(Observer o in observers)
            {
                o.update();
            }
        }
    }
}

第四、五个类:具体观察者类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 观察者模式__通知信息
{
    class Stock_Observer : Observer
    {
        public Stock_Observer(string name, Subject sub) : base(name, sub) { }
        public override void update()
        {
            Console.WriteLine("{0}{1}关闭股票,继续工作", sub.SubjectState, name);
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 观察者模式__通知信息
{
    class Nba_Observer : Observer
    {
        public Nba_Observer(string name, Subject sub) : base(name, sub) { }
        public override void update()
        {
            Console.WriteLine("{0}{1}停止看球,继续工作", sub.SubjectState, name);
        }
    }
}

测试类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 观察者模式__通知信息
{
    class Program
    {
        static void Main(string[] args)
        {
            Subject_Secretary L1 = new Subject_Secretary();
            Stock_Observer S1 = new Stock_Observer("S1",L1);
            Nba_Observer N1 = new Nba_Observer("N1", L1);
            L1.Attach(S1);
            L1.Attach(N1);
            L1.SubjectState = "老板来了";
            L1.Notify();
        }
    }
}

六、代码实例二

一个股票的例子

第一个类:一个抽象的股票类

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 观察者模式__股票行情
{
    abstract class Stock
    {
        protected string symbol;
        protected double price;
        private ArrayList investors = new ArrayList();

        protected Stock(string symbol, double price)
        {
            this.symbol = symbol;
            this.price = price;
        }
        public void Attach(IInvestor inv)
        {
            investors.Add(inv);
        }
        public void Detach(IInvestor inv)
        {
            investors.Remove(inv);
        }
        public void Notify()
        {
            foreach(IInvestor i in investors)
            {
                i.update(this);
            }
                
        }
        public double Price
        {
            get { return price; }
            set { price = value; Notify(); }
        }
        public string Symbol
        {
            get { return symbol; }
            set { symbol = value; }
        }
    }
}

第二个类:观察者接口

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 观察者模式__股票行情
{
    interface  IInvestor
    {
        void update(Stock stock);
    }
}

第三个类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 观察者模式__股票行情
{
    class Investor_One : IInvestor
    {
        private string name;
        private string ObserveState;
        private Stock stock;

        public Investor_One(string name)
        {
            this.name = name;
        }


        public void update(Stock stock)
        {
            Console.WriteLine("Notified investor {0} of {1}'s change to {2:C}", name, stock.Symbol, stock.Price);
        }
        public Stock Stock
        {
            get { return stock; }
            set { stock = value; }
        }
    }
}

第四个类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 观察者模式__股票行情
{
    class IBM:Stock
    {
        public IBM(string symbol,double price):base(symbol, price) { }
       
    }
}

第五个测试类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 观察者模式__股票行情
{
    class Program
    {
        static void Main(string[] args)
        {
            Investor_One i1 = new Investor_One("i1");
            Investor_One i2 = new Investor_One("i2");
            IBM ibm = new IBM("IBM", 200.1);
            ibm.Attach(i1);
            ibm.Attach(i2);
            ibm.Price = 201;
            ibm.Price = 101.9;
        }
    }
}

七、C#中的委托事件机制

delegate void UpdateDelegate()是定义一个委托,下面两个观察者的更新函数都符合这个委托。

public event UpdateDelegate UpdateHandler定义事件,一旦事件被触发,就会调用一组 UpdateDelegate()规范的方法。

+号就可以实现添加事件功能。

UpdateHandler不为空时,代表有订阅者,就会调用UpdateHandler()

主题类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 观察者模式__委托
{
    delegate void UpdateDelegate();//委托对象
    class Subject
    {
        public event UpdateDelegate UpdateHandler;
        public void Attach(UpdateDelegate ud)
        {
            UpdateHandler += ud;
        }
        public void Detach(UpdateDelegate ud)
        {
            UpdateHandler -= ud;
        }
        public void Notify()
        {
            if (UpdateHandler != null)
                UpdateHandler();//委托事件
        }

    }
}

真实主题类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 观察者模式__委托
{
    class ConcreteSubject:Subject
    {
        private string subjectState;
        public string SubjectState
        {
            get { return subjectState; }
            set { subjectState = value; }
        }
    }
}

观察者类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 观察者模式__委托
{
    class ConcreteObserver
    {
        private string name;
        private string observerState;
        private ConcreteSubject subject;

        public ConcreteObserver(string name, ConcreteSubject subject)
        {
            this.name = name;
            this.subject = subject;
        }
        public void update()
        {
            observerState = subject.SubjectState;
            Console.WriteLine("observer {0} s new state is{1}", name, observerState);
        }
        public ConcreteSubject Subject
        {
            get { return subject; }
            set { subject = value; }
        }
    }
}

另一个观察者类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 观察者模式__委托
{
    class ConcreteObserver_Another
    {
        public void show()
        {
            Console.WriteLine("AnotherObserver got an Notification!");
        }
    }
}

测试类 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 观察者模式__委托
{
    class Program
    {
        static void Main(string[] args)
        {
            ConcreteSubject cs = new ConcreteSubject();
            ConcreteObserver c1 = new ConcreteObserver("c1",cs);
            ConcreteObserver c2 = new ConcreteObserver("c2", cs);
            ConcreteObserver_Another c3 = new ConcreteObserver_Another();
            cs.Attach(new UpdateDelegate(c1.update));
            cs.Attach(new UpdateDelegate(c2.update));
            cs.Attach(new UpdateDelegate(c3.show));
            cs.SubjectState = "啊哈哈哈哈";
            cs.Notify();
            Console.WriteLine("------------");
            cs.Detach(new UpdateDelegate(c3.show));
            cs.Notify();




        }
    }
}

猫大叫一声,所有的老鼠都开始逃跑,主人被惊醒。

代码实例:

抽象主题:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ObserverOne
{
    abstract class Subject
    {
        public string State { get ; set ; }
        abstract public void Attach(UpdateDelegate a); 
        abstract public void Detach(UpdateDelegate a);
        abstract public void Notify();
    }
}

具体主题:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ObserverOne
{
    delegate void UpdateDelegate();
    class CatSubject:Subject
    {
        private string state;
        public event UpdateDelegate UpdateHandler;
        public string State { get => state; set => state = value; }

        public override void Attach(UpdateDelegate a)
        {
            UpdateHandler += a;//---
        }

        public override void Detach(UpdateDelegate a)
        {
            UpdateHandler -= a;
        }

        public override void Notify()
        {
            if (UpdateHandler != null) UpdateHandler();
        }
    }
}

抽象观察者:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ObserverOne
{
    abstract class ObserverPlus
    {
        protected string name;
        protected Subject subject;

        protected ObserverPlus(string name, Subject subject)
        {
            this.name = name;
            this.subject = subject;
        }
        public abstract void update();
    }
}

具体:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ObserverOne
{
    class MouseObserverPlus : ObserverPlus
    {
        private CatSubject c = new CatSubject();
        public MouseObserverPlus(string name,CatSubject subject) : base(name, subject) { c = subject; }

        public override void update()
        {
            Console.WriteLine("{0}....{1}来了快跑!", c.State,name);
           // Console.WriteLine(subject.State+"---");
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ObserverOne
{
    class PersonObserver : ObserverPlus
    {
        private CatSubject c=new CatSubject();
        public PersonObserver(string name,CatSubject subject) : base(name, subject) { c = subject; }
        public override void update()
        {
            Console.WriteLine("{0}....来了{1}惊醒了!", c.State, name);
        }
    }
}

测试:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ObserverOne
{
    static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            //CatSubject cat = new CatSubject();
            //MouseObserver m1 = new MouseObserver("Tom", cat);
            //cat.Attach(new UpdateDelegate(m1.update));
            //cat.State = "猫马上来";
            //cat.Notify();
            //cat.State = "猫来了";
            //cat.Notify();//-----//-----//-----//----
            CatSubject cat = new CatSubject();
            MouseObserverPlus m1 = new MouseObserverPlus("猫", cat);
            cat.Attach(new UpdateDelegate(m1.update));
            cat.State = "马上";
            cat.Notify();
            cat.State = "现在";
            cat.Notify();
            PersonObserver p1 = new PersonObserver("小明", cat);
            cat.Attach(new UpdateDelegate(p1.update));
            cat.Notify();

        }
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值