设计模式:观察者模式

观察者模式(Observer Pattern)

有一个例子,电子屏幕和内部显示器上的股票价格要随着股票价格改变而改变。

使用C++来实现这个逻辑

#include <iostream>
// 显示器类
class Mointor{
public:
    // 展示股票价格
    void print(int v){
        std::cout << "Mointor: " << v << std::endl;
    }
};
// 电子屏类
class Billboard{
public:
    // 展示股票价格
    void display(int v){
        std::cout << "Billboard: " << v << std::endl;
    }
};
​
// 股票类
class stack{
public:
    stack(Mointor* mointor, Billboard* billboard,
          int v): prices(v), mointor(mointor), billboard(billboard){}
    // 设置股票价格
    void setPrice(int v){
        prices = v;
        mointor->print(v);
        billboard->display(v);
    }
private:
    int prices;
    Mointor* mointor;
    Billboard* billboard;
};
​
int main(){
    // 创建显示器对象
    Mointor* mointor = new Mointor();
    // 创建电子屏对象
    Billboard* billboard = new Billboard();
    // 创建股票对象
    stack* stock = new stack(mointor, billboard, 10);
    // 设置股票价格
    stock->setPrice(20);
    return 0;
}

这种实现方式,类之间紧耦合,当显示介质(Mointor或Billboard)发生变化时或新的显示媒介加入Stock类会频繁修改。

采用观察者模型修改上述代码:

  1. 抽象主题(Subject)角色:也叫抽象目标类或目标接口类,它提供了一个用于保存观察者对象的聚集类(List)和增加(attch)、删除观察者(detach)对象的方法,以及通知所有观察者的抽象方法。
  2. 具体主题(Stack)(被观察目标)角色:也叫具体目标类,它是被观察的目标,它实现抽象目标中的通知方法,当具体主题的内部状态发生改变时,通知所有注册过的观察者对象。
  3. 观察者接口(Observer)角色:它是一个抽象类或接口,它包含了一个更新自己的抽象方法(update),当接到具体主题的更改通知时被调用。
  4. 具体观察者(Mointor or Billboard)角色:实现抽象观察者中定义的抽象方法,以便在得到目标的更改通知时更新自身的状态。

#include <iostream>
#include <list>
​
class Stock;
class Observer{
public:
    Observer(Stock* stock): stock(stock){}
    virtual ~Observer(){}
    virtual void update(int v)=0;
private:
    Stock* stock;
};
​
class Subject{
public:
    // 添加观察者
    void attach(Observer* o){
        observers.push_back(o);
    }
    // 移除观察者
    void detach(Observer* o){
        observers.remove(o);
    }
    // 通知观察者
    void notify(int v){
        for(auto o:observers){
            o->update(v);
        }
    }
private:
    std::list<Observer*> observers;
};
​
// 股票价格类
class Stock{
public:
    // 添加观察者
    void attach(Observer* o){
        subject.attach(o);
    }
    // 移除观察者
    void detach(Observer* o){
        subject.detach(o);
    }
    // 通知观察者
    void notify(int v){
        subject.notify(v);
    }
    // 设置股票价格
    void setPrice(int v){
        price = v;
        notify(price);
    }
private:
    int price;
    Subject subject;
};
​
​
// 显示器类
class Mointor: public Observer{
public:
    Mointor(Stock* stock): Observer(stock){}
    ~Mointor(){}
    // 展示股票价格
    void print(int v){
        std::cout << "Mointor: " << v << std::endl;
    }
​
    void update(int v) override{
        print(v);
    }
};
​
// 电子屏类
class Billboard: public Observer{
public:
    Billboard(Stock* stock): Observer(stock){}
    // 展示股票价格
    void display(int v){
        std::cout << "Billboard: " << v << std::endl;
    }
    void update(int v) override{
        display(v);
    }
};
​
int main(){
    // 创建股票和显示器
    Stock* stock = new Stock();
    Mointor* monitor = new Mointor(stock);
    Billboard* billboard = new Billboard(stock);
    // 添加观察者
    stock->attach(monitor);
    stock->attach(billboard);
    // 设置股票价格
    stock->setPrice(10);
    stock->setPrice(20);
    // 移除观察者
    stock->detach(monitor);
    stock->setPrice(30);
    delete stock;
    delete monitor;
    delete billboard;
    return 0;
};

参考:

https://segmentfault.com/a/1190000040530952

DY:EfficLab

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值