跨平台开发集群聊天项目四——设计模式学习

一、单例模式

程序只需要一个对象时要用单例模式,那么整个程序只构造了一次,这样还要遵照标准吗?这个看个人吧!但是要特别注意:多线程中可能会反复构造对象,我这个项目中就出现了这种情况,如果我不把服务层设计为单例模式,那么网络层每开辟一个线程就要构造一个对象。
再者,单例模式有饿汉,懒汉之分,饿汉的对象时静态变量,程序一启动就会构造,对于一个大的软件来说,没有人希望打开软件就花费个5分钟把。

  1. 饿汉模式
class Singleton
{
public:
	static Singleton* getInstance()
	{
		return &instance;
	}
private:
	Singleton() {};
	static Singleton instance;
};
Singleton Singleton::instance;
  1. 懒汉模式
class Singleton
{
public:
	static Singleton* getInstance()//用指针
	{
		static Singleton instance;
		return &instance;
	}

private:
	Singleton() {};
	Singleton(const Singleton&) {};
};

class Singleton2
{
public:
	static Singleton2& getInstance()//用引用
	{
		static Singleton2 instance;
		return instance;
	}
private:
	Singleton2() {};
	Singleton2(const Singleton2&) {};
};

int main()
{
	Singleton* p1 = Singleton::getInstance();
	Singleton2& p2 = Singleton2::getInstance();
}

二、MVC模式

MVC模式:有叫观察者-监听模式、发布-订阅模式。
框架:map<键:消息类型,值:处理方式>,发布函数,订阅函数
(1)项目中socket 层的回调函数和service层处理方法就时这种关系, 且一种消息对应一种处理方式。
(2)项目中radio 和 多个服务器也是MVC模型,不过多种消息对应一种处理者,且服务器即使发布方也是订阅方。

//项目中服务层代码
class Service
{
public:
	Service()
	{
		Map[1] = bind(&Service::fun0, this);
		Map[10] = bind(&Service::fun1, this);
		Map[11] = bind(&Service::fun1, this);
		Map[12] = bind(&Service::fun1, this);
	}

	void Pulish(int i)
	{
		Map[i]();
	}

	void fun0() { cout << "0+"<<endl; }
	void fun1() { cout << "10+"<<endl; }
	void fun2() { cout << "20+"<<endl; }

private:
	using Fun=function<void()>;
	unordered_map<int, Fun> Map;
};
//用动多态的方式实现
class Observer
{
public:
	virtual void handle(int msgid) = 0;
};

class Observer1 : public Observer
{
public:
	void handle(int msgid)
	{
		switch (msgid)
		{
		case 1:
			cout << "Observer1 recv 1 msgid" << endl;
			break;
		case 2:
			cout << "Observer1 recv 2 msgid" << endl;
			break;
		}
	}
};

class Observer2 : public Observer
{
public:
	void handle(int msgid)
	{
		switch (msgid)
		{
		case 2:
			cout << "Observer2 recv 2 msgid" << endl;
			break;
		}
	}
};

class Observer3 : public Observer
{
public:
	void handle(int msgid)//handle处理
	{
		switch (msgid)
		{
		case 1:
			cout << "Observer3 recv 1 msgid" << endl;
			break;
		case 3:
			cout << "Observer3 recv 3 msgid" << endl;
			break;
		}
	}
};

class Subject
{
public:
	//订阅
	void addObserver(Observer* obser, int msgid)
	{
		_subMap[msgid].push_back(obser);
	}

	//发布
	void dispatch(int msgid)
	{
		auto it = _subMap.find(msgid);
		if (it != _subMap.end())
		{
			for (Observer* pObser : it->second)
			{
				pObser->handle(msgid);
			}
		}
	}

private:
	unordered_map<int, list<Observer*>> _subMap;
};

int main()
{
	Subject subject;
	Observer* p1 = new Observer1();
	Observer* p2 = new Observer2();
	Observer* p3 = new Observer3();

	subject.addObserver(p1, 1);
	subject.addObserver(p1, 2);
	subject.addObserver(p2, 2);
	subject.addObserver(p3, 1);
	subject.addObserver(p3, 3);

	int msgid = 0;
	while (1)
	{
		cout << "please enter id: ";
		cin >> msgid;
		if (msgid == -1) break;
		subject.dispatch(msgid);
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值