jueves, 4 de enero de 2018

GoF patterns launcher and Chain of Resposibility pattern example (C++)

A C++ (codeblocks ide) project for GoF patterns practicing.It can be extended with the rest of patterns (command, state, factory, mediator, etc...).

Files in project:

main.cpp

:
#include 
#include 
#include "chainofresp.h"
#include "patternexec.h"

using namespace std;

const int CHAIN = 2;

int main()
{
    int sdirective = 2;
    PatternExec* _patterne = 0;
    string name ="CHAIN";
    string conf = "1000";

    switch(sdirective){
    case CHAIN:
        _patterne =  new PatternExec(new ChainOfResp(name,conf));
    break;
    default:
        return -100;

    }

   int r =   _patterne->execute();

   if(!r)
    cout << "Program ended correctly" << endl;

    return r;
}

patternexec.h

: It contains pattern's launcher (command) and specific pattern (in this case ChainOfResp) runner.
#ifndef PATTERNEXEC_H_INCLUDED
#define PATTERNEXEC_H_INCLUDED

#include 
#include 
#include 

using namespace std;

class Pattern {
public:
Pattern();
Pattern(string name, string conf);
virtual int run();
private:
    string _name;
    string _conf;
};
Pattern::Pattern() {}
Pattern::Pattern(string name, string conf) {
     _name = name; _conf= conf;
}
int Pattern::run() {
cout<< "Running an empty pattern " << endl;
return 10;
}
class PatternExec {

public:
PatternExec();
PatternExec(Pattern* pattern);
virtual int execute();
private:
    Pattern* _pattern;
};
PatternExec::PatternExec(Pattern* p){ _pattern = p;}
int PatternExec::execute() {
    return this->_pattern->run();
}


class ChainOfResp: public Pattern {
public:
ChainOfResp();
ChainOfResp(string name, string conf);
virtual int run();
void setConf(string conf);
private:
    string _staticName = "CHAIN";
    int _deep;
};
ChainOfResp::ChainOfResp(){}
ChainOfResp::ChainOfResp(string name, string conf){
   if( _staticName != name) cout<<"Incorrect pattern Name" <setConf(conf);
}
void ChainOfResp::setConf(string conf) {
 if(conf == "1000")
    _deep = 1000;
}
/**
Here is where pattern is applied
The value _deep indicates the TOPIC value which determines which component will process the call
*/
int ChainOfResp::run(){

Widget* aButton;
Widget* aField;
Dialog* aConfirm;
Application* anApp;

anApp = new Application(0, (TOPIC) _deep);
aConfirm = new Dialog(anApp, (TOPIC) _deep);
aField = new Widget(aConfirm, (TOPIC) _deep);
aButton = new Widget(aConfirm, (TOPIC) _deep);
cout << "Launch ChainOfResp from Button" << endl;
aButton->handle();
cout << "Launch CofResp from Field" << endl;
aField->handle();

cout << _staticName << " Pattern ended correctly " << endl;
return 0;
}

#endif // PATTERNEXEC_H_INCLUDED

chainofresp.h

: specific pattern implementation
#ifndef CHAINOFRESP_H_INCLUDED
#define CHAINOFRESP_H_INCLUDED

#include 
#include 

using namespace std;

typedef  int TOPIC;
const TOPIC NO_VALUE = -1;

class Handler {
public:
Handler();
Handler(Handler* sucessor,TOPIC topic);
 virtual int handle();

 virtual int doProcess();

private:
    Handler* _sucessor;
    TOPIC _topic;
    const static TOPIC _myTopic = 0;
};
Handler::Handler(){}
Handler::Handler(Handler* sucessor, TOPIC topic){
_sucessor=sucessor;
_topic = topic;
}

int Handler::handle() {
    cout<< "Handling from Handler class" << endl;

   if(_topic == _myTopic){
        _sucessor->handle();
   }else doProcess();

}
int Handler::doProcess() {
    cout<< "Processing!!! from Handler class " << endl;
}

class Widget: public Handler {
public:
Widget();
Widget(Handler* widget, TOPIC topic);
virtual int handle();
virtual int doProcess();
private:
    Handler* _parent;
    TOPIC _topic;
   const static TOPIC _myTopic = 1;
};
Widget::Widget(){}
Widget::Widget(Handler* w, TOPIC topic) {
    _parent = w;
    _topic = topic;
}
int Widget::handle(){
cout << "Hadling from Widget class " << endl;
 if(_topic == _myTopic){
    _parent->handle();
 }else doProcess();

}

int Widget::doProcess() {
cout << "Processing from Widget class " << endl;
Handler::doProcess();
}

class Dialog:public Handler{
public:
    Dialog();
    Dialog(Handler* h, TOPIC t);
    virtual int handle();
    virtual int doProcess();
private:
    Handler* _handler;
    TOPIC _topic;
    const static TOPIC _myTopic = 2;
};
Dialog::Dialog(){}
Dialog::Dialog(Handler* h, TOPIC t):Handler(h,t) {

}

class Application:public Handler {
public:
    Application();
    Application(Handler* h, TOPIC t);
    int handle();
    int doProcess();
private:
    const Application* _app = this;
    const static TOPIC _myTopic = 1000;

};
Application::Application(){}
Application::Application(Handler* h, TOPIC t):Handler(h,t){}


#endif // CHAINOFRESP_H_INCLUDED

Download project from Github

No hay comentarios :

Publicar un comentario