Monday, April 1, 2013

Composite Pattern

  • Composite pattern is useful when you want to treat a group of objects in the same manner as a single instance of the object. The objects grouped, themselves could be in composite manner in a tree fashion.

  • The primitive and compound objects are treated uniformly.

  • A component interface is defined and both the leaf as well as composite objects implement it in uniform fashion.

  • Below example shows an implementation with a phone diagnostics composite pattern. A composite object is formed by combining all the phone related diagnostics objects in a tree manner. Then a diagnostic run on the composite object, which in turn reciprocates the request to all the diagnostics objects in a tree manner.

Sample implementation of composite pattern in C++


#include <iostream>
#include <string>
#include <list>

using namespace std;

class DiagnosticInterface {
public:
    virtual void runDiagnostics() = 0;
    virtual string getDianosticsResult() = 0;
};

class DiagnosticCompositeInterface : public DiagnosticInterface  {
public:
    void runDiagnostics() {
        for (list<DiagnosticInterface*>::iterator it = mCompositeObjs.begin(); it != mCompositeObjs.end(); ++it )
            (*it)->runDiagnostics();
    }
    string getDianosticsResult() {
        string ret = "";
        for (list<DiagnosticInterface*>::iterator it = mCompositeObjs.begin(); it != mCompositeObjs.end(); ++it )
            ret += (*it)->getDianosticsResult() + "\n";
        return ret;
    }
    void addChild(DiagnosticInterface *child) {
        mCompositeObjs.push_back(child);
    }
    void removeChild(DiagnosticInterface *child) {
        // find and remove the child. not implemented yet.
    }
    DiagnosticInterface* getChild(int i) {
        // get the child at i. Not implemented yet.
    }
protected:
    list<DiagnosticInterface*> mCompositeObjs;
};

class PhoneDiagnostics : public DiagnosticCompositeInterface {
public:
    void runDiagnostics() {
        cout << "running PhoneDiagnostics..." << endl;
        DiagnosticCompositeInterface::runDiagnostics();
    }
    string getDianosticsResult() {
        string ret = "PhoneDiagnostics all tested Okay!\n";
        ret += DiagnosticCompositeInterface::getDianosticsResult();
        return ret;
    }
};

class ScreenSaverDiagnostics : public DiagnosticInterface {
public:
    void runDiagnostics() {
        cout << "running ScreenSaverDiagnostics..." << endl;
    }
    string getDianosticsResult() {
        return "ScreenSaverDiagnostics all tested Okay!";
    }
};

class HardwareDiagnostics : public DiagnosticCompositeInterface {
public:
    void runDiagnostics() {
        cout << "running HardwareDiagnostics..." << endl;
        DiagnosticCompositeInterface::runDiagnostics();
    }
    string getDianosticsResult() {
        string ret = "HardwareDiagnostics all tested Okay!\n";
        ret += DiagnosticCompositeInterface::getDianosticsResult();
        return ret;
    }
};

class NetworkDiagnostics : public DiagnosticCompositeInterface {
public:
    void runDiagnostics() {
        cout << "running NetworkDiagnostics..." << endl;
        DiagnosticCompositeInterface::runDiagnostics();
    }

    string getDianosticsResult() {
        string ret = "NetworkDiagnostics all tested Okay!\n";
        ret += DiagnosticCompositeInterface::getDianosticsResult();
        return ret;
    }
};

class TouchScreenDiagnostics : public DiagnosticInterface {
public:
    void runDiagnostics() {
        cout << "running TouchScreenDiagnostics..." << endl;
    }
    string getDianosticsResult() {
        return "TouchScreenDiagnostics all tested Okay!";
    }
};

class OnOffKeyDiagnostics : public DiagnosticInterface {
public:
    void runDiagnostics() {
        cout << "running OnOffKeyDiagnostics..." << endl;
    }
    string getDianosticsResult() {
        return "OnOffKeyDiagnostics all tested Okay!";
    }
};

class WifiDiagnostics : public DiagnosticInterface {
public:
    void runDiagnostics() {
        cout << "running WifiDiagnostics..." << endl;
    }
    string getDianosticsResult() {
        return "WifiDiagnostics all tested Okay!";
    }
};

class ThreeGDiagnostics : public DiagnosticInterface {
public:
    void runDiagnostics() {
        cout << "running ThreeGDiagnostics..." << endl;
    }
    string getDianosticsResult() {
        return "ThreeGDiagnostics all tested Okay!";
    }
};

int main()
{
    DiagnosticCompositeInterface *phoneDiagnostics = new PhoneDiagnostics();

    DiagnosticInterface *screenSaverDiagnostics = new ScreenSaverDiagnostics();
    DiagnosticCompositeInterface *hardwareDiagnostics = new HardwareDiagnostics();
    DiagnosticCompositeInterface *networkDiagnostics = new NetworkDiagnostics();

    DiagnosticInterface *touchScreenDiagnostics = new TouchScreenDiagnostics();
    DiagnosticInterface *onOffKeyDiagnostics = new OnOffKeyDiagnostics();

    DiagnosticInterface *wifiDiagnostics = new WifiDiagnostics();
    DiagnosticInterface *threeGDiagnostics = new ThreeGDiagnostics();

    hardwareDiagnostics->addChild(touchScreenDiagnostics);
    hardwareDiagnostics->addChild(onOffKeyDiagnostics);

    networkDiagnostics->addChild(wifiDiagnostics);
    networkDiagnostics->addChild(threeGDiagnostics);

    phoneDiagnostics->addChild(screenSaverDiagnostics);
    phoneDiagnostics->addChild(hardwareDiagnostics);
    phoneDiagnostics->addChild(networkDiagnostics);

    cout << "Run diagnostics on the phone!" << endl;
    phoneDiagnostics->runDiagnostics();
    cout << "****\nGet the diagnostics result\n" << phoneDiagnostics->getDianosticsResult() << endl;
    return 0;
}

Output:-
Run diagnostics on the phone! 
running PhoneDiagnostics... 
running ScreenSaverDiagnostics... 
running HardwareDiagnostics... 
running TouchScreenDiagnostics... 
running OnOffKeyDiagnostics... 
running NetworkDiagnostics... 
running WifiDiagnostics... 
running ThreeGDiagnostics... 
**** 
Get the diagnostics result 
PhoneDiagnostics all tested Okay! 
ScreenSaverDiagnostics all tested Okay! 
HardwareDiagnostics all tested Okay! 
TouchScreenDiagnostics all tested Okay! 
OnOffKeyDiagnostics all tested Okay! 
 
NetworkDiagnostics all tested Okay! 
WifiDiagnostics all tested Okay! 
ThreeGDiagnostics all tested Okay!

Contact Form

Name

Email *

Message *

Back to Top