1. 程式人生 > >觀察者模式實現案例(C++)

觀察者模式實現案例(C++)

#include <iostream>
#include <string>
#include <vector>
#include <memory>

using namespace std;

class Cat;   //前置宣告
class Dog;
class Mouse;

class Animal
{
public:
	class IVisitor   //類中宣告觀察者類
	{
	public:
		virtual ~IVisitor() {}

		virtual void Visit(Cat* animal) = 0;
		virtual void Visit(Dog* animal) = 0;
		virtual void Visit(Mouse* animal) = 0;
	};
private:
	string name;

public:
	Animal(const string& theName)
		:name{ theName }
	{
	}

	virtual ~Animal()
	{
	}

	const string& GetName()const
	{
		return name;
	}

	virtual string Introduce() const = 0;
	virtual void Accept(IVisitor* visitor) = 0;  //觀察者函式虛擬函式
};

class Cat : public Animal
{
public:
	Cat(const string& theName)
		:Animal{ theName }
	{
	}

	string Introduce()const override
	{
		return "我是一隻貓,我的名字叫\"" + GetName() + "\"。";
	}

	void Accept(IVisitor* visitor) override {   //重寫觀察者函式
		visitor->Visit(this);
	}
};

class Dog : public Animal
{
public:
	Dog(const string& theName)
		:Animal{ theName }
	{
	}

	string Introduce()const override
	{
		return "我是一隻狗,我的名字叫\"" + GetName() + "\"。";
	}

	void Accept(IVisitor* visitor) override {   //重寫觀察者函式
		visitor->Visit(this);
	}
};

class Mouse : public Animal
{
public:
	Mouse(const string& theName)
		:Animal{ theName }
	{
	}

	string Introduce()const override
	{
		return "我是一隻老鼠,我的名字叫\"" + GetName() + "\"。";
	}
	 
	void Accept(IVisitor* visitor) override {  //重寫觀察者函式
		visitor->Visit(this);
	}
};

class OnlyPrintCatVisitor :public Animal::IVisitor {     //用於在主函式中進行呼叫
public:
	void Visit(Cat* animal) override {    
		cout << animal->Introduce() << endl;
	}

	void Visit(Dog* animal) override {

	}

	void Visit(Mouse* animal) override {

	}
};

int main()
{
	auto tom = make_shared<Cat>("Tom");
	auto jerry = make_shared<Mouse>("Jerry");
	auto spike = make_shared<Dog>("Spike");
	auto butch = make_shared<Cat>("Butch");
	auto lightning = make_shared<Cat>("Lightning");
	vector<shared_ptr<Animal>> friends{ tom, jerry, spike, butch, lightning };

	OnlyPrintCatVisitor visitor;  //依次呼叫
	for (auto animal : friends)   
	{
		animal->Accept(&visitor);
	}


	system("PAUSE");
	return 0;
}