设计模式之十:观察者模式(Observer)

观察者模式:
在对象之间定义了一种一对多的依赖关系。当一个对象改变它的状态时,全部依赖它的对象会自己主动接收通知并更新自己的状态。

Define a one-to-many dependency between objects so that when one object changes state, 
all its dependents are notified and updated automatically.

UML图:

这里写图片描写叙述

主要包含:

  1. Subjcet(Stock):抽象的主题角色,把全部的观察者保存到一个集合中,每一个主题角色能够有不论什么数量的观察着。而且提供了一个接口来加入和删除观察着。
  2. ConcreteSubject(IBM):详细的主题角色。保存有关的状态信息,当它的状态发生变化时会将消息发送给全部的观察者。

  3. Observer(IInverstor):抽象的观察者角色。定义了一个更新自身的接口,当主题角色状态发生变化时会调用这个接口。

  4. ConcreteObserver(Investor):详细的观察着,持有一个主题角色的引用,实现了抽象观察者定义的更新自身的接口,以便使自身的状态与主题的状态相协调。

观察者模式的C++代码实现例如以下:

#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <list>
using namespace std;
class Subject;

class Observer
{
    public:
            Observer()
            {
            }
            Observer(Subject* s,string n)
            {
                subject=s;
                name=n;
            }
            virtual void update()=0;

            string getName()
            {
                return name;
            }

            Subject * getSubject()
            {
                return subject;
            }
    private:
            Subject *subject;
            string name;
};


class Subject
{
    public:
            void attach(Observer * o)
            {
                lists.push_back(o);
            }
            void detach(Observer * o)
            {
                lists.remove(o);
            }
            void notify()
            {
                list<Observer *>::iterator iter=lists.begin();
                for(;iter!=lists.end();iter++)
                {
                    (*iter)->update();
                }
            }

            virtual string getState()=0;
    private:
            list<Observer*> lists;

};

class ConcreteSubject :public Subject
{
    public:
        string getState()
        {
            string str("ConcreteSubject notify");
            return str;
        }
};

class ConcreteObserver:public Observer
{
    public:
            ConcreteObserver(Subject * s,string n):Observer(s,n)
            {   

            }
            void update()
            {
                std::cout<<getName()<<" update from "<<getSubject()->getState()<<std::endl;
            }
};

int main()
{
    Subject *s=new ConcreteSubject();
    Observer *o1=new ConcreteObserver(s,"Bill");
    Observer *o2=new ConcreteObserver(s,"Joe");

    s->attach(o1);
    s->attach(o2);

    s->notify();

    delete s;
    delete o1;
    delete o2;
    return 0;
}

运行输出:

这里写图片描写叙述

以下是一个详细的样例:

  1. Subject为Stock(股票)
  2. ConcreteSubject为IBM(IBM公司的股票。还能够是其他公司的股票)
  3. Observer为IInvestor(投资者接口)
  4. ConcreteObserver为Investor(就详细的投资者。即持有股票的人)

一种股票能够被多个投资者持有,即存在一种一对多的依赖关系,当股票的价格发生变化时须要通知全部持有这些股票的投资者(即观察者)。

UML类图例如以下:

这里写图片描写叙述

C++代码实现例如以下:

#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <string>
#include <list>


using namespace std;

class Stock;

class IInvestor
{
    public:
            IInvestor()
            {

            }
            IInvestor(string str,Stock *s):name(str),stock(s)
            {
            }
            Stock * getStock()
            {
                return stock;
            }
            string getName()
            {
                return name;
            }
            virtual void update()=0;
    private:
            Stock * stock;//投资的股票
            string name;//投资人名称
};

class Stock
{
    public:
            Stock()
            {

            }
            Stock(string str,double p):symbol(str),price(p)
            {
            }
            void setPrice(double p)
            {
                    price=p;
                    notify();
                    std::cout<<std::endl;
            }
            double getPrice()
            {
                    return price;
            }
            string getSymbol()
            {
                    return symbol;
            }
            void attach(IInvestor * ii)
            {
                investors.push_back(ii);
            }   
            void deattach(IInvestor *ii)
            {
                investors.remove(ii);
            }

            void notify()
            {
                list<IInvestor*>::iterator iter=investors.begin();
                for(;iter!=investors.end();iter++)
                {
                    (*iter)->update();
                }
            }

    private:
            string symbol; //股票名称
            double price;//股票价格
            list<IInvestor *> investors;//投资者

};

class IBM:public Stock
{
    public:
            IBM()
            {

            }
            IBM(string symbol,double price):Stock(symbol,price)
            {
            }
};

class Investor :public IInvestor
{
    public:
            Investor()
            {
            }
            Investor(string n,Stock *s):IInvestor(n,s)
            {
            }
            void update()
            {
                std::cout<<"Notified "<<getName()<<" of "<<getStock()->getSymbol()<<"'s change to "<<getStock()->getPrice()<<std::endl;
            }


};

int main()
{
    std::cout<<"股票交易的观察着模式的实现"<<std::endl;
    IBM *ibm=new IBM("IBM",120.10);

    IInvestor* investor1=new Investor("Sorros",ibm);
    IInvestor* investor2=new Investor("Berkshire",ibm);

    ibm->attach(investor1);
    ibm->attach(investor2);

    ibm->setPrice(120.50);
    ibm->setPrice(120.75);

    delete ibm;
    delete investor1;
    delete investor2;
    return 0;
}

运行结果:

这里写图片描写叙述

原文地址:https://www.cnblogs.com/mfrbuaa/p/5083684.html