特別說明:本文件中部分代碼來自:
1. https://www.cnblogs.com/chengjundu/p/8473564.html
2. <設計模式:可複用面向對象軟件的基礎>
創建型模式
簡介:在創建對象時使用方法or類而不使用new運算符的方式
模式:
1. 生成器(BUILDER)
簡介:將一個複雜對象的構建與他的表示分離,使得同樣的構建過程可以創建不同的表示<br>
用途:
> 1.當創建複雜對象的算法應該獨立於該對象的組成部分以及他們的裝配方式時<br>
> 2.當構造過程必須允許被構造的對象有不同的表示時<br>
2. 工廠方法(FACTORY METHOD)
簡介:定義一個創建對象的接口,讓子類決定實例化哪一個類,Factory Method使一個類的實例<br>化延遲到其子類。<br>
用途:
> 1.我們明確地計劃不同條件下創建不同實例的時候<br>
> 2.當一個類希望由它的子類來制定它所創建的對象的時候<br>
示例:
```
class Tank
{
public:
virtual void message() = 0;
};
class Tank80:public Tank
{
public:
void message()
{
cout << "Tank80" << endl;
}
};
class Tank99:public Tank
{
public:
void message()
{
cout << "Tank99" << endl;
}
};
class TankFactory
{
public:
virtual Tank* createTank() = 0;
};
class Tank80Factory:public TankFactory
{
public:
Tank* createTank()
{
return new Tank80();
}
};
class Tank99Factory:public TankFactory
{
public:
Tank* createTank()
{
return new Tank99();
}
};
```
3. 抽象工廠(ABSTACT FACTORY)
簡介:提供一個創建一系列相關或相互依賴的對象接口,無需指定他們的具體類.
用途:
> 在一個產品族裏面,定義多個產品,而系統只消費其中某一族的產品
示例:
```
class Tank
{
public:
virtual void message() = 0;
};
class Tank80:public Tank
{
public:
void message()
{
cout << "Tank80" << endl;
}
};
class Tank99:public Tank
{
public:
void message()
{
cout << "Tank99" << endl;
}
};
class Plain
{
public:
virtual void message() = 0;
};
class Plain80: public Plain
{
public:
void message()
{
cout << "Plain80" << endl;
}
};
class Plain99: public Plain
{
public:
void message()
{
cout << "Plain99" << endl;
}
};
class Factory
{
public:
virtual Tank* createTank() = 0;
virtual Plain* createPlain() = 0;
};
class Factory80:public Factory
{
public:
Tank* createTank()
{
return new Tank80();
}
Plain* createPlain()
{
return new Plain80();
}
};
class Factory99:public Factory
{
public:
Tank* createTank()
{
return new Tank99();
}
Plain* createPlain()
{
return new Plain99();
}
};
```
4. 原型(PROTOTYPE)
簡介:用原型實例指定創建對象的種類,並且通過拷貝這些原型創建新的對象
用途:一般用在一開始不確定對象的類型,需要在程序運行期間創建新的對象
示例:
```
class Clone
{
public:
Clone()
{
}
virtual ~Clone()
{
}
virtual Clone* clone() = 0;
virtual void show() = 0;
};
class Sheep:public Clone
{
public:
Sheep(int id, string name):Clone(),m_id(id),m_name(name)
{
cout << "Sheep() id add:" << &m_id << endl;
cout << "Sheep() name add:" << &m_name << endl;
}
~Sheep()
{
}
Sheep(const Sheep& obj)
{
this->m_id = obj.m_id;
this->m_name = obj.m_name;
cout << "Sheep(const Sheep& obj) id add:" << &m_id << endl;
cout << "Sheep(const Sheep& obj) name add:" << &m_name << endl;
}
Clone* clone()
{
return new Sheep(*this);
}
void show()
{
cout << "id :" << m_id << endl;
cout << "name:" << m_name.data() << endl;
}
private:
int m_id;
string m_name;
};
int main()
{
Clone* s1 = new Sheep(1, "abs");
s1->show();
Clone* s2 = s1->clone();
s2->show();
delete s1;
delete s2;
return 0;
}
```
5. 單例(SINGLETON)
簡介:保證一個類只有一個實例,並提供一個訪問他的全局訪問點
單例大約有兩種實現方法:懶漢與餓漢。
> 懶漢:在第一次用到類實例的時候纔會去實例化
> 餓漢:在單例類定義的時候就進行實例化
特點與選擇:
> 由於要進行線程同步,所以在訪問量比較大,或者可能訪問的線程比較多時,採用餓漢實現
> ,可以實現更好的性能。這是以空間換時間
> 在訪問量較小時,採用懶漢實現。這是以時間換空間
示例:
```
//懶漢式:加lock,線程安全
std::mutex mt;
class Singleton
{
public:
static Singleton* getInstance();
private:
Singleton(){}
Singleton(const Singleton&) = delete; //明確拒絕
Singleton& operator=(const Singleton&) = delete; //明確拒絕
static Singleton* m_pSingleton;
};
Singleton* Singleton::m_pSingleton = NULL;
Singleton* Singleton::getInstance()
{
if(m_pSingleton == NULL)
{
mt.lock();
m_pSingleton = new Singleton();
mt.unlock();
}
return m_pSingleton;
}
//END
//餓漢式:線程安全,注意delete
class Singleton
{
public:
static Singleton* getInstance();
private:
Singleton(){}
Singleton(const Singleton&) = delete; //明確拒絕
Singleton& operator=(const Singleton&) = delete; //明確拒絕
static Singleton* m_pSingleton;
};
Singleton* Singleton::m_pSingleton = new Singleton();
Singleton* Singleton::getInstance()
{
return m_pSingleton;
}
//END
```