我這篇文章的主旨是介紹一部分類和接口的高質(zhì)量設(shè)計(jì)的準(zhǔn)則。這些準(zhǔn)則不但應(yīng)該保證設(shè)計(jì)并且實(shí)現(xiàn)的類或者接口本身有高質(zhì)量代碼,而且更重要的是在工業(yè)領(lǐng)域應(yīng)該盡可能的使代碼的更新和維護(hù)不影響客戶的活動(dòng),主要也就是保持二進(jìn)制代碼兼容(binary compatibility)和源代碼兼容(source compatibility)。我希望這些準(zhǔn)則能幫助剛從學(xué)校進(jìn)入工業(yè)領(lǐng)域的朋友盡快適應(yīng)更高標(biāo)準(zhǔn)的編程要求,盡快提升自己的設(shè)計(jì)能力。
文中以C++類的設(shè)計(jì)為討論范圍。
總提
面向?qū)ο缶幊虒?duì)于產(chǎn)出高質(zhì)量,易維護(hù)的代碼是非常有幫助的。面向?qū)ο缶幊痰母拍顦?gòu)建于三個(gè)基本特征之上:封裝,繼承,多態(tài)。在C++中,class是面向?qū)ο缶幊谈拍畹暮诵暮途唧w形式。class通過(guò)私有成員體現(xiàn)“封裝”,通過(guò)直接繼承或者組合體現(xiàn)“繼承”,通過(guò)虛函數(shù)和動(dòng)態(tài)綁定(dynamic binding)體現(xiàn)“多態(tài)”。class的設(shè)計(jì)質(zhì)量直接決定了整個(gè)系統(tǒng)的質(zhì)量。
從整體功能層面談class設(shè)計(jì),有這么三條原則:
·單一功能原則(Single Responsibility Principle)
一個(gè)class就其整體應(yīng)該只提供單一的服務(wù)。如果一個(gè)class提供多樣的服務(wù),那么就應(yīng)該把它拆分,反之,如果一個(gè)在概念上單一的功能卻由幾個(gè)class負(fù)責(zé),這幾個(gè)class應(yīng)該合并。
·開放/封閉原則(Open/Close Principle)
一個(gè)設(shè)計(jì)并實(shí)現(xiàn)好的class,應(yīng)該對(duì)擴(kuò)充的動(dòng)作開放,而對(duì)修改的動(dòng)作封閉。也就是說(shuō),這個(gè)class應(yīng)該是允許擴(kuò)充的,但不允許修改。如果需要功能上的擴(kuò)充,一般來(lái)說(shuō)應(yīng)該通過(guò)添加新類實(shí)現(xiàn),而不是修改原類的代碼。添加新類不單可以通過(guò)直接繼承,也可以通過(guò)組合。
·最小驚訝原理(Least Surprise Principle)
在重載函數(shù),或者子類實(shí)現(xiàn)父類虛函數(shù)時(shí),應(yīng)該基本維持函數(shù)原來(lái)所期望的功能。比如:
class Pet {
public:
virtual Talk() = 0;
};
class Cat : public Pet {
public:
void Talk() { cout << "miao"; }
};
class Dog : public Pet {
public:
void Talk() { BiteOwner(); }
};
class Dog 在實(shí)現(xiàn)虛函數(shù)Talk的時(shí)候,沒(méi)有像我們期望的那樣輸出狗吠聲,而是咬起主人來(lái)了。這是應(yīng)該避免的。
文中以C++類的設(shè)計(jì)為討論范圍。
總提
面向?qū)ο缶幊虒?duì)于產(chǎn)出高質(zhì)量,易維護(hù)的代碼是非常有幫助的。面向?qū)ο缶幊痰母拍顦?gòu)建于三個(gè)基本特征之上:封裝,繼承,多態(tài)。在C++中,class是面向?qū)ο缶幊谈拍畹暮诵暮途唧w形式。class通過(guò)私有成員體現(xiàn)“封裝”,通過(guò)直接繼承或者組合體現(xiàn)“繼承”,通過(guò)虛函數(shù)和動(dòng)態(tài)綁定(dynamic binding)體現(xiàn)“多態(tài)”。class的設(shè)計(jì)質(zhì)量直接決定了整個(gè)系統(tǒng)的質(zhì)量。
從整體功能層面談class設(shè)計(jì),有這么三條原則:
·單一功能原則(Single Responsibility Principle)
一個(gè)class就其整體應(yīng)該只提供單一的服務(wù)。如果一個(gè)class提供多樣的服務(wù),那么就應(yīng)該把它拆分,反之,如果一個(gè)在概念上單一的功能卻由幾個(gè)class負(fù)責(zé),這幾個(gè)class應(yīng)該合并。
·開放/封閉原則(Open/Close Principle)
一個(gè)設(shè)計(jì)并實(shí)現(xiàn)好的class,應(yīng)該對(duì)擴(kuò)充的動(dòng)作開放,而對(duì)修改的動(dòng)作封閉。也就是說(shuō),這個(gè)class應(yīng)該是允許擴(kuò)充的,但不允許修改。如果需要功能上的擴(kuò)充,一般來(lái)說(shuō)應(yīng)該通過(guò)添加新類實(shí)現(xiàn),而不是修改原類的代碼。添加新類不單可以通過(guò)直接繼承,也可以通過(guò)組合。
·最小驚訝原理(Least Surprise Principle)
在重載函數(shù),或者子類實(shí)現(xiàn)父類虛函數(shù)時(shí),應(yīng)該基本維持函數(shù)原來(lái)所期望的功能。比如:
class Pet {
public:
virtual Talk() = 0;
};
class Cat : public Pet {
public:
void Talk() { cout << "miao"; }
};
class Dog : public Pet {
public:
void Talk() { BiteOwner(); }
};
class Dog 在實(shí)現(xiàn)虛函數(shù)Talk的時(shí)候,沒(méi)有像我們期望的那樣輸出狗吠聲,而是咬起主人來(lái)了。這是應(yīng)該避免的。

