用C++实现观察者模式的几种变体

观察者模式的标准定义

定义一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。当这个主题对象的状态发生改变时,会通知所有观察者对象,使它们能够自动更新自己的状态。

观察者模式的标准结构图

观察者模式结构图

观察者模式的标准实现

Subject(抽象主题)

Subject.h

#pragma once

#include <list>
#include <string>

class Observer;

class Subject
{
public:
	virtual ~Subject();

	virtual void addObserver(Observer* obsv);

	virtual void removeOvserver(Observer* obsv);

	virtual void notify();

private:
	std::list<Observer *> mObserverList;

};


Subject.cpp

#include "Subject.h"

#include "Observer.h"

Subject::~Subject()
{
	if (!mObserverList.empty())
	{
		mObserverList.clear();
	}
}

void Subject::addObserver(Observer* obsv)
{
	if (nullptr == obsv)
		return;
	bool bExist = false;
	std::list<Observer*>::const_iterator iter = mObserverList.begin();
	for (; iter != mObserverList.end(); ++iter)
	{
		Observer* const curObsv = iter.operator*();
		//*iter == obsv;
		if (curObsv == obsv)
		{
			bExist = true;
			break;
		}
	}

	if (bExist)
		return;
	mObserverList.push_back(obsv);
}

void Subject::removeOvserver(Observer* obsv)
{
	if (mObserverList.empty() || (nullptr == obsv))
		return;
	bool bExist = false;
	std::list<Observer*>::const_iterator iter = mObserverList.begin();
	for (; iter != mObserverList.end(); ++iter)
	{
		Observer* const curObsv = *iter;
		if (curObsv == obsv)
		{
			bExist = true;
			break;
		}
	}

	if (bExist)
		mObserverList.remove(obsv);
}

void Subject::notify()
{
	std::list<Observer*>::const_iterator iter;
	for (iter = mObserverList.begin(); iter != mObserverList.end(); ++iter)
	{
		Observer* const curObsv = *iter;
		curObsv->update();
	}
}

这里先说两个概念:原语函数钩子函数
原语函数,即纯虚函数,意思就是必须在子类中重定义的函数;
钩子函数,即虚函数,意思是可以在子类中重定义的函数。

ConcreteSubject(具体主题)

ConcreteSubject.h

#pragma once
#include "Subject.h"
class ConcreteSubjectA :
    public Subject
{
public:
    void setState(bool b);
    bool getState() const;

    void changedState();

private:
    bool mSendToA = false;
    bool mSendToB = false;
};


ConcreteSubject.cpp

#include "ConcreteSubjectA.h"
#include <iostream>

void ConcreteSubjectA::setState(bool b)
{
	mSendToA = mSendToB = b;
	changedState();
}

bool ConcreteSubjectA::getState() const
{
	return (mSendToA && mSendToB);
}

void ConcreteSubjectA::changedState()
{
	std::cout << "刘亦菲来啦~" << std::endl;

	if (getState())
	{
		notify();
	}
}

Observer(抽象观察者)

Observer.h

#pragma once

class string;

class Observer
{
public:
	Observer();
	virtual ~Observer();

	virtual void update() = 0;

};

Observer.cpp

#include "Observer.h"

Observer::Observer()
{
}

Observer::~Observer()
{
}

ConcreteObserverA(具体观察者A)

ConcreteObserverA.h

#pragma once
#include "Observer.h"
class ConcreteObserverA :
    public Observer
{
public:
    ConcreteObserverA();
    ~ConcreteObserverA();

    virtual void update() override;

};

ConcreteObserver.cpp

#include "ConcreteObserverA.h"
#include <iostream>

ConcreteObserverA::ConcreteObserverA()
{
}

ConcreteObserverA::~ConcreteObserverA()
{
}

void ConcreteObserverA::update()
{
	std::cout << "我要上报给领导!" << std::endl;
}

ConcreteObserverB(具体观察者B)

ConcreteObserverB.h

#pragma once
#include "Observer.h"

class ConcreteSubjectA;

class ConcreteObserverB :
    public Observer
{
public:
    ConcreteObserverB();
    virtual ~ConcreteObserverB();

    virtual void update() override;

};

ConcreteObserverB.cpp

#include "ConcreteObserverB.h"

#include "ConcreteSubjectA.h"

#include <iostream>

ConcreteObserverB::ConcreteObserverB()
{
}

ConcreteObserverB::~ConcreteObserverB()
{

}

void ConcreteObserverB::update()
{
	std::cout << "我要通知其他人!" << std::endl;
}

主程序简单调用

#include "ConcreteObserverA.h"
#include "ConcreteSubjectA.h"
#include "ConcreteObserverB.h"

#include <iostream>

int main()
{
    // Standard version
    ConcreteObserverA* obsvA = new ConcreteObserverA();
    ConcreteObserverB* obsvB = new ConcreteObserverB();
    ConcreteSubjectA* subA = new ConcreteSubjectA();
    subA->addObserver(obsvA);
    subA->addObserver(obsvB);
    subA->setState(true);
    subA->removeOvserver(obsvB);
    subA->removeOvserver(obsvA);

    return EXIT_SUCCESS;
}

其实到这里,可以结束了;但是,好像又远远不够。哪里不够呢?
你难道不觉得这两个观察者A、B有点太轻信于主题A了吗?不管谁给它们发消息,它们都相信 ,这样容易上当受骗呀——说是刘亦菲来了,其实是刘姥姥来啦~。
观察者A、B也很委屈,腹诽道:我也不知道是谁给我的消息,我只知道,有消息,我就得做出反应;哪里还管得了你的、他的。
这还不简单…

观察者变身一

Observer.h

#pragma once

#include "Subject.h"

class Observer_SecondVer // 响应固定主题
{
public:
	Observer_SecondVer();
	Observer_SecondVer(Subject* subject);
	virtual ~Observer_SecondVer();

	virtual void update(Subject* subject = nullptr) = 0;

protected:
	Subject* mSubject = nullptr;

};

ConcreteObserverA.h

#pragma once
#include "Observer.h"

class ConcreteObserverA_SecondVer : public Observer_SecondVer
{
public:
    ConcreteObserverA_SecondVer();
    ConcreteObserverA_SecondVer(Subject* subject);
    ~ConcreteObserverA_SecondVer();

    virtual void update(Subject* subject = nullptr) override;

    void doSomething();
};

ConcreteObserverA.cpp

#include "ConcreteObserverA.h"
#include <iostream>

ConcreteObserverA_SecondVer::ConcreteObserverA_SecondVer()
{
}

ConcreteObserverA_SecondVer::ConcreteObserverA_SecondVer(Subject* subject) : Observer_SecondVer(subject)
{
}

ConcreteObserverA_SecondVer::~ConcreteObserverA_SecondVer()
{
}

void ConcreteObserverA_SecondVer::update(Subject* subject)
{
	if (subject && subject == mSubject)
	{
		doSomething();
	}
}

void ConcreteObserverA_SecondVer::doSomething()
{
	std::cout << "通知老板!" << std::endl;
}

ConcreteObserverB.h

#pragma once
#include "Observer.h"

class ConcreteSubjectA;

class ConcreteObserverB_SecondVer : public Observer_SecondVer
{
public:
    ConcreteObserverB_SecondVer();
    ConcreteObserverB_SecondVer(ConcreteSubjectA* subject);
    ~ConcreteObserverB_SecondVer();

    virtual void update(Subject* subject = nullptr) override;

    void doSomething();
};

ConcreteObserverB.cpp

#include "ConcreteObserverB.h"

#include "ConcreteSubjectA.h"

#include <iostream>

ConcreteObserverB_SecondVer::ConcreteObserverB_SecondVer()
{
}

ConcreteObserverB_SecondVer::ConcreteObserverB_SecondVer(ConcreteSubjectA* subject) : Observer_SecondVer(subject)
{
}

ConcreteObserverB_SecondVer::~ConcreteObserverB_SecondVer()
{
}

void ConcreteObserverB_SecondVer::update(Subject* subject)
{
	if (subject && subject == mSubject)
	{
		doSomething();
	}
}

void ConcreteObserverB_SecondVer::doSomething()
{
	std::cout << "通知其他人!" << std::endl;
}

怎么样?以后,只要观察者A、B认定了主题A的消息,都进行响应,是不是就没那么容易上当受骗了。
突然,观察者A又有点其他的想法,弱弱地问道:“那个~我不想只看刘亦菲,只要是美女,能不能都给我发消息呀?”
啊~ 你这~
于是乎…

主题变身一/二 + 观察者变身二

Subject.h

#pragma once

#include <list>
#include <string>

class Observer;
class Observer_SecondVer;
class Observer_ThirdVer;

class Subject
{
public:
	virtual ~Subject();

	virtual void addObserver(Observer* obsv);

	virtual void removeOvserver(Observer* obsv);

	virtual void notify();

	virtual void addObserver(Observer_SecondVer* obsv);

	virtual void removeOvserver(Observer_SecondVer* obsv);

	virtual void notify_SecondVer();

	virtual void addObserver(Observer_ThirdVer* obsv);

	virtual void removeOvserver(Observer_ThirdVer* obsv);

	virtual void notify_ThirdVer();

private:
	std::list<Observer *> mObserverList;
	std::list<Observer_SecondVer*> mObserverList_SecondVer;
	std::list<Observer_ThirdVer*> mObserverList_ThirdVer;

};

Subject.cpp

void Subject::notify_SecondVer()
{
	std::list<Observer_SecondVer*>::const_iterator iter;
	for (iter = mObserverList_SecondVer.begin(); iter != mObserverList_SecondVer.end(); ++iter)
	{
		Observer_SecondVer* const curObsv = *iter;
		curObsv->update(this);
	}
}

void Subject::notify_ThirdVer()
{
	std::list<Observer_ThirdVer*>::const_iterator iter;
	for (iter = mObserverList_ThirdVer.begin(); iter != mObserverList_ThirdVer.end(); ++iter)
	{
		Observer_ThirdVer* const curObsv = *iter;
		curObsv->update(this, std::string("有美女!"));
	}
}

ConcreteSubjectA.h

#pragma once
#include "Subject.h"
class ConcreteSubjectA :
    public Subject
{
public:
    void setState(bool b);
    bool getState() const;

    void setStateA(bool b);
    bool getStateA() const;

    void setStateB(bool b);
    bool getStateB() const;

    void changedState();

private:
    bool mSendToA = false;
    bool mSendToB = false;
};

ConcreteSubjectA.cpp

#include "ConcreteSubjectA.h"
#include <iostream>

void ConcreteSubjectA::setState(bool b)
{
	mSendToA = mSendToB = b;
	changedState();
}

bool ConcreteSubjectA::getState() const
{
	return (mSendToA && mSendToB);
}

void ConcreteSubjectA::setStateA(bool b)
{
	std::cout << "美女来啦~" << std::endl;
	mSendToA = b;
	changedState();
}

bool ConcreteSubjectA::getStateA() const
{
	return mSendToA;
}

void ConcreteSubjectA::setStateB(bool b)
{
	std::cout << "刘亦菲来啦~" << std::endl;
	mSendToB = b;
	changedState();
}

bool ConcreteSubjectA::getStateB() const
{
	return mSendToB;
}

void ConcreteSubjectA::changedState()
{
	if (getStateA())
	{
		notify_SecondVer();
	}
	else if (getStateB())
	{
		notify_ThirdVer();
	}
	else if (getState())
	{
		notify();
		notify_SecondVer();
		notify_ThirdVer();
	}
	else
	{
		notify();
	}
}

Observer.h

#pragma once

#include "Subject.h"

class string;

class Observer_ThirdVer // 响应固定主题 + 固定消息
{
public:
	virtual ~Observer_ThirdVer() {}

	virtual void update(Subject* subject, const std::string& info) = 0;

};

ConcreteObserverA.h

#pragma once
#include "Observer.h"

class ConcreteObserverA_ThirdVer : public Observer_ThirdVer
{
public:
    ConcreteObserverA_ThirdVer() {}
    ConcreteObserverA_ThirdVer(Subject* subject);
    virtual ~ConcreteObserverA_ThirdVer();

    virtual void update(Subject* subject, const std::string& info) override;

protected:
    Subject* mSubject = nullptr;

};

ConcreteObserverA.cpp

#include "ConcreteObserverA.h"
#include <iostream>

ConcreteObserverA_ThirdVer::ConcreteObserverA_ThirdVer(Subject* subject) : mSubject(subject)
{
}

ConcreteObserverA_ThirdVer::~ConcreteObserverA_ThirdVer()
{
	if (mSubject)
		mSubject = nullptr;
}

void ConcreteObserverA_ThirdVer::update(Subject* subject, const std::string& info)
{
	if (subject && subject == mSubject)
	{
		if (info == "有美女!")
		{
			std::cout << "哇~" << std::endl;
		}
		else
		{
			std::cout << "(ˉ▽ ̄~) 切~~" << std::endl;
		}
	}
}

  • 45
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值