C++設計模式之代理模式

臣有一事不知當不當講發表於2018-04-14

問題:當待排的資料元素為體積龐大的物件時,如何提高排序的效率?

更換演算法的改善能力如果不足以滿足效率的提高要求?

問題分析:排序過程中不可避免地需要進行交換操作

                交換操作的本質是資料元素間的相互複製;

                當資料元素體積較大時,交換操作耗時巨大。

所以問題變成了如何提高交換操作的效率?

新的設計模式:代理模式

1、為待排資料元素設定代理物件;

2、對代理物件所組成的序列進行排序;

3、需要訪問有序資料元素時,通過訪問代理序列來完成。


首先例項化一個資料物件:

struct Test : public Object
{
    int id;
    int data1[1000];
    double data2[500];

    bool operator < (const Test& obj)
    {
       return id < obj.id;
    }

    bool operator >= (const Test& obj)
    {
       return id >= obj.id;
    }

    bool operator <= (const Test& obj)
    {
       return id <= obj.id;
    }

    bool operator > (const Test& obj)
    {
       return id > obj.id;
    }
};

在這個資料結構中,不僅僅定義了較大的資料物件,還對幾個比較運算子進行了過載。


如上圖所示,在實現代理類的過程中,需要通過引用來訪問實體:

protected:
    Test* m_pTest;  //指標成員指向被代理的物件
    Test& test() const
    {
        return *m_pTest;
    }

並且對實體類中的資料成員進行初始化操作:

    int id()
    {
        return m_pTest->id;
    }

    int* data1()
    {
        return m_pTest->data1;
    }

    double* data2()
    {
        return m_pTest->data2;
    }

同時過載比較運算子:

 bool operator < (const TestProxy& obj)
    {
       return test() < obj.test();
    }

    bool operator >= (const TestProxy& obj)
    {
       return test() >= obj.test();
    }

    bool operator <= (const TestProxy& obj)
    {
       return test() <= obj.test();
    }

    bool operator > (const TestProxy& obj)
    {
       return test() > obj.test();
    }

最後,過載賦值操作符:

    Test& operator =(Test& test)
    {
        m_pTest = &test;

        return test;
    }

建立代理類和實體:

Test t[1000];
TestProxy pt[1000];
主函式如下:
int main()
{
    clock_t begin = 0;
    clock_t end = 0;

   for(int i=0; i<1000; i++)
   {
      t[i].id = i;
      pt[i] = t[i];
   }

    begin = clock();

    Sort::Bubble(pt, 1000, false);

    end = clock();

    cout<< "begin = " <<begin <<endl;
    cout<< "end = " <<end <<endl;

    for(int i=0; i<1000; i++)
    {
       //cout<< t[i].id << " " <<pt[i].id()<<endl;
    }
    return 0;
}

執行上述程式碼,可以發現,是否使用代理來對資料進行排序,耗時差異較大,意味著效率差異也十分明顯。

問題提出:代理模式提高效率的本質是什麼? 排序還是需要對資料進行操作的,為什麼通過代理就可以提高效率。即使是代理去排序,還是對原物件進行操作。

代理的本質:必須注意的是,通過代理對物件的操作,是通過引用或者指標來進行的,通過這種方式,就可以提高效率。

小結: 當排序體積龐大的物件是,使用代理模式間接完成;

            代理模式的使用有效避開大物件交換時的耗時操作;

            代理模式解決方案是空間換時間思想的體現。

友情連結:https://blog.csdn.net/wuzhekai1985/article/details/6669219

                https://blog.csdn.net/lh844386434/article/details/18045671

            《大話設計模式》


相關文章