jueves, 8 de marzo de 2018

Understanding java.util.concurrent.Future (Basics)

In this article you'll find a basic example of this Java interface and it will introduce you to the use of the @Async Spring, EJB, annotation

You can find it at: Future interface basics

lunes, 5 de marzo de 2018

miércoles, 21 de febrero de 2018

Branch & Bound + visitor pattern, path finder example (C++)

This example tries to solve the following problem: We have a NxN checker. Every (i,j) case contains k points (in this example k=4). One entry point that is a point located into the case's boundary. Two points are inside the case and the last point is an exit point, also at the boundary (different from entry). The algorithm uses Branch & Bound technique to: given an initial case and an end case, compute the minimal cost path from init to end. It also uses visitor pattern to get results. Implementation needs to be finished in some points.

Main library: "pathfinder.h"

#ifndef PATHFINDER_H_INCLUDED
#define PATHFINDER_H_INCLUDED

#include "visitor.h"

#include 
#include 
#include 
#include 
#include 

typedef struct {
B = 0, // boundary point
M = 1  // middle point
} PointType;

class Point2D {
public:
Point2D(double x, double y, PointType t){ this->_x = x; this->_y= y; this->_type = t;}
Point2D(double x, double y){ this->_x = x; this->_y= y; this->_type = PointType::I;}
~Point2D();
static double segment(Point2D * from, Point2D * to);
virtual Point2D* closest(Point2D * pa, Point2D* pb);
double getX() { return this->_x; }
double getY() { return this->_y; }
PointType getType() { return this->_type;}
bool equals (Point2D* other){
this->_type = other->_type;
this->_x = other->_x;
this->_y = other->_y;
}
private:
    double _x;
    double _y;
    PointType _type;
};

static double Point2D::segment(Point2D * a, Point2D * b) {
    return  (double)(abs(b->getX()-a->getX()) + abs(b->getY()-a->getY()));
}
/* returns the closest distance value pair  from an input points vector */
map * Point2D::closest(vector * points){
map * clst = NULL;
double da = 0, db = 0, m = 0;
Point2D* mp = NULL;
int i,j;

for(i=0;isize()-1;i++){
 da = Point2D::segment(this, points[i]);
 for(j=i+1;jsize();j++){
        db = Point2D::segment(this,points[j]);
        if(da<=db){
            m = da;
            mp = points[i];
        }else{
            m = db;
            mp = points[j];
        }
 }
}
 if(mp!=NULL){
    clst = new map();
    clst->insert(make_pair(m,mp));
 }
 return ( clst );
}

class Node {
public:
    Node(string name, double cost, int x, int y, long position, vector & values);
    ~Node();
    virtual double segment(Node* n, int atPointIdx);
    void setPosition(long pos) { this->_position = pos;}
    void setCost(double c) { this->_cost = c; }
    long getPosition() { return this->_position;}
    double getCost() { return this->_cost;}
    string getName() { return this->_name; }
    int getX() { return this->_x;}
    int getY() { return this->_y; }
    int getNextPointIdx();
    int getCurrentPointIdx() { return this->_currentPointIdx; }
    void setCurrentPointIdx(int v) { this->_currentPointIdx = v;}
    Point2D* getBPoint2D();
    Point2D * getPoint2D(int idx);
    void setUpMoveIdx(int v) { this->_currentUpMoveIdx = v; }
    void setBackMoveIdx(int v) { this->_currentBackMoveIdx = v; }
    void setFwdMoveIdx(int v){ this->_currentFwdMoveIdx = v; }
    int getUpMoveIdx(){ return this->_currentUpMoveIdx; }
    int getBackMoveIdx() { return this->_currentBackMoveIdx; }
    int getFwdMoveIdx(){ return this->_currentFwdMoveIdx; }
    vector & getValues() { return this->_values;}
    void setValues(vector & values) { this->_values = values;}
    static Node* copyNode(Node* fromNode);
    Point2D* getIntersection(Node* target);
    void computeMinPath(Node* toNode); /* this  and toNode have to have at least one boundary Point2D in common else returns NULL*/
    vector & getMinPath() { return this->_lastMinPath; }
    vector getMinCost() { return this->_lastMinCost; }
private:
    string _name;
    double _cost;
    vector _lastMinPath;
    vector _lastMinCost;
    int _x;
    int _y;
    long _position;
    int _currentPointIdx = 0;
    int _currentUpMoveIdx = 0;
    int _currentBackMoveIdx = 0;
    int _currentFwdMoveIdx = 0;
    vector _values;
};

Node::Node(string name, double cost, int x, int y, long position, vector & values) {
    this->_name = name; this->_cost = cost; this->_x= x; this->_y = y;
    this->_position = position;
    this->_values =  values;
}

static Node* Node::copyNode(Node* fromNode) {

Node * cpy = new Node(fromNode->getName(), fromNode->getCost(), fromNode->getX(), fromNode->getY(), fromNode->getPosition(), fromNode->getValues());

    cpy->setCurrentPointIdx(fromNode->getCurrentPointIdx());
    cpy->setCurrentUpMoveIdx(fromNode->getCurrentUpMoveIdx());
    cpy->setCurrentBackMoveIdx(fromNode->getCurrentBackMoveIdx());
    cpy->setCurrentFwdMoveIdx(fromNode->getCurrentFwdMoveIdx());

  return cpy;
}

int Node::getNextPointIdx() {

int next = this->_currentPointIdx +1;

if(next>=this->_values.size())
    next = -1;

 this->_currentPointIdx = next;

return this->_currentPointIdx;

}
Point2D * Node::getPoint2D(int idx){
Point2D * n =  NULL;
if(idx>=0 && idx_values.size())
    n = (Point2D *)this->values.at(idx);

    return n;
}
/* returns current indexed point if it is boundary or next boundary point */
Point2D* Node::getBPoint2D() {

    Point2D* bdry = NULL;
    int i = this->getCurrentPointIdx();
    int j = 0;
    while(i_values.size()){
        j = i % this->_values.size();
        Point2D* c = (Point2D*)(this->_values[j])->getType();
        if( c == PointType.B){
            bdry = c;
            break;
        }
        i++;
    }
   // this->setCurrentPointIdx(j);

    return bdry;
}
double Node::segment(int fromAtPointIdx, Node* to, int toAtPointIdx){
Point2D * from = this->getPoint2D(fromAtPointIdx);
Point2D * to = n->getPoint2D(toAtPointIdx);

    return Point2D::segment(from, to);

}

Point2D* Node::getIntersection(Node* from){

Point2D* intersec = NULL;
Point2D* cv = NULL;
Point2D* cf = NULL;
vector fv = from->getValues();

for(int i=0;i_values.size();i++){
    cv = this->_values[i];
    for(int j=0;jgetType() == PointType.B && cv->equals(cf)){
            intersec = cv;
            break;
        }
    }
}

 return intersec;

}
/* verifies if nodes are adjacent if true computes minimum path in current node to reach that boundary point */
void  Node::computeMinPath(Node* toNode){

vector * middles = new vector();
vector * segments = new vector();
map currentMinv = NULL;
mapgetBPoint2D();
Point2D* itsec = this->getIntersection(toNode);
if(startp!=NULL && itsec!=NULL &&
    !startp->equals(itsec)){

    middles = this->getMiddles();


}


}

class Maze {
public:
    Maze();
    Maze(int height, int legth, double scale);
    ~Maze();
    map*> * getData();
    vector* getRow(int rowNum);
    double getScale() { return this->_scale;}
    void setScale(double s) { this->_scale = s;}
    virtual int addNode(int x, int y, Node * node);
    virtual Node* getNode(int x, int y);
    virtual int getCurrentX();
    virtual int getCurrentY();
    virtual int getLevel();
    virtual int deleteNode(int x, int y);
    virtual void setNodeNumber(int x, int y, long nn);
    virtual long incNodeNumber(int delta);
    virtual long decNodeNumber(int delta);
    virtual Node* moveUp(Node* fromNode);
    virtual Node* moveFwd(Node* fromNode);
    virtual Node* moveBack(Node* fromNode);
    virtual Node* traverse(Node* innode, Node* tonode); /* returns a solution node from innode that contains optimized path to tonode*/
    virtual double computeMaxCost(Node* from, Node* to);
    virtual double computeMinCost(Node* from, Node* to);

private:
    map *> * _data;
    double _scale;
    int _level;
    int _currentX;
    int _currentY;
    long _nodeNumber;
    int _height;
    int _legth;
    const static vector * _fwdMoves = {new Point2D(0,1), new Point2D(1,0)};
    const static vector * _upMoves = {new Point2D(-1,0)};
    const static vector * _backMoves = { new Point2D(0,-1)};
};

Maze::Maze() {
    this->Maze(4,4,1);
}

Maze::Maze(int h, int l, double scale){
this->_scale = scale;
this->_level = 0;
this->_currentX = 0;
this->_currentY = 0;
this->_nodeNumber = 0;

 this->_height = h; this->length= l;

 map*>* d = new map*>(this->_height);
 vector * v;

 for(int i = 0;i_height;i++){
        v = new vector(NULL,this->_legth)
        d[i] = v;
 }

 this->_data = d;

}

Maze::~Maze(){
    delete this->_data;
}

map*> * Maze::getData() {
    return this->_data;
}

vector* Maze::getRow(int rownum) {
    return this->_data[rownum];
}
Node* Maze::getNode(int x, int y) {
    return this->_data[x][y];
}
int Maze::addNode(int x, int y , Node* n){
    this->_data[x][y] = n;
    return 0;
}

int Maze::deleteNode(int x, int y) {
    this->_data[x][y] = NULL;
    return 0;
}

int Maze::setNodeNumber(int x, int y, log nn) {
 Node * n  = this->getNode(x,y);
 if(n!=NULL){
    n->setPosition(nn);
    return 0;
 }
 return -1;
}

double Maze::computeMaxCost(Node* f, Node* t) {
Point2D * maxIntersecPoint = NULL;
Point2D * from = new Point2D(f->getX(),f->getY());
Point2D * to = new Point2D(t->getX(), t->getY());
/* intersection right to left and bottom to up */
maxIntersecPoint = new Point2D(to->getX(), from->getY());


return ( Point2D::segment(from, maxIntersecPoint) + Point2D::segment(maxIntersecPoint, to) +2 ) / this->_scale;


}

double Maze::computeMinCost(Node* f, Node* t){

Point2D * from = new Point2D(f->getX(),f->getY());
Point2D * to = new Point2D(t->getX(), t->getY());


return ( Point2D::segment(from, to)  + sqrt(2) / this->_scale;


}
class Solution:public Maze {
public:
    Solution();
    ~Solution();
    virtual vector* getOptSol();
    double getOptimalCost();
    vector* getCosts();
    void setCosts(vector * costs);
    void setOptSolIndex(int idx);
    double getOptCost();
private:
    vector * _costs
    int _optSolIndex;


};


class Backtracking {
public:
    Backtracking(Maze * maze);
    ~Backtracking();
    virtual int compute();
    virtual void accept(Visitor * v);
    virtual Solution * getSolution();
    virtual bool isSolution(int level);
    virtual bool criteria(int level, Node* n);
    virtual Node* computeNext(int level);
    virtual bool hasSibbling(int level);
    virtual int computeBack(int fromLevel);
    virtual bool isFinished(int level);
    virtual void setCurrentPoint(int x, int y);
    virtual setTargetPoint(int x, int y);
    virtual computeMaxTCost();
    virtual computeMinTCost();
private:
    long _totalNodes;
    long _numberOfNodes = 10000;
    double _minTotalCost = 100000;
    double _maxTotalCost = 0;
    int _currentLevel;
    Point2D _currentPoint = new Point2D(0,0);
    Point2D _targetPoint = NULL;
    bool isEnd = false;
    int _globalIterations = 0;
    Maze * _maze;
    Solution * _solution;
    Node* _tempNode;
    cons static _MAXITERATIONS = 10 * _numberOfNodes;
    Visitor * _visitor;
};



class PathFinder: public Backtracking {
public:
    PathFinder(Maze * maze):Backtracking(maze) {}
    void accept(Visitor * v);

private:

};

PathFinder::~PathFinder() { delete this->_maze; delete this->_solution;}

int PathFinder::compute(){
Node* solNode = NULL;
int status =  0;
this->_currentLevel = 0;

this->_tempNode = this->_maze->getNode(0,0);
if(this->_tempNode!=NULL){

 this->_solution->addNode(_tempNode->getCurrentX(),_tempNode->getCurrentY(),_tempNode);
    solNode = this->computeNext(this->_currentLevel);

    this->_totalNodes = 1;

    while(!isEnd && !isFinished(this->_currentLevel)){

        if(isSolution(this->_currentLevel)){
            isEnd = true;
        }else if(criteria(this->_currentLevel, solNode)){
            this->_solution->addNode(solNode->getCurrentX(),solNode->getCurrentY(),solNode);
            this->_tempNode = solNode;
            this->_currentLevel++;
            solNode = this->computeNext(this->_currentLevel);

        }else if(hasSibbling(this->_currentLevel)){

            solNode = this->computeNext(this->_currentLevel);
        }else {

            while(!hasSibbling(this->_currentLevel && !isFinished(this->_currentLevel))){
                this->_currentLevel = this->computeBack(_this->currentLevel);
            }
            if(!isFinished(this->_currentLevel)){
                solNode = this->computeNext(this->_currentLevel);
            }else   status = -100; /* no solution found */
        }


    }


}


return status;

}
void PathFinder::accept(Visitor * v){
        this->_visitor = v;
        this->_visitor->visit(this);
}

Solution * PathFinder::getSolution() {}
bool PathFinder::criteria(int level){}
Node* PathFinder::computeNext(int level){}
bool PathFinder::hasSibbling(int level){}
int PathFinder::computeBack(int fromLevel){}
bool PathFinder::isFinished(int level){}



#endif // PATHFINDER_H_INCLUDED

Getting results (visitor pattern): "visitor.h"

#ifndef VISITOR_H_INCLUDED
#define VISITOR_H_INCLUDED
#include "pathfinder.h"
#include 


class SolutionDisplay {
public:
    SolutionDisplay(Solution * sol);
    ~SolutionDisplay();
    virtual void print();
private:
    Solution * _solution;
};



class Visitor {
public:
    Visitor();
    ~Visitor();
    virtual void visit(Backtracking * b)
    virtual void printSolution();
    virtual vector* getSolution();
    virtual double getCost();
private:
    Solution * _solution;
    SolutionDisplay * _solutionDis;
};

void Visitor::printSolution(){
    this->_solutionDis = new SolutionDisplay(this->_solution);
    this->_solutionDis->print();
}


class PathFinderVisitor: public Visitor {
public:
        PathFinderVisitor();
        ~PathFinderVisitor();

private:

};

void PathFinderVisitor::visit(Backtracking * backtracking) {

    if(!backtracking->compute())
        this->_solution = backtracking->getSolution();

}

#endif // VISITOR_H_INCLUDED

jueves, 18 de enero de 2018

Southwind : Gof Patterns example of Template method and Strategy patterns

Southwind C++ (codeblocks ide) project for GoF patterns practicing. It takes as example a possible template method from the trader company "Southwind" and the use of 2 different Strategies (Kanban and JustInTime).

Files in project:

main.cpp

:
#include 
#include "templatemethod.h"
#include 

using namespace std;

int main()
{
 const static vector * catalog = {"Tablets offer", "SmartPhones offer", "Javas offer", "Androids offer", "Creatives offer"};
 const static vector  * locations = {"KanbanCity","JustInTimeCity"};

  int status = -1;
  map> * tradingdata;
  Strategy * strategy = NULL;
  Context* context = NULL;
  TraderCompany* southwind = NULL;


  vector * preorder = createPreOrder(catalog);
  string* location = getLocation(locations);

  if(location->compare(locations->at(0))== 0))
   /* we work with Kanban city */
    strategy = new KanbanStrategy();
   else
    strategy = new JustinStrategy();

   context = new Context(strategy);


   southwind = new Southwind(context);
   /* call to the template method */
   status = southwind->trade(preorder);


   tradingdata = southwind->getTraderdata();


   return status;






}



vector* createPreOrder(vector* catalog) {

 vector * selecteds(-1,5);
 vector * preOrder ;

 vector::iterator it = catalog->begin();
 int i = 1;
 int j = 0;
 bool exit = false;

 cout << "Welcome to Southwind company please choose our offers : ";
 cout << endl << endl;
 cout << "Catalog :" << endl;
 while(it!= catalog->end()) {
    cout << "Number: " << i << " " << "Product: " << *it << "  " << endl;
    it++;
    i++;
 }

i = 100;
cout << "Choose your offers : (input correct offer's number (1-" << catalog->size() << ") or 0 number for exit) " << endl;

while(i!= 0 && !exit){
cout << "Offer's number: " << endl;
 cin >> i;

 if(i>0 && i< catalog->size())
    selecteds->push_back( i--);
 else{
    j++;
    cout << " Input number is incorrect (1-6)" << endl;
    i = 100;
   if(j==10){
    cout << "Too many incorrect input, exiting..." << endl;
    exit = true;
   }

 }

 it = selecteds->begin();
 while(it!= selecteds->end()){
    preOrder->push_back( catalog[ *(it++)]);

 }

    return preOrder;
}

string * getLocation( vector* locations) {


 string * loc;

 vector::iterator it = locations->begin();
 int i = 1;
 int j = 0;
 int k = 0;

 cout << "Welcome to Southwind, this are the possible locations:";
 cout << endl << endl;
 cout << "Location :" << endl;
 while(it!= locations->end()) {
    cout << "Number: " << i << " " << "Location : " << *it << "  " << endl;
    it++;
    i++;
 }

i = 100;

cout << "Choose your location : (input correct location's number (1-" << locations->size() << ") or 0 number for exit) " << endl;


while(i!= 0 && k>1){
cout<< "Location's number: " << endl;
 cin >> i;

 if(i>0 && i< locations->size()){
    selecteds->push_back( i--);
    k++;
 }
 else{
    j++;
    cout << " Input number is incorrect (1-" << localtions->size() << ")" << endl;
    i = 100;
   if(j==10){
    cout << "Too many incorrect input, exiting..." << endl;
    exit = true;
   }

 }

}

 it = selecteds->begin();
 while(it!= selecteds->end())
    *loc  =   locations[ *(it++)]);


    return loc;

}








templatemethod.h

: It contains template method implementation and strategy pattern dependency.
#ifndef TEMPLATEMETHOD_H_INCLUDED
#define TEMPLATEMETHOD_H_INCLUDED

#include 
#include 
#include "strategy.h"
#include 
#include 


/**
Southwind trading company

*/

typedef map> TradeData;

class TraderCompany {
public:
    TraderCompany(Context* c);
    ~TraderCompany();
    int trade(vector* preorder);
    virtual int takeOrder();
    virtual int prepareOrder();
    virtual int computePrice();
    virtual int doShipping();
    virtual int doConfirm();
    map>* getTraderdata();
    int doReport();
private:
    Context* _context;
    map>  * _tradedata;
    vector _preorder;
};

TraderCompany::TraderCompany(Context* c){
    this->_context = c;
}
int TraderCompany::trade(vector * preorder) {
    this->_preorder = preorder;
    this->takeOrder();
    this->prepareOrder();
    this->computePrice();
    this->doShipping();

    return this->doConfirm();

}
int TraderCompany::doConfirm() {
    cout << " Operation confirm!!";
    return this->doReport();
}
map>* TraderCompany::getTraderdata() {
    return this->_tradedata;
}

class Southwind: public TraderCompany {
public:
    Southwind(Context * c);
    ~Southwind();
    int trade(vector * preorder);
    virtual int takeOrder();
    virtual int prepareOrder();
    virtual int computePrice();
    virtual int doShipping();
    virtual int doConfirm();
    int doReport();
private:
    Context* _context;
    map>  * _tradedata;
    vector * _preorder;
};


#endif // TEMPLATEMETHOD_H_INCLUDED

strategy.h

: specific strategies to be implemented
#ifndef STRATEGY_H_INCLUDED
#define STRATEGY_H_INCLUDED
#include 
#include 
#include 
#include 

using namespace std;

typedef map> * TradeData;

class Strategy {
public:
 Strategy();
 ~Strategy();
 virtual int create(vector * input);
 virtual int prepare();
 virtual int ship();
 virtual int confirm();
 map> * getData();
private:
    map> * _data;
};


class JustinStrategy: public Strategy {

};

class KanbanStrategy: public Strategy {


};


class Context {
public:
    Context(Strategy * s);
    ~Context();
    virtual int createOrder(vector * input);
    virtual int prepareOrder();
    virtual int ship();
    virtual int confirm();
    map> * getOrder();
private:
    Strategy * _strategy;
    map>* _order;

};



#endif // STRATEGY_H_INCLUDED

Download project from Github

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

domingo, 3 de diciembre de 2017

Design by contract (Software engineering, Bertrand Meyer)

Software engineering (by Restless Aficionados)

1. Design by contract

As object-oriented techniques steadily gain ground in the world of software development. users and prospective users of these techniques are clamof object-oriented or more and more loudly for a “methodology” software construction - or at least for some methodological guidelines.

This article presents such guidelines, whose main goal is to help improve the reliability of software systems. Reliability is here defined as the combination of correctness and robustness or more prosaically, as the absence of bugs.

Everyone developing software systems. or just using them, knows how pressing this question of reliability is in the current state of software engineering. Yet the rapidly growing literature on object-oriented analysis, design, and programming includes remarkably few contributions on how to make object-oriented software more reliable. This is surprising and regrettable, since at least three reasons justify devoting particular attention to reliability in the context of object-oriented development:
The cornerstone of object-oriented technology is reuse. For reusable components, which may be used in thousands of different applications, the potential consequences of incorrect behavior are even more serious than for application specific developments.
Proponents of object-oriented methods make strong claims about their beneficial effect on software quality. Reliabitity is certainly a central component of any reasonable definition of quality as applied to software.
*The object-oriented approach, based on the theory of abstract data types, provides a particularly appropriate framework for discussing and enforcing reliability.
Reliability is even more important in object-oriented programming than elsewhere. This article shows how to reduce bugs by building software components on the basis of carefully designed contracts.

The pragmatic techniques presented in this article, while certainly not providing infallible ways to guarantee reliability, may help considerably toward this goal. They rely on the theory of design by contract. which underlies the design of the Eiffel analysis, design, and programming language’ and of the supporting libraries, from which a number of examples will be drawn.

The contributions of the work reported below include a coherent set of methodological principles helping to produce correct and robust software; a systematic approach to the delicate problem of how to deal with abnormal cases. leading to a simple and powerful exception-handling mechanism; and *a better understanding of inheritance and of the associated techniques (redeclaration, polymorphism, and dynamic binding) through the notion of subcontract, allowing a systematic approach to using these powerful but sometimes dangerous mechanisms.

Most of the concepts presented here have appeared elsewhere. They were previewed in the book “Object-Oriented Software Construction”; and a more complete exposition was presented in a recent book chapter,”from which this article has been adapted”. More profoundly, this work finds its root in earlier work on systematic program development and abstract data types. This article focuses on the central ideas, introducing them concisely for direct application by developers.

1.1. Defensive programming

1.2. The notion of contract

1.3. Assertions:Contracting for software

1.4. The role of assertions

1.5. Further sources

1.6. Observations on software contracts

1.7. Who should check?

1.8. Class invariants

1.9. On the assertion language

1.10. Documenting a software contract

1.11. Monitoring assertions

1.12. Why monitor?

1.13. Introducing inheritance

1.14. The concurrency issue

1.15. Invariants and dynamic binding

1.16. Dealing with abnormal situations

1.17.A disciplined exception-handling mechanism

1.18. Status of Eiffel

1.19. Acknowledgments

2. References

B. Meyer. “Design by Contract.” in Advances in Object-Oriented Software Engineering, D. Mandrioli and B. Meyer.eds.. Prentice Hall. Englewnod Cliffs, N.J.. 1991. pp. I-SO.