C++設計模式::裝飾模式or代理模式or面向切片程式設計(AOP)

Inside_Zhang發表於2015-11-20

一個例項


這裡寫圖片描述

裝飾模式:動態地一個物件(而非一個類)新增一些額外的職責。就增加功能來說,裝飾模式比建立子類更加靈活,因為有時我們的需求是給某個物件而不是整個類新增一些功能,比如為一部手機新增增加掛件、螢幕貼膜等等特性,一種比較靈活的方式,將手機(被裝飾器類)嵌入到另一個物件(裝飾器類)中(兩者之間是一種組合關係),有這個物件(裝飾器類)完成物件新特性的新增。

如上面的裝飾器UML類圖所示,裝飾器類作為被裝飾器類的兄弟類派生自同一個基類,二者介面一致,因此它對該元件的客戶透明。圖中我們也可以看到,用於裝飾的裝飾器類可以被獨立出來,可單獨發展,這無疑能夠簡化具體被修飾類的設計,使其專注於其核心功能的實現。

class IHello
{
public:
    virtual ~IHello() {}       // 將多型基類的解構函式宣告為virtual
    virtual void show() = 0;
                    // 子類只有實現該介面才可進行物件的例項化工作
};

class Hello :public IHello
{
private:
    std::string _name;
public:
    Hello(const std::string& name):_name(name){}
    void show() { std::cout << "hello " + _name << std::endl;}
};

class HelloDecorator :public IHello
{
private:
    IHello* _hello;
    virtual void addDecorator() = 0;
public:
    HelloDecorator(IHello* hello):_hello(hello){}
    void show() { _hello->show();}
};

class HelloDecoratorA :public HelloDecorator
{
private:
    void addDecorator() { std::cout << "logging in ..." << std::endl;}
public:
    HelloDecoratorA(IHello* hello):HelloDecorator(hello){}
    void show()
    {
        addDecorator();
        HelloDecorator::show();
    }
};

class HelloDecoratorB :public HelloDecorator
{
private:
    void addDecorator() { std::cout << "logging out ..." << std::endl;}
public:
    HelloDecoratorB(IHello* hello):_hello(hello){}
    void show() 
    {
        HelloDecorator::show();
        addDecorator();
    }   
};

int main(int, char**)
{
// shard_ptr<IHello>統一使用基類智慧指標,進行堆物件的管理

    std::shared_ptr<IHello> hello(new Hello("Inside Zhang"));
    std::shared_ptr<IHello> helloA(new HelloDecoratorA(hello.get()));
    std::shared_ptr<IHello> helloB(new HelloDecoratorB(hello.get()));
    std::shared_ptr<IHello> helloAB(new HelloDecoratorB(helloA.get()));
//  helloA->show();
//  helloB->show();
    helloAB->show();
    return 0;
}

這不由得讓人聯想起裝飾器模式與面向切面程式設計(Aspect Oriented Programming,AOP)的相似性,當我看到一本書中介紹面相切面程式設計畫了一樣的UML類圖時。面向切面程式設計是作為物件導向程式設計的有益補充而被引入的。


這裡寫圖片描述

  1. AOP能夠解決一些OOP中的一些問題,或者準確地說,是為了解決繼承中存在的問題。

    比如,OOP中的繼承是一種縱向的從基類到子類(自上而下)的關係,不適合定義從左到右的橫向關係。當繼承體系中的許多無關聯的物件存在一些公共行為(比如增加列印日誌的功能),這些公共行為可能分佈在不同的元件不同的物件之中。通過繼承方式來提取這些公共行為,這些核心業務邏輯之外的修飾性的功能,就顯得力不從心了。

  2. AOP提高程式的可維護性。

    AOP將程式的非核心邏輯都“橫切”出來,將非核心邏輯和核心邏輯分離,使我們集中精力在核心邏輯上。

可不可以將裝飾器模式理解為面向切面程式設計思想的一種具體的實現方式呢?

相關文章