//
Purpose. Chain of Responsibility. #include <iostream.h>
//
//
Discussion. Instead of the client class H {
// having to know about the
number of public:
//
"handlers", and manually map re- H( H* next = 0 ) {
// quests to available handlers;
de- id_ = count_++;
// sign the handlers into
an "intel- busy_ =
0;
// ligent" chain. Clients
"launch next_ =
next;
// and leave" requests with the head }
// of the chain. ~H() {
cout << id_<<"
dtor" << endl;
#include <iostream.h> // don't get into a
loop
if (next_->next_)
{
class H { H* t = next_;
public:
next_ = 0;
H() {
delete t;
id_ =
count_++; } }
busy_ = 0;
void setNext( H* next ) {
} next_ =
next;
~H() { }
cout << id_ << "
dtor" << endl; void
handle() {
} if
(busy_ = ! busy_)
int handle()
{ cout
<< id_ << " handles"
if (busy_ = ! busy_) { << endl;
cout << id_ << "
handles" else {
<< endl; cout << id_
<< " is busy"
return 1; << endl;
} else { next_->handle();
cout << id_ << " is
busy" } }
<< endl; private:
return 0; int
id_, busy_;
} } H* next_;
private: static int count_;
int
id_, busy_;
};
static int
count_; int H::count_
= 1;
};
int H::count_ = 1; H* setUpList() {
H*
first = new H;
void main( void ) { H* last = new H(first);
const int TOTAL = 2; first->setNext( last
);
H* list[TOTAL] = { new H, new
H }; return first;
}
for (int i=0; i < 6;
i++)
for (int j=0; 1 ; void main( void ) {
j = (j + 1) % TOTAL) H* head = setUpList();
if (list[j]->handle())
break; for (int i=0; i < 6; i++)
head->handle();
for
(int k=0; k < TOTAL; k++)
delete list[k];
delete head;
} }
// 1
handles // 1
handles
// 1 is busy // 1 is busy
// 2 handles // 2 handles
//
1 handles //
1 handles
// 1 is busy
// 1 is busy
// 2 is
busy // 2 is
busy
// 1 handles // 1 handles
// 1 is busy // 1 is busy
//
2 handles //
2 handles
// 1 handles // 1 handles
// 1 dtor // 1 dtor
//
2 dtor //
2 dtor
// Purpose. Chain of Responsibility design pattern
// 1. Put a
"next" pointer in the base class
// 2. The "chain"
method in the base class always delegates to the next object
// 3. If the
derived classes cannot handle, they delegate to the base class
#include
<iostream>
#include <vector>
#include <ctime>
using
namespace std;
class Base {
Base* next; // 1.
"next" pointer in the base class
public:
Base() { next = 0; }
void setNext( Base* n ) { next = n; }
void add( Base* n ) { if (next)
next->add( n ); else next = n; }
// 2. The "chain" method in the base class always delegates to
the next obj
virtual void handle( int i ) {
next->handle( i ); }
};
class Handler1 : public Base {
public:
/*virtual*/ void handle(
int i ) {
if (rand() % 3)
{ // 3. Don't handle requests 3
times out of 4
cout
<< "H1 passsed " << i << " ";
Base::handle( i );
// 3. Delegate to the base class
} else
cout << "H1 handled " << i << " ";
} };
class Handler2 : public Base { public:
/*virtual*/ void handle( int i ) {
if (rand() % 3) { cout << "H2
passsed " << i << "
"; Base::handle( i ); }
else cout << "H2 handled " << i <<
" ";
} };
class Handler3 : public Base {
public:
/*virtual*/ void handle(
int i ) {
if (rand() % 3) {
cout << "H3 passsed " << i << " "; Base::handle( i ); }
else cout << "H3 handled
" << i << "
";
} };
void
main( void ) {
srand( time( 0 )
);
Handler1 root; Handler2 two; Handler3 thr;
root.add( &two ); root.add(
&thr );
thr.setNext(
&root );
for (int i=1; i
< 10; i++) {
root.handle(
i ); cout << '\n';
} }
// H1 passsed 1 H2 passsed 1 H3 passsed 1 H1 passsed
1 H2 handled 1
// H1 handled
2
// H1 handled 3
// H1 passsed 4
H2 passsed 4 H3 handled 4
//
H1 passsed 5 H2 handled 5
// H1
passsed 6 H2 passsed 6 H3 passsed 6 H1 handled 6
// H1 passsed 7 H2 passsed 7 H3 passsed
7 H1 passsed 7 H2 handled 7
// H1 handled 8
// H1
passsed 9 H2 passsed 9 H3 handled 9
//
Purpose. Chain of Responsibility and
Composite
// 1. Put a "next" pointer in the base
class
// 2. The "chain" method in the base class always
delegates to the next object
// 3. If the derived classes cannot handle,
they delegate to the base class
#include <iostream>
#include
<vector>
#include <ctime>
using namespace std;
class
Component {
int value;
Component* next;
// 1. "next" pointer in the base class
public:
Component( int v, Component* n ) { value =
v; next = n; }
void setNext( Component* n ) { next = n; }
virtual void traverse() { cout << value << ' ';
}
// 2. The "chain"
method in the base class always delegates to the next obj
virtual void volunteer() { next->volunteer(); }
};
class
Primitive : public Component { public:
Primitive( int val, Component* n = 0 ) : Component( val, n ) { }
/*virtual*/ void volunteer() {
Component::traverse();
// 3. Primitive objects don't handle
volunteer requests 5 times out of 6
if (rand() * 100 % 6 != 0)
// 3. Delegate to the base class
Component::volunteer();
} };
class Composite : public Component {
vector<Component*> children;
public:
Composite( int val, Component* n = 0 ) :
Component( val, n ) { }
void
add( Component* c ) { children.push_back( c ); }
/*virtual*/ void traverse() {
Component::traverse();
for (int i=0; i < children.size();
i++)
children[i]->traverse();
}
// 3. Composite objects
never handle volunteer requests
/*virtual*/ void volunteer() { Component::volunteer(); }
};
void
main( void ) {
srand( time( 0 )
); // 1
Primitive seven( 7 ); // |
Primitive six( 6, &seven ); // +-- 2
Composite three( 3, &six ); // |
|
three.add( &six
); three.add( &seven ); // |
+-- 4 5
Primitive five(
5, &three ); //
|
Primitive four( 4, &five
); // +-- 3
Composite two( 2, &four ); // | |
two.add( &four ); two.add(
&five ); // | +-- 6 7
Composite one( 1, &two ); // |
Primitive nine( 9, &one ); // +-- 8 9
Primitive eight( 8, &nine );
one.add( &two );
one.add( &three ); one.add(
&eight ); one.add( &nine );
seven.setNext( &eight );
cout << "traverse: "; one.traverse(); cout << '\n';
for (int i=0; i < 8; i++) {
one.volunteer(); cout
<< '\n';
} }
//
traverse: 1 2 4 5 3 6 7 8 9
// 4
// 4 5 6 7
// 4 5 6 7 8 9 4 5 6
7 8 9 4
// 4
// 4 5 6
// 4 5
// 4 5
// 4 5 6 7 8 9 4 5
6 7 8 9 4 5 6
// Purpose. Chain of Responsibility - links bid on job,
chain assigns job
//
// 1. Base class maintains a "next"
pointer
// 2. Each "link" does its part to handle (and/or pass
on) the request
// 3. Client "launches and leaves" each request
with the chain
// 4. The current bid and bidder are maintained in chain
static members
// 5. The last link in the chain assigns the job to the low
bidder
#include <iostream>
#include <ctime>
using
namespace std;
class Link {
int id;
Link* next; // 1. "next" pointer
static int theBid; //
4. Current bid and bidder
static
Link* bidder;
public:
Link(
int num ) { id = num; next = 0; }
void addLast( Link* l ) {
if (next) next->addLast( l ); // 2. Handle and/or pass on
else next = l;
}
void bid() {
int num = rand() % 9;
cout << id << '-' <<
num << " ";
if (num < theBid) {
theBid = num; // 4. Current bid and
bidder
bidder =
this;
}
if (next) next->bid(); // 2. Handle and/or pass on
else bidder->execute();
// 5. The last 1 assigns the job
}
void execute() {
cout << id << " is
executing\n";
theBid =
999;
} };
int Link::theBid = 999; // 4. Current bid and bidder
Link*
Link::bidder = 0;
void main( void ) {
Link chain( 1 );
for (int i=2; i < 7; i++)
chain.addLast( new Link( i ) );
srand( time( 0 ) );
for (i=0; i < 10; i++)
chain.bid(); // 3.
Client "launches & leaves"
}
// 1-1 2-6
3-0 4-3 5-1
6-0 3 is executing
//
1-1 2-1 3-1 4-0 5-7
6-1 4 is executing
//
1-0 2-1 3-0 4-6 5-1
6-2 1 is executing
//
1-6 2-3 3-8 4-0 5-1
6-4 4 is executing
//
1-8 2-0 3-5 4-8 5-4
6-2 2 is executing
//
1-1 2-0 3-8 4-8 5-7
6-0 2 is executing
//
1-1 2-1 3-3 4-1 5-6
6-2 1 is executing
//
1-2 2-1 3-0 4-3 5-6
6-8 3 is executing
//
1-7 2-5 3-4 4-2 5-1
6-2 5 is executing
//
1-3 2-6 3-7 4-7 5-6
6-0 6 is executing