现在的位置: 首页 > 综合 > 正文

《大话设计模式》之 第14章 老板回来,我不知道——观察者模式 小结

2013年10月01日 ⁄ 综合 ⁄ 共 3025字 ⁄ 字号 评论关闭

观察者模式?我觉得用通知者模式来形容也是可以的。

某个事物(Subject)的某些状态发生变化,于是通知观察列表中的观察者(Observer)去更新(Update)自身的相应状态,而这个相应的状态,是和Subject息息相关的。

《Head First 设计模式》设计原则

设计原则一

找出程序中会变化的方面,然后将其和固定不变的方面相分离——

观察者模式中,会变化的是主题的状态,以及观察者的数目和类型。使用这个模式,可以改变依赖于主题状态的对象,而不必改变主题

设计原则二

针对接口编程,不针对实现编程——

主题和观察者都是用接口:观察者利用主体的接口向主体注册,而主题利用观察者的接口Update通知观察者。这样可以让两者之间运作正常,又同时具有松耦合的优点。

设计原则三

多用组合,少用继承——

观察者模式利用“组合”将许多观察者组合进主题中。对象之间的这种关系不是通过继承产生的,而是在运行时利用组合的方式而产生的。

实际场景:

某些屌丝男(观察者)一直关注着Iphone5S的价格,屌丝男(观察者)的记住了当前的价格为price = 6000,由于这个价格太高,所以屌丝男(观察者)请求关注这个产品价格的变动,于是京东商城(通知者)将屌丝男(观察者)添加入了被通知列表,于是当某一次京东开展降价活动,Iphone5S的价格发生了变化,京东商城(通知者)循环遍历屌丝男(观察者)列表,告诉他们:屌丝男(观察者),你们的春天来了,Iphone5S降价了,你们快执行更新函数Update来做出相应的策略选择吧!于是屌丝男(观察者)们纷纷调用各自的Update函数,去更新Price(屌丝男自身的数据一直是price
= 6000,现在通过执行get操作,更新这个price),然后再根据Price的情况做出其他的决策。

OK,大致就是这个原理。

这里看过一篇点击打开CSDN博客链接,写得不错。

好了,啥也不说了,上代码

【观察者基类】

class Observer{
public:
    Observer(void);
    virtual ~Observer(void);
    virtual void Update(void) = 0;
    Subject* subject;
};

//观察者基类
Observer::Observer(void){
    
}

Observer::~Observer(void){
    
}

【DiaosinanObserver类】

class DiaosinanObserver : public Observer{
public:
    DiaosinanObserver(void);
    ~DiaosinanObserver(void);
    void Update(void);
public:
    double price;
};

//观察者
DiaosinanObserver::DiaosinanObserver(void){
    
}

DiaosinanObserver::~DiaosinanObserver(void){
    
}

void DiaosinanObserver::Update(void){
    price = ((JDSubject*)this->subject)->getPrice();
    std::cout << "====屌丝男们做出如下反应====\n";
    if (price < 4000) {
        std::cout << "====价格很合理,我买了====\n";
        this->subject->Detach(this);
    }else{
        std::cout <<"====价格仍旧太高,屌丝伤不起====\n";
    }
}

【通知者基类】

class Subject{
public:
    Subject(void);
    virtual ~Subject(void);
    virtual void Attach(Observer* observer);
    virtual void Detach(Observer* observer);
    void Notify(void);
    
public:
    std::list<Observer*> lObserver;
};

//通知者基类
Subject::Subject(void){
    
}
Subject::~Subject(void){
    
}

void Subject::Attach(Observer *observer){
    this->lObserver.push_back(observer);
    observer->subject = this;
}

void Subject::Detach(Observer *observer){
    this->lObserver.remove(observer);
    observer->subject = NULL;
}

void Subject::Notify(void){
    for (std::list<Observer*>::iterator p = this->lObserver.begin(); p != this->lObserver.end(); ++p) {
        (*p)->Update();
    }
}

【通知者子类】

class JDSubject : public Subject{
public:
    JDSubject(void);
    ~JDSubject(void);
    void setPrice(double pri){price = pri;}
    double getPrice(void){return price;}
    
protected:
    double price;
};

//通知者子类
JDSubject::JDSubject(void){
    
}

JDSubject::~JDSubject(void){
    
}

【main】

int main(int argc, const char * argv[])
{
    DiaosinanObserver* diaosinan = new DiaosinanObserver();
    diaosinan->price = 6000;
    
    JDSubject* jd = new JDSubject();
    jd->setPrice(6000);
    std::cout << "====太贵了,屌丝男要求关注Price====\n";
    //太贵了,屌丝男要求关注Price
    jd->Attach(diaosinan);
    std::cout << "====价格变化,通知屌丝男们====\n";
    //价格变化,通知屌丝男们
    jd->setPrice(5000);
    jd->Notify();
    std::cout << "====观察者列表中的成员个数为:" << jd->lObserver.size() << std::endl;
    std::cout << "====价格再次变化,继续通知屌丝男们====\n";
    //价格再次变化,继续通知屌丝男们
    jd->setPrice(3000);
    jd->Notify();
    
    std::cout << "====观察者列表中的成员个数为:" << jd->lObserver.size() << std::endl;
    
    delete diaosinan;
    diaosinan = NULL;
    
    delete jd;
    jd = NULL;
    
    return 0;
}

【结果】

====太贵了,屌丝男要求关注Price====

====价格变化,通知屌丝男们====

====屌丝男们做出如下反应====

====价格仍旧太高,屌丝伤不起====

====观察者列表中的成员个数为:1

====价格再次变化,继续通知屌丝男们====

====屌丝男们做出如下反应====

====价格很合理,我买了====

====观察者列表中的成员个数为:0

抱歉!评论已关闭.