2015-03-12---外观模式,建造者模式(附代码),观察者模式(附代码),boost库应用

7 篇文章 0 订阅
3 篇文章 0 订阅

今天白天主要看了boost库的应用,主要是常用的一些库,array,bind,function,regex,thread,unordered,ref,smartpointers库,晚上看了看设计模式,主要就是外观模式,建造者模式和观察者模式。我们从boost简要说起。

其实boost的库好多东西在c++11里面已经有了,比如bind,只不过boost的库的bind比c++11用着感觉要方便,其实有些东西我自己因为也没有用c++做过什么大的项目,所以不敢乱说,只敢说点建议性的,关于bind就是绑定函数吧,这个。。。比如一个函数原型是这样void fun(int a,int b),我们就可以用boost再绑定一下,比如第2个参数我们固定为100,那么就可以这么写boost::function<void(int,int)> fun1 = boost::bind(fun,_1,100),这样我们就成功的通过function和bind联合起来用,来绑定了,我们这里说的是一个定值,其实这里完全可以根据业务需求来换成一个不定的值。

接下来说说regex,这个是今天最头疼的问题,不是因为正则表达式难,正则表达式在以前我做java的时候用过,感觉还不错啊,但是boost,c++的语法今天实在是令我淡疼,所以我就想,就先这么肤浅的用着吧,有项目要用的时候我们在深入一下也不迟,boost::regex_match这个函数主要是全部匹配匹配整个串,boost::regex_search这个函数可以实现匹配部分哦,比如192.168.0.1,我们可以通过"(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)",来匹配出数字啊,结果自然就存在boost::smatch里面啦,还有一个boost::regex_replace,这个替换完的会通过返回值返回回来的。

还有thread,其实c++11就是抄的boost的thread,他俩大同小异,大家可以借助文档啦。

还有智能指针,智能指针大体有3种,scoped,shared,weak,细分的话就是scoped_ptr,scoped_array,同理shared也是,weak只有weak_ptr,scoped的意思就是我们分配了就只能是我自己指向这块内存,不能拷贝赋值,shared可以拷贝赋值。weak_ptr是一个弱引用,为什么说是弱引用呢,其实并不修改该对象的引用计数。

若引用可以防止内存泄露,不要认为只能指针就不会内存泄露,c++的内存泄露也是偶尔会存在智能指针里的,举个栗子:

#include <iostream>
#include <boost/smart_ptr.hpp>

using namespace std;

class Parent;
class Children;

class Parent
{
public:
	Parent()
	{
		cout << "parent create" << endl;
	}
	~Parent()
	{
		cout << "parent destroy" << endl;
	}
	boost::shared_ptr<Children> c;
};

class Children
{
public:
	Children()
	{
		cout << "children create" << endl;
	}
	~Children()
	{
		cout << "children destroy" << endl;
	}
	boost::shared_ptr<Parent> p;
};

void test()
{
	boost::shared_ptr<Parent> p(new Parent);
	boost::shared_ptr<Children> c(new Children);
	p->c = c;
	c->p = p;
}

void main()
{
	test();
	cin.get();
}

这不就内存泄露了吗,Parent里有指针指向Children,Children内部有指针指向Parent,这俩就在这循环着,谁也不释放内存,如果想结局这个问题,我们就要用到weak_ptr,只要我们将其中一个对象内部的指针从shared_ptr改为weak_ptr就可以了,所以说我们编程的时候,一定要有这个意识,智能指针也会内存泄露。

ref就是一个包装的引用,有的时候我们不能拷贝复制,因为有的时候传参是拷贝传参的,所以这个时候我们就要用到了ref。

unordered里主要是由unordered_map,unordered_mutlimap,unordered_set,unordered_mutliset,他们内部结构都是哈希,查找的时间复杂度为O(1),这个是boost帮我们实现的了。


-----------------------------------------------------------------------------------------------------------分割线-------------------------------------------------------------------------------------------------------------------


下面是设计模式了


外观模式:上图:


这个外观模式的精髓就在于Facade这个类实现的分离。

外观模式就是给客户端暴露的接口很少,真正复杂的业务逻辑我们全都缴费Facade和SubSystem来交互。

应用场景:

首先,在设计初期阶段,应该要有意识将不同的两个层分离,,层与层之间建立外观Facade,
其次,在开发阶段,子系统往往因为不断的重构演化而变得越来越复杂。增加外观模式,减少依赖。
第三,维护一个一流的大型系统的时候,可能这个系统已经非常难以维护和扩展了,就要修改设计,让新系统与Facade对象交互,Facade与遗留代码交互所有复杂工作。

MVC不就是采用的这个模式吗.分层思想。。。



建造者模式:上图;


这个建造者模式的精髓主要用于创建一些复杂的最想,这些对象内部构建间的建造顺序通常是稳定的,但对象内部的构建通常面临着复杂的变化。

这个内部很复杂,但是这些东西都是Director来做的,Client不用管,Client管的就是按照接口一个一个的把方法实现就行了,然后用Director来创建对象,最后产品就出来了。

好处:使建造代码与表示代码分离,由于建造者隐藏了该产品是如何组装的,所以如果需要改变一个产品的内部表示,只需要再定义一个具体的建造者就可以了。


所以说,建造者模式是在当创建复杂对象的算法应该独立于该对象的组成部分以及他们的装配方式时使用的模式.


其实我们在android里的AlertDialog.Builder不也很相似吗,我们没有关注细节,最后build除了那个dialog

建造者模式代码:
#include <iostream>

using namespace std;

class Product
{
public :
	char *head = nullptr;
	char *body = nullptr;

	friend ostream & operator<<(ostream & os, Product & pro)
	{
		os << pro.head << "   " << pro.body;
		return os;
	}
};

class Builder
{
protected:
	Product *p = nullptr;
public:
	Builder()
	{
		p = new Product;
	}
	~Builder()
	{
		delete p;
	}
public:
	virtual Product & getResult()
	{
		return *p;
	}
	virtual void buildPartA() = 0;
	virtual void buildPartB() = 0;
};

class BuilderA : public Builder
{
public:
	virtual void buildPartA() override
	{
		p->head = "大头";
	}
	virtual void buildPartB() override
	{
		p->body = "金身";
	}
};

class BuilderB : public Builder
{
public:
	virtual void buildPartA() override
	{
		p->head = "小头";
	}
	virtual void buildPartB() override
	{
		p->body = "测试";
	}
};

class Director
{
public:
	void build(Builder & b)
	{
		b.buildPartA();
		b.buildPartB();
	}
};

void main_jianzao()
{
	Builder *b1 = new BuilderA;
	Builder *b2 = new BuilderB;
	Director dir;
	dir.build(*b1);
	dir.build(*b2);
	Product &p1 = b1->getResult();
	Product &p2 = b2->getResult();
	cout << p1 << endl;
	cout << p2 << endl;


	cin.get();
}





观察者模式:上图:



今天晚上用c++调了半天,最后还是有点小问题,明天再调吧,今天实在是困得不行不行了。

我们说完,观察者模式就是我们常说的监听,其实监听器就是根据这个模式来的。
当一个对象的改变需要同时改变其他对象的时候就需要我们考虑用观察者模式了,
而且他不知道具体有多少对象有待改变的时候,应该考虑使用观察者模式。


观察者模式所做的工作就是在解除耦合.让耦合双方都依赖于抽象,而不是依赖于具体,从而使得各自的变化都不会影响另一边的变化.

观察者模式代码如下:
#include <iostream>
#include <vector>
#include <algorithm>
#include <boost/smart_ptr.hpp>
#include <memory>

using namespace std;

class Observer;
class TongshiA;
class TongshiB;
class Event;
template<class T>
class AbstractSubject;

class Secretary;
class Boss;

class Event
{
public:
	string type = nullptr;
	string content = nullptr;
	Event()
	{

	}
	Event(string &type, string & content) :type(type), content(content)
	{

	}
};

template<class T>
class AbstractSubject
{
protected:
	vector<T *> *obsevers = nullptr;
	
public:
	virtual void attch(T * p)
	{
		obsevers->push_back(p);
	}
	virtual void detach(T * p)
	{
		remove(obsevers->begin(), obsevers->end(), p);
	}
	virtual void notifyall() = 0;
	AbstractSubject()
	{
		obsevers = new vector<T*> ;
	}
	~AbstractSubject()
	{
		delete obsevers;
	}
	
};

class Observer
{
public:
	const char *name;
	Observer(const char *name) :name(name)
	{

	}
	virtual void update(Event & e)
	{
		cout << "消息内容:" << e.content.c_str() << endl;
	}
};

class TongshiA : public Observer
{
public:
	TongshiA(const char * name) :Observer(name)
	{

	}
	virtual void update(Event & e) override
	{
		cout << "消息内容:" << e.content.c_str() << endl;
		if (strcmp(e.type.c_str(), "警报") == 0)
		{
			cout << "关闭游戏,继续工作" << endl;
		}
		else
		{
			cout << "反正老板也没回来,去刷副本" << endl;
		}
	}
};

class TongshiB : public Observer
{
public:
	TongshiB(const char *name) :Observer(name)
	{

	}
	virtual void update(Event & e) override
	{
		cout << "消息内容:" << e.content.c_str() << endl;
		if (strcmp(e.type.c_str(), "警报") == 0)
		{
			cout << "最小化股票,好好工作" << endl;
		}
		else
		{
			cout << "和同事还能聊会儿天" << endl;
		}
	}
};

class Secretary : public AbstractSubject<Observer>
{
public:

	virtual void attch(Observer * t)
	{
		obsevers->push_back(t);
	}
	virtual void detach(Observer * t)
	{
		remove(obsevers->begin(), obsevers->end(), t);
	}
	virtual void notifyall() override
	{
		for_each(obsevers->begin(), obsevers->end(), [&](Observer * obs)
		{
			string s1("警报");
			string s2("老板来了");
			Event e(s1, s2);
			obs->update(e);
		});
	}
};

class Boss : public AbstractSubject < Observer >
{
public:
	virtual void attch(Observer * t)
	{
		obsevers->push_back(t);
	}
	virtual void detach(Observer * t)
	{
		remove(obsevers->begin(), obsevers->end(), t);
	}
	virtual void notifyall() override
	{
		for_each(obsevers->begin(), obsevers->end(), [&](Observer * obs)
		{
			string s1("正常");
			string s2("老板出去了");
			Event e(s1,s2);
			obs->update(e);
		});
	}
};




void main()
{

	AbstractSubject<Observer> *sec = new Secretary;
	Observer *a = new TongshiA("tongshia");
	Observer *b = new TongshiB("tongshib");
	sec->attch(a);
	sec->attch(b);

	AbstractSubject<Observer> *boss = new Boss;
	boss->attch(a);
	boss->attch(b);

	sec->notifyall();
	cout << "---------------------------------" << endl;
	boss->notifyall();

	cin.get();
}




实在是困了,这了快2点了,明天正常的话要7点多起床,看来要8点起床了,已经刷完牙啦,准备睡觉,各位看官都这个点了,早点睡吧,我去睡觉了,晚安~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值