• 正文
    • 1 代理模式
    • 2 實(shí)例
    • 總結(jié)
  • 推薦器件
  • 相關(guān)推薦
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

《大話設(shè)計(jì)模式解讀》04-代理模式

2024/06/24
696
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

上篇文章,介紹了《大話設(shè)計(jì)模式》的第6章——裝飾模式。

本篇,來介紹《大話設(shè)計(jì)模式》的第7章——代理模式。并通過C++代碼實(shí)現(xiàn)實(shí)例代碼的功能。

1 代理模式

代理模式的通俗理解為,一個(gè)人(代理人)替另一個(gè) (被代理人)來做某些事情。

代理模式(Proxy):為其它對(duì)象提供一種代理以控制對(duì)這個(gè)對(duì)象的訪問。

代理模式的類圖如下:

    • Subject:抽象主題類,

定義了需要代理的接口

    • RealSubject:具體主題類,即被代理類,

實(shí)現(xiàn)具體的接口功能

    • Proxy:代理類,提供代理接口,其具體的功能實(shí)現(xiàn)是調(diào)用被代理人的接口功能,即

作為中間人來替別人和第三方進(jìn)行交互

2 實(shí)例

背景:書中小故事,卓賈易同學(xué)送想要追求嬌嬌,但不認(rèn)識(shí)嬌嬌,就找戴勵(lì)同學(xué)幫其送禮物給嬌嬌,結(jié)果最后代理人戴勵(lì)與嬌嬌在一起了,卓賈易成了為別人做嫁衣。

題目:寫代碼來表示上述送禮物功能

2.1 版本一:沒有代理

版本一:沒有代理,讓追求者卓賈易直接送禮物給追求嬌嬌,類圖如下:

2.1.1 追求者與被追求者類

這里需要實(shí)現(xiàn)兩個(gè)類:

被追求者類,嬌嬌,目前題目中不需要有其它功能,僅維護(hù)一個(gè)自己的名字即可

追求者類,卓賈易,在實(shí)例化時(shí),傳入要追求的對(duì)象,并提供送禮物的接口,就是加句打印

// 被追求者
class SchoolGirl
{
public:
    std::string name;
};

// 追求者
class Pursuit
{
public:
    Pursuit(SchoolGirl mm)
    {
        m_mm = mm;
    }
    
    void GiveDOlls()
    {
        printf("%s 送你洋娃娃n", m_mm.name.c_str());
    }
    
    void GiveFlowers()
    {
        printf("%s 送你鮮花n", m_mm.name.c_str());
    }    
    
    void GiveChocolate()
    {
        printf("%s 送你巧克力n", m_mm.name.c_str());
    }  
             
private:
    SchoolGirl m_mm;
};

2.1.2 主函數(shù)

首先實(shí)例化一個(gè)被追求者,

然后實(shí)例化一個(gè)追求者,并傳入被追求者,然后依次調(diào)用追求者的送禮物接口。

#include <iostream>

int main()
{
   	// 被追求者
    SchoolGirl jiaojiao;
    jiaojiao.name = "嬌嬌";
    
    // 追求者
    Pursuit zhuojiayi = Pursuit(jiaojiao); // 嬌嬌并不認(rèn)識(shí)卓賈易,此處有問題
    zhuojiayi.GiveDOlls();
    zhuojiayi.GiveFlowers();
    zhuojiayi.GiveChocolate();
    
    return 0;
}

代碼運(yùn)行效果如下:

由于實(shí)際情況是,嬌嬌并不認(rèn)識(shí)卓賈易,因此不能直接將被追求者作為參數(shù)傳遞給給追求者。

下面來看版本二,使用代理,因?yàn)榇碚哒J(rèn)識(shí)嬌嬌。

2.2 版本二:只有代理

版本二與版本一的結(jié)構(gòu)基本一致,只是將追求者換成了代理人,類圖如下:

2.2.1 代理者與被追求者類

這里需要實(shí)現(xiàn)兩個(gè)類:

被追求者類,嬌嬌,僅維護(hù)一個(gè)自己的名字即可

代理者類,戴勵(lì),在實(shí)例化時(shí),傳入要追求的對(duì)象,并提供送禮物的接口

// 被追求者
class SchoolGirl
{
public:
    std::string name;
};

// 代理者
class Proxy
{
public:
    Proxy(SchoolGirl mm)
    {
        m_mm = mm;
    }
    
    void GiveDOlls()
    {
        printf("%s 送你洋娃娃n", m_mm.name.c_str());
    }
    
    void GiveFlowers()
    {
        printf("%s 送你鮮花n", m_mm.name.c_str());
    }    
    
    void GiveChocolate()
    {
        printf("%s 送你巧克力n", m_mm.name.c_str());
    }  
             
private:
    SchoolGirl m_mm;
};

2.2.2 主函數(shù)

首先實(shí)例化一個(gè)被追求者,

然后實(shí)例化一個(gè)代理者,并傳入被追求者,然后依次調(diào)用追求者的送禮物接口。

#include <iostream>

int main()
{
    // 被追求者
    SchoolGirl jiaojiao;
    jiaojiao.name = "嬌嬌";
    
    // 代理人
    Proxy daili = Proxy(jiaojiao); // 此時(shí)是代理者“戴勵(lì)”,追求者實(shí)例“卓賈易”又不在了
    daili.GiveDOlls();
    daili.GiveFlowers();
    daili.GiveChocolate();
    
    return 0;
}

代碼運(yùn)行效果如下:

版本二這種寫法,完全忽視了被代理者(追求者,卓賈易)的存在,也是不合實(shí)際的。

實(shí)際需求是要能體現(xiàn)禮物是追求者買的,代理是幫忙送禮物。

2.3 版本三:符合實(shí)際的代碼

版本三使用代理模式,類圖如下,定義一個(gè)接口類,來聲明需要代理來送的禮物類型,

然后追求者類(被代理人,卓賈易)和代理人類(戴勵(lì))各自實(shí)現(xiàn)送禮物的具體接口,實(shí)現(xiàn)接口,用虛線+空心三角表示,

代理人的接口內(nèi)部,實(shí)際是調(diào)用被代理人的接口實(shí)現(xiàn),

這里代理人需要“知道”被代理人的各種代理需求,這種“知道”的關(guān)系屬于關(guān)聯(lián)關(guān)系,用實(shí)線(加箭頭)表示。

2.3.1 追求者、代理者與被追求者類

這里需要實(shí)現(xiàn)四個(gè)類:

被追求者類,嬌嬌,僅維護(hù)一個(gè)自己的名字即可

代理接口,IGiveGift,聲明需要代理的功能

追求者類,卓賈易,在(通過代理)實(shí)例化時(shí),傳入要追求的對(duì)象,并提供送禮物的接口,就是加句打印

代理者類,戴勵(lì),在實(shí)例化時(shí),傳入要追求的對(duì)象,并提供送禮物的接口,其接口內(nèi)部是調(diào)用追求者類的具體實(shí)現(xiàn)

// 被追求者
class SchoolGirl
{
public:
    std::string name;
};

// 代理接口
class IGiveGift
{
public:
    virtual void GiveDolls(){};
    virtual void GiveFlowers(){};
    virtual void GiveChocolate(){};
};

// 追求者
class Pursuit : public IGiveGift
{
public:
    Pursuit(SchoolGirl *mm)
    {
        m_mm = mm;
    }
    
    ~Pursuit()
    {
        if(m_mm)
        {
            delete m_mm;
        }
    }
    
    void GiveDolls()
    {
        printf("%s 送你洋娃娃n", m_mm->name.c_str());
    }
    
    void GiveFlowers()
    {
        printf("%s 送你鮮花n", m_mm->name.c_str());
    }    
    
    void GiveChocolate()
    {
        printf("%s 送你巧克力n", m_mm->name.c_str());
    }  
             
private:
    SchoolGirl *m_mm;
};

// 代理者
class Proxy : public IGiveGift
{
public:
    Proxy(SchoolGirl *mm)
    {
        m_gg = new Pursuit(mm);
    }
    
    ~Proxy()
    {
        if(m_gg)
        {
            delete m_gg;
        }
    }
    
    void GiveDolls()
    {
        m_gg->GiveDolls();
    }
    
    void GiveFlowers()
    {
        m_gg->GiveFlowers();
    }    
    
    void GiveChocolate()
    {
        m_gg->GiveChocolate();
    }  
             
private:
    Pursuit *m_gg;
};

2.3.2 主函數(shù)

#include <iostream>

int main()
{
    SchoolGirl *jiaojiao = new SchoolGirl();
    jiaojiao->name = "嬌嬌";
    
    Proxy daili = Proxy(jiaojiao);
    daili.GiveDolls();
    daili.GiveFlowers();
    daili.GiveChocolate();
    
    delete jiaojiao;
    return 0;
}

代碼運(yùn)行效果如下:

總結(jié)

本篇介紹了設(shè)計(jì)模式中的代理模式,并通過代理人替被代理人送禮物的實(shí)例,使用C++編程,來演示代理模式的使用。

推薦器件

更多器件
器件型號(hào) 數(shù)量 器件廠商 器件描述 數(shù)據(jù)手冊 ECAD模型 風(fēng)險(xiǎn)等級(jí) 參考價(jià)格 更多信息
LAN8720AI-CP-TR 1 SMSC Ethernet Transceiver, 1-Trnsvr, CMOS, 4 X 4 MM, 0.85 MM HEIGHT, ROHS COMPLIANT, QFN-24
$1.74 查看
HFBR-2416Z 1 Foxconn Receiver, 160Mbps, ST Connector, Through Hole Mount, ROHS COMPLIANT, PLASTIC, 8 PIN
$24.86 查看
FTLF1321P1BTL 1 Finisar Corporation Transceiver, 1270nm Min, 1360nm Max, 2667Mbps(Tx), 2667Mbps(Rx), LC Connector, Panel Mount, ROHS COMPLIANT PACKAGE
$733.33 查看

相關(guān)推薦

登錄即可解鎖
  • 海量技術(shù)文章
  • 設(shè)計(jì)資源下載
  • 產(chǎn)業(yè)鏈客戶資源
  • 寫文章/發(fā)需求
立即登錄