關於composition與singleton的爭論(?)
最近與公司同事討論到了這兩種方式的使用時機,請看以下狀況:
當我們提到composition的時候,主要是要拿來維持各個物件中的階層關係,以及讓物件的歸屬更為清楚。
class A
{
public:
A(){};
~A(){};
private:
};

class B
{
public:
B(){m_poA = new A;};
~B(){delete m_poA;};
private:
A* m_poA;
};
依以上的程式碼來看,class B在construct時便會建立一個A物件,而在B destruct時,A也會一同消失。
那麼現在來看看另外一種可以達到同樣目的寫法:
class C
{
public:
C(){m_poInstance = NULL;};
~C();

static C* GetInstance()
{
if(!m_poInstance)
{
m_poInstance = new C;
}
};

void Release()
{
delete m_poInstance;
};

void Init(){};

private:
static C* m_poInstance;
};

class B
{
public:
B()
{
C::GetInstance()->Init();
};

~B()
{
C::GetInstance()->Release();
};

private:
};

這次以singleton的寫法,來實作剛才的需求:B在destruct時,裡面的member也必須一併destruct。
根據同事的說法,兩種方法的不同點,在於第一種是遵循OO法則,class裡面的member很清楚歸屬於誰,該生成就生成,該消滅就消滅,並不會有模糊地帶。
而第二種方式等於是一個全域變數,使用者不管在何時何地呼叫,都會保證該class一定存在,等於是破壞了OO的法則。
這邊我提出一些看法,我覺得這兩種方式在結果上並無不同。第一種方式,必須在class中加上欲使用class的指標,然後去把他new出來,接著在適當的地方加上delete。
第二種方式使用singleton的做法,只需要在class中include對應的.h檔、然後呼叫GetInstance()即可開始使用,與第一種比較起來,少掉了在class中加上成員變數的麻煩,當然一樣要記住呼叫Release(),才不會造成memory leak。
而所謂的全域問題,問題應該歸咎於使用者的使用不當,比如說並未如上述所說去呼叫Release(),讓他在該消失的時候消失,結果造成該class一直都存在,甚至在程式結束時造成memory leak。那麼用第一種new的方式呢?還是要使用者手動去new以及delete,那麼如果使用者使用不當,不也是會造成memory leak?
當使用者確認在同一時間內(某個時段內),只會有一個實體存在的時候,使用singleton是沒有問題的,這也是singleton最大的存在意義。所以我是覺得這並不是設計原則的問題,只是寫法上的問題,應該沒有所謂的牴觸了OO法則這種情事。
posted on 2008-10-29 17:59 LancetChang 阅读(132) 评论(0) 收藏 举报


A()
浙公网安备 33010602011771号