C++ Composite Pattern

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 resultn" << 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 resultPhoneDiagnostics 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!