//
Purpose. Builder class Builder { public:
//
virtual void addFront( char ) = 0;
// The monolithic design
supports a virtual void addBack(
char ) = 0;
// single representation.
The Builder virtual
Array& getResult() = 0;
//
design allows a different rep per
};
// Builder derived class, and the com-
// mon input and
parsing have been de- class BuilderOne
: public Builder {
// fined in the Director class. The D
public:
// constructs, the B returns result. void addFront( char ch ) {
one.lst.push_back( ch ); }
class Array { void addBack( char ch ) {
public:
one.lst.push_back( ch ); }
void addFront( char ch ) {
Array& getResult() {
lst.push_front( ch ); }
return one; }
void
addBack( char ch ) {
private:
lst.push_back( ch ); }
OneEnded one;
void traverse()
{ };
for (i=0; i < lst.size(); i++)
cout << lst[i] << '
'; class BuilderTwo : public
Builder {
cout << endl;
} public:
private: void
addFront( char ch ) {
deque<char> lst; int
i; two.lst.push_front(
ch ); }
}; void addBack( char ch )
{
two.lst.push_back( ch
); }
string in[] = { "fa", "bb", "fc", Array& getResult() {
"bd", "fe",
"bf", "fg", "bh" }; return two; }
private:
void main(
void ) { TwoEnded
two;
Array list; };
for (int i=0; i < 8; i++)
if (in[i][0] == 'f')
string in[] = { "fa", "bb", "fc",
list.addFront( in[i][1] ); "bd", "fe",
"bf", "fg", "bh" };
else if (in[i][0] == 'b')
list.addBack( in[i][1] ); class Director {
list.traverse(); }
public:
Director( Builder* b )
{
// g e c a b d f h setBuilder( b ); }
void setBuilder( Builder* b ) {
///////////////////\\\\\\\\\\\\\\\\\\\ bldr = b; }
void construct() {
class Array { public: for (int i=0; i < 8; i++)
virtual void traverse() = 0; if (in[i][0] == 'f')
};
bldr->addFront(in[i][1]);
else if (in[i][0]
== 'b')
class OneEnded : public Array { bldr->addBack(in[i][1]);
public: }
friend class BuilderOne; private:
void traverse() { Builder* bldr;
for (i=0; i < lst.size(); i++) };
cout << lst[i] << ' ';
cout << endl; } void main( void ) {
private: BuilderOne
one;
vector<char>
lst; int i; BuilderTwo two;
}; Director dir( &one
);
class TwoEnded : public Array { dir.construct();
public:
one.getResult().traverse();
friend class BuilderTwo;
dir.setBuilder( &two );
void traverse() {
dir.construct();
for
(i=0; i < lst.size(); i++)
two.getResult().traverse();
cout << lst[i] << ' '; }
cout << endl; }
private: // a b c d e f g h
deque<char> lst; int i; // g e c a b d f h
};
//
Purpose. Builder design pattern
demo.
//
// Discussion. The
forte of Builder is constructing a complex object step
// by step. An abstract base class declares the standard
construction
// process, and concrete derived classes define the
appropriate
// implementation for each step of the process. In this example,
// "distributed
work packages" have been abstracted to be persistent and
// platform
independent. This means that the
platform-specific mechanism
// for implementing files, queues, and
concurrency pathways is defined in
// each platform's concrete derived
class. A single "reader"
object (i.e.
// parser) retrieves the archived specification for a
DistrWorkPackage and
// proceeds to delegate each build step to the
builder object that was
// registered by the client. Upon completion, the client retrieves
the
// end result from the builder.
#include
<iostream.h>
#include <stdio.h>
#include
<string.h>
enum PersistenceType { File, Queue, Pathway
};
struct PersistenceAttribute {
PersistenceType
type;
char value[30];
};
class
DistrWorkPackage {
public:
DistrWorkPackage(
char* type ) {
sprintf( _desc, "Distributed
Work Package for: %s", type); }
void
setFile ( char* f, char* v ) {
sprintf(
_temp, "\n File(%s): %s", f,
v );
strcat( _desc,
_temp); }
void setQueue ( char* q, char* v ) {
sprintf(
_temp, "\n Queue(%s): %s", q,
v );
strcat( _desc,
_temp); }
void setPathway(
char* p, char* v ) {
sprintf( _temp, "\n Pathway(%s): %s", p, v );
strcat(_desc,_temp); }
const char* getState() { return _desc;
}
private:
char _desc[200], _temp[80];
};
class
Builder {
public:
virtual
void configureFile( char* ) =
0;
virtual void configureQueue(
char* ) = 0;
virtual void configurePathway( char* ) =
0;
DistrWorkPackage*
getResult() { return _result; }
protected:
DistrWorkPackage*
_result;
};
class
UnixBuilder : public Builder {
public:
UnixBuilder() { _result = new DistrWorkPackage(
"Unix" ); }
void
configureFile( char* name ) {
_result->setFile(
"flatFile", name ); }
void
configureQueue( char* queue ) {
_result->setQueue(
"FIFO", queue ); }
void
configurePathway( char* type ) {
_result->setPathway(
"thread", type ); }
};
class VmsBuilder : public
Builder {
public:
VmsBuilder()
{ _result = new DistrWorkPackage( "Vms" ); }
void configureFile( char* name ) {
_result->setFile(
"ISAM", name ); }
void
configureQueue( char* queue ) {
_result->setQueue(
"priority", queue ); }
void
configurePathway( char* type ) {
_result->setPathway(
"LWP", type ); }
};
class Reader {
public:
void setBuilder( Builder* b ) { _builder =
b; }
void construct(
PersistenceAttribute[], int );
private:
Builder* _builder;
};
void Reader::construct(
PersistenceAttribute list[], int num ) {
for
(int i=0; i < num; i++)
if
(list[i].type == File)
_builder->configureFile(
list[i].value );
else if
(list[i].type == Queue)
_builder->configureQueue(
list[i].value );
else if
(list[i].type == Pathway)
_builder->configurePathway(
list[i].value ); }
const int
NUM_ENTRIES = 6;
PersistenceAttribute input[NUM_ENTRIES] = { {File, "state.dat"},
{File,"config.sys"}, {Queue,
"compute"}, {Queue, "log"},
{Pathway, "authentication"}, {Pathway, "error
processing"} };
void main() {
UnixBuilder
unixBuilder;
VmsBuilder vmsBuilder;
Reader
reader;
reader.setBuilder(
&unixBuilder );
reader.construct(
input, NUM_ENTRIES );
cout
<< unixBuilder.getResult()->getState() << endl;
reader.setBuilder( &vmsBuilder
);
reader.construct( input,
NUM_ENTRIES );
cout <<
vmsBuilder.getResult()->getState() << endl;
}
//
Distributed Work Package for: Unix
//
File(flatFile): state.dat
//
File(flatFile): config.sys
//
Queue(FIFO): compute
//
Queue(FIFO): log
//
Pathway(thread): authentication
// Pathway(thread): error processing
// Distributed Work
Package for: Vms
// File(ISAM):
state.dat
// File(ISAM):
config.sys
// Queue(priority):
compute
// Queue(priority):
log
// Pathway(LWP):
authentication
// Pathway(LWP):
error processing