1. 程式人生 > >2015-03-12---外觀模式,建造者模式(附代碼),觀察者模式(附代碼),boost庫應用

2015-03-12---外觀模式,建造者模式(附代碼),觀察者模式(附代碼),boost庫應用

思想 err map 函數 成功 each clu all 說我

今天白天主要看了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這個類實現的分離。

外觀模式就是給client暴露的接口非常少。真正復雜的業務邏輯我們全都繳費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點起床了。已經刷完牙啦。準備睡覺。各位看官都這個點了,早點睡吧,我去睡覺了,晚安~

2015-03-12---外觀模式,建造者模式(附代碼),觀察者模式(附代碼),boost庫應用