餐馆那些事之:Observer Pattern

1. 概述
Observer pattern常常用来描述对象一对多的关系,“一”称为subject,“多”称为observer。
subject状态如果发生变化,周知所有observer,这和发布/订阅有点类似。
observer pattern类图如下:
餐馆那些事之:Observer Pattern_第1张图片

2. 实例
餐馆中菜的价格和菜原料相关,猪肉价格暴涨,以猪肉(青椒炒肉、茄子炒肉)作为原料的菜的价格也会相应上涨。
此处:
Subject:原料
ConcreteSubject:肉
Observer:菜
ConcreateObserver:青椒炒肉、茄子炒肉

代码:

#include <iostream>
#include <list>
#include <algorithm>
using namespace std;

//observer
class Food
{
public:
        virtual ~Food()
        {
        }
        virtual void update(int) = 0;
};

//subject
class Material
{
public:
        virtual ~Material()
        {
                list<Food*>::iterator iter;
                for(iter = _food_list.begin(); iter != _food_list.end();)
                {
                        if(*iter)
                        {
                                _food_list.erase(iter++);
                        }
                }
        }

    //增加observer
        void add(Food* f)
        {
                _food_list.push_back(f);
        }

        //移除observer
        void remove(Food* f)
        {
                list<Food*>::iterator iter;
                iter = find(_food_list.begin(), _food_list.end(), f);
                while(iter != _food_list.end())
                {
                        _food_list.erase(iter);
                }
        }

        //通知observer
        void notify(int price)
        {
                list<Food*>::iterator iter;
                for(iter = _food_list.begin(); iter != _food_list.end(); iter++)
                {
                        (*iter)->update(price);
                }
        }

private:
        //observer链表
        list<Food*> _food_list;
};

//ConcreteSubject
class Pork : public Material
{
public:
        Pork()
        {
                _price = 10;
        }

        void price(int price)
        {
                _price = price;
                notify(_price);
        }
private:
        int _price;
};

//ConcreateObserver
class Pepper_Peak : public Food
{
public:
        Pepper_Peak()
        {
                _pepper = 5;
                _peak = 10;
                _other = 20;
        }

        void price()
        {
                int price = _pepper + _peak + _other;
                cout << "Pepper Peak price: " << price << endl;
        }

        void update(int peak)
        {
                _peak = peak;
        }

public:
        int _pepper;
        int _peak;
        int _other;
};

//ConcreteObserver
class Aube_Peak : public Food
{
public:
        Aube_Peak()
        {
                _aube = 2;
                _peak = 10;
                _other = 20;
        }

        void price()
        {
                int price = _aube + _peak + _other;
                cout << "Aube Peak price: " << price << endl;
        }

        void update(int peak)
        {
                _peak = peak;
        }

public:
        int _aube;
        int _peak;
        int _other;
};

int main(int argc, char** argv)
{
        Pork pork;

        Pepper_Peak* pepper_peak = new Pepper_Peak;
        Aube_Peak* aube_peak = new Aube_Peak;

        pork.add(pepper_peak);
        pork.add(aube_peak);

        pork.price(10);
        pepper_peak->price();
        aube_peak->price();

        pork.price(20);
        pepper_peak->price();
        aube_peak->price();

        delete pepper_peak;
        delete aube_peak;

        return 0;
}

运行输出:
$ ./bin/test
Pepper Peak price: 35
Aube Peak price: 32
Pepper Peak price: 45
Aube Peak price: 42

你可能感兴趣的:(餐馆那些事之:Observer Pattern)