zoukankan      html  css  js  c++  java
  • 设计模式之十:观察者模式(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;
    }
    

    运行结果:

    这里写图片描写叙述

  • 相关阅读:
    vue登录注册及token验证
    react实现登录注册
    React Native仿京东客户端实现(首页 分类 发现 购物车 我的)五个Tab导航页面
    进度条效果
    手风琴切换效果
    React实现了一个鼠标移入的菜单栏效果
    react购物车
    react实现tab切换效果
    网络缓存
    java线程面试手写题
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/5083684.html
Copyright © 2011-2022 走看看