二、單例模式、建造者模式、原型模式(沒寫完) 享元模式 (沒寫完)

單例模式(singleton)

保證一個類只有一個實例存在,提供對該實例加以訪問的全局訪問方法

實現:

  1. 構造函數私有化
    防止別的地方調用
  2. 提供一個全局的靜態方法
  3. 類中有一個靜態指針,指向該類類型
    讓類負責保存他唯一的實例。

這里隱含的含義是,程序知道這個類只能被這樣實例化。

代碼

// ./Singleton.h
class Singleton
{
private:
  Singleton()=default;
  static Singleton *_instance;
public:
  static Singleton *instance();
  static bool freeInstance();
}

// ./Singleton.cc
#include "Singleton.h"


//惰性模式,不訪問不創建,在第一次訪問的時候創建
//對靜態變量的初始化必需放在類的外部
Singleton Singleton::*_instance=nullptr;
Singleton Singleton::*instance()
{
  if(_instance=nullptr)
  {
    _instance = new Singleton();
  }
  return _instance; 
}
//
//非惰性模式
//在程序一運行就進行了初始化
Singleton Singleton::*_instance=new Singleton();
Singleton Singleton::*instance()
{
  return _instance; 
}
//
bool Singleton::freeInstance()
{
  if(_instance!=nullptr)
  {
    delete _instance;
    _instance=nullptr;
  }
}

使用

#include "Singleton.h"
int main()
{
  Singleton *p=Singleton::instance();
  //....
  return 0;
}

單例模式與多線程

惰性單例模式由于其實例初始化的方式,會導致在多線程中可能創建多個實例,所以其構造函數不是一種線程安全的函數。
因此如果使用惰性模式,需要使用互斥量。

"單例"模式

單例模式的類,可以不止有一個實例,如果一個類需要幾個特定類型,或者需要的某種類型的實例的數量只需要一個。
那么可以不使用_instance存儲,改為map<string,Singleton*>即可。

建造者模式

對象的構建太復雜
將對象的表示與構建分離

例如,有一些類在創建的時候,需要傳大量的參數,還可能某一下參數是選填的。
并且還可能,這個類的實例創建出來以后,還有一些字段需要填。
那么如果只是用構造函數,那么這個邏輯,這個構造函數,可能會很臃腫。
也有一些字段可能就那么幾種,也就是說有那么一個模板。

啥?你說怎么可能有這樣的類?
人員管理啊,名字,地址,聯系方式,這些是必填的選項吧。郵箱,老婆,女朋友,這些事選填的吧。萬一以后又要加上工資這個字段,咋辦?還是用構造函數?
不現實啊。

設計模式是將問題的解決方法標準化的方法,再加上解耦,這個本來就復雜的問題,變得更加復雜了。嗯~~

UML

建造者模式

代碼

//人員
class ClerkDetail
{
public:
  clerkDetail()=default;
  clerkDetail(string name);      //表示必填的字段
  string sex();                  //下面的是字段的設置和獲取選項,使用了重載。
  void sex(string s);
  int age();
  void age(int i);
private:
  string _name;
  string _sex;                   //下面兩個表示選填的字段
  int      _age;
};

//模板繼承的基類
class abClerkTplt
{
  virtual void sex();      //這兩個是抽象的借口,t他們沒有參數
  virtual void age();        //因為其子類,將根據子類所指示的那種模板設置參數。
  virtual ClerkDetail* getclerk();
};

//人員的一些模板
class ManClerk:pubilc:abClerkTplt
{
public: 
  ManClerk()
  {
    _clerk=new ClerkDetail;
  }
  virtual void sex()
  {
    _clerk->set("man");
  }
  virtual void  age()
  {
    _clerk->age(17);
  }
  virtual ClerkDetail* getclerk()
  {
    return _clerk;
  }
private:
  ClerkDetail *_clerk;
};

//人員的一些模板,這里還是一個模板
class WomanClerk:pubilc:abClerkTplt
{
  //....
};

//一個執行模板子類的類。
class createClerk
{
public:
  createClerk(abClerkTplt* Tplt)
  {
    _tplt=tplt;
  }
  vodi create()
  {
    tplt->age();
    tplt->sex();
  }
private:
  abClerkTplt* _tplt;
};

//使用
int main()
{
  abClerkTplt* manTplt=new ManClerk;
  createClerk   dir(manTplt);
  dir.crete();
  ClerkDetail *clerk1=manTplt->getClerk();
}

這個模式過于復雜。應該是可以簡化的吧。比如createClerk這個類,應該可以去掉吧。
以后再想想。

原型模式

類能夠提供一個能夠復制自身的接口

復制自身則涉及到深拷貝和淺拷貝。
在復制指針類型時,如果之復制指針那么就是淺拷貝:兩個指針指向相同的地址,容易造成二次釋放。(多次釋放同一塊內存的地址)
復制指針的時候,復制指針復制地址的內容,在內存中開辟新的內存空間,而不是復制指針內容,稱為深拷貝:沒啥問題。
淺拷貝好比復制頂層。而深拷貝復制底層。

原型模式時,類自身提供一個clone()接口,返回自身類型的指針。就這么簡單
復制的時候,要么使用默認構造函數,創建一個臨時對象,要么使用拷貝構造函數。

UML

代碼

class AbPerson
{
public:  
  virtual AbPerson *clone()=0;
}

class Clerk:public:AbPerson
{
public:
  Clerk();
  Clerk(&clerk c)
  {
    //這里可以直接復制的就直接復制
    i=this.i;
    //c因為是個指針。不能夠直接復制,需要分配內存。
    c=this.cloneC();
  }
  virtual AbPerson *clone()
  {
    //轉發給拷貝構造函數,讓拷貝構造函數干活
    return new Clerk(*this)
  }
private:
  int i;
  char *c;
  char *cloneC()//這里可以放一個函數,用來復制C,有幾個指針,就有幾個這種函數。
   {

  }
}

這一部分回頭看看書。。。深拷貝+拷貝構造函數有點蒙了。

既然有了拷貝構造函數,那么為什么還需要原型模式?
拷貝構造函數只能復制自身。
而原型模式的基類提供了一種可以復制自身的方法,并且返回基類的指針。

拷貝構造函數為原型模式提供了實現。

享元模式

使用共享對象可有效的支持大量細粒度的對象

享元模式:共享不變的那部分元素。
如果系統需要創建大量的元素,而這些元素某一部分特征又是相同的,另一部分與有自己的特征。

比如,別人都提到的文本編輯器,每個字符可共享的部分就是字符本身,特征部分是字符的字號,顏色。
比如黑白棋,棋子可共享,但是有黑白和位置之分。

享元模式將一個對象劃分為可變部分和不可變部分,該類型對象的數量并沒介紹反而增加了。但是系統中總的對象數量確實是減少了。程序所占內存減少。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,362評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,577評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,486評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,852評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,600評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,944評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,944評論 3 447
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,108評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,652評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,385評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,616評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,111評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,798評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,205評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,537評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,334評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,570評論 2 379

推薦閱讀更多精彩內容