面向對象的思想和基于接口的思想

(李林老師linux環(huán)境高級編程課后筆記)


架構的核心就是做到代碼封閉性黄橘,即來了新的需求不用改老代碼亥至,只用增加新代碼
核心要素:來一個變化點就新建一個體系結構
---李林老師


背景是實現一個加法器悼沈,對象中有一個數據成員作被加數贱迟,一個成員函數函數傳入加數姐扮,返回和。
此加法器類實現起來很簡單衣吠,如下代碼

#include <iostream>
using namespace std;
class CLAdder
{
public:
    explicit CLAdder(int iAugend)
    {
    m_iAugend = iAugend;
    }

    int Add(int iAddend)
    {
    return m_iAugend + iAddend;
    }

private:
    int m_iAugend;
};

int main()
{
    CLAdder adder(2);
    cout << adder.Add(4) << endl;
   
    return 0;
}

現在來了一個變化點(新的需求):需要實現帶權重的加法器的功能茶敏。
即輸出 被加數*權重+加數

此時用 來一個變化點就新建一個繼承體系 的思想,用c++面向對象思想來實現缚俏。

  • 面向對象的思想(繼承+多態(tài))


#include <iostream>
using namespace std;
class CLAdder
{
    public:
        explicit CLAdder(int iAugend)
        {
            m_iAugend = iAugend;
        }

        virtual ~CLAdder()
        {
        }

        virtual int Add(int iAddend)
        {
            return m_iAugend + iAddend;
        }

    protected:
        int m_iAugend;
};

class CLWeightingAdder : public CLAdder
{
    public:
        CLWeightingAdder(int iAugend, int iWeight) : CLAdder(iAugend)
    {
        m_iWeight = iWeight;
    }

        virtual ~CLWeightingAdder()
        {
        }

        virtual int Add(int iAddend)
        {
            return m_iAugend * m_iWeight + iAddend;
        }

    protected:
        int m_iWeight;
};

int main()
{
    //基類對象(不帶權重的加法器)
    CLAdder adder(2);
    //基類指針指向基類對象
    CLAdder * p = &adder;
    cout << "CLAdder:" << p->Add(4) << endl;
  
    //派生類對象(帶權重的加法器)
    CLWeightingAdder wadder(3, 4);
    
  //基類指針指向派生類對象
    p = &wadder;
    cout << "CLWeightAdder:" << p->Add(4) << endl;
    return 0;
}

c++中的多態(tài)思想惊搏,核心就是 基類指針指向派生類對象 ,c++的這個多態(tài)性質是虛函數機制支撐的忧换。具體可以看另一個筆記:虛函數和虛表初步

  • 這種程序設計思想在架構中的好處

    在測試代碼中恬惯,用戶都是對基類指針進行操作,來了變化點也是對p進行操作亚茬,在復雜的業(yè)務環(huán)境中如
fun(CLAdder * p)
{
  ...
}

中酪耳,對fun的使用,即使來了變化點(加了權重)刹缝,也不用對原本的fun函數進行修改碗暗,照樣可以用,只要傳進去的是派生類對象就可以梢夯,即做到了代碼的封閉性言疗,只加新代碼不改老代碼。

但是颂砸,這種設計方法也有不足的情況和更好的方案及基于接口的思想


此時又來了一個變化點噪奄,若基本的加法器是只能由兩個無符號整數相加,這時實現一個有符號整數的人乓、帶權重的加法器勤篮。誠然,依據來一個變化點就加一個繼承體系的思想撒蟀,可以再接著設計一個派生類叙谨,加一個有符號數的數據成員,和自己的加法函數保屯。但是手负,這樣的話涤垫,派生類就繼承了不必要的數據成員,產生了很多不必要的浪費竟终。這樣的設計卻是犯了過度設計的缺點蝠猬,并不是所有的變化點都是需求,此時有更好的方案统捶。即基于接口的思想

  • 基于接口的思想


#include <iostream>
using namespace std;
class ILAdder
{
public:
    ILAdder()
    {
    }

    virtual ~ILAdder()
    {
    }

    virtual int Add(int iAddend) = 0;
};

class CLAdder : public ILAdder
{
public:
    explicit CLAdder(unsigned int iAugend)
    {
    m_iAugend = iAugend;
    }

    virtual ~CLAdder()
    {
    }

    virtual int Add(int iAddend)
    {
    return m_iAugend + iAddend;
    }

private:
    unsigned int m_iAugend;
};

class CLWeightingAdder : public ILAdder
{
public:
    CLWeightingAdder(int iAugend, int iWeight)
    {
    m_iWeight = iWeight;
    m_iAugend = iAugend;
    }

    virtual ~CLWeightingAdder()
    {
    }

    virtual int Add(int iAddend)
    {
    return m_iAugend * m_iWeight + iAddend;
    }

private:
    int m_iAugend;
    int m_iWeight;
};

void f(ILAdder *pAdder)
{
    cout << pAdder->Add(4) << endl;
}

int main()
{
    CLAdder adder(2);
    f(&adder);

    CLWeightingAdder wadder(3, 4);
    f(&wadder);
   
    return 0;
}

在此思想中用到了c++中的另一個機制榆芦,虛基類和純虛函數。虛基類的實現為空喘鸟,成員函數都為純虛函數匆绣,就是要給子類重寫用的。

  • 這種設計思想的好處



    在測試代碼和原來的程序中什黑,f()函數的參數類型是虛基類即接口的指針崎淳,根據傳入的對象類型不同,調用的是不同的加法器的函數愕把。并沒有在來了需求后改老的代碼( f() )拣凹,也做到了代碼的封閉性。


對比和收獲

  • 本質上都是多態(tài)的思想恨豁,面向對象的思想我理解其實是繼承的思想嚣镜,基于接口的思想是把原來的父子關系變成了兄弟關系。
  • 面向對象的思想是拿著基類指針來干活橘蜜,基于接口的思想是拿著虛基類即接口的指針來干活菊匿。
  • 繼承的思想是一種強耦合關系,無論需不需要扮匠,子類都完全繼承了基類的數據成員捧请,基類變了,所有的派生類都要變棒搜,耦合與接口(函數)疹蛉,耦合與實現(數據成員)。所以能少用繼承就少用繼承力麸。
  • 想起以前設計類的時候可款,只會用繼承關系,當時就覺得基類有些數據成員和函數其實派生類并不需要克蚂,但是又覺得派生類確實是要跟基類有聯系的闺鲸,就無腦用了繼承,現在覺得耦合度確實太強了埃叭,并且會造成不必要的資源消耗摸恍。以后可以考慮接口的思想。

架構本質上就是解耦的過程,但是會增加很多的中間結構立镶,可能會降低性能壁袄,需要在設計的時候來權衡。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末媚媒,一起剝皮案震驚了整個濱河市嗜逻,隨后出現的幾起案子,更是在濱河造成了極大的恐慌缭召,老刑警劉巖栈顷,帶你破解...
    沈念sama閱讀 212,383評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異嵌巷,居然都是意外死亡萄凤,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 90,522評論 3 385
  • 文/潘曉璐 我一進店門晴竞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蛙卤,“玉大人狠半,你說我怎么就攤上這事噩死。” “怎么了神年?”我有些...
    開封第一講書人閱讀 157,852評論 0 348
  • 文/不壞的土叔 我叫張陵已维,是天一觀的道長。 經常有香客問我已日,道長垛耳,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,621評論 1 284
  • 正文 為了忘掉前任飘千,我火速辦了婚禮堂鲜,結果婚禮上,老公的妹妹穿的比我還像新娘护奈。我一直安慰自己缔莲,他們只是感情好,可當我...
    茶點故事閱讀 65,741評論 6 386
  • 文/花漫 我一把揭開白布霉旗。 她就那樣靜靜地躺著痴奏,像睡著了一般。 火紅的嫁衣襯著肌膚如雪厌秒。 梳的紋絲不亂的頭發(fā)上读拆,一...
    開封第一講書人閱讀 49,929評論 1 290
  • 那天,我揣著相機與錄音鸵闪,去河邊找鬼檐晕。 笑死恳啥,一個胖子當著我的面吹牛浅缸,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 39,076評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼萤厅,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了渊额?” 一聲冷哼從身側響起尽纽,我...
    開封第一講書人閱讀 37,803評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎乃坤,沒想到半個月后苛让,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 44,265評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡湿诊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,582評論 2 327
  • 正文 我和宋清朗相戀三年狱杰,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片厅须。...
    茶點故事閱讀 38,716評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡仿畸,死狀恐怖,靈堂內的尸體忽然破棺而出朗和,到底是詐尸還是另有隱情错沽,我是刑警寧澤,帶...
    沈念sama閱讀 34,395評論 4 333
  • 正文 年R本政府宣布眶拉,位于F島的核電站千埃,受9級特大地震影響,放射性物質發(fā)生泄漏忆植。R本人自食惡果不足惜放可,卻給世界環(huán)境...
    茶點故事閱讀 40,039評論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望朝刊。 院中可真熱鬧耀里,春花似錦、人聲如沸拾氓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽痪枫。三九已至织堂,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間奶陈,已是汗流浹背易阳。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留吃粒,地道東北人潦俺。 一個月前我還...
    沈念sama閱讀 46,488評論 2 361
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親事示。 傳聞我的和親對象是個殘疾皇子早像,可洞房花燭夜當晚...
    茶點故事閱讀 43,612評論 2 350

推薦閱讀更多精彩內容