//
Purpose. Lots of client effort to
manage a list of Processors
public class ChainBefore {
interface
Image { String process(); }
static class IR implements Image { public
String process() { return "IR"; } }
static class LS implements
Image { public String process() { return "LS"; } }
static
class Processor {
private static
java.util.Random rn = new java.util.Random();
private static int nextId = 1;
private int id = nextId++;
public boolean handle( Image img ) {
if (rn.nextInt(2) != 0) {
System.out.println( " Processor " + id + " is
busy" );
return
false;
}
System.out.println( "Processor
" + id + " - " + img.process() );
return true;
} }
public static void main(
String[] args ) {
Image[] input
= { new IR(), new IR(), new LS(), new IR(), new LS(), new LS() };
Processor[] procs = { new Processor(), new
Processor(), new Processor() };
for (int i=0, j; i < input.length; i++) {
j = 0;
while ( ! procs[j].handle( input[i] ))
j = (j+1) % procs.length;
} }}
// Processor 1 - IR
// Processor 1 is busy
// Processor 2 is busy
// Processor 3 is busy
// Processor 1 is busy
// Processor 2 is busy
// Processor 3 -
IR
// Processor 1 is busy
//
Processor 2 - LS
// Processor 1 - IR
// Processor 1 - LS
// Processor 1 is busy
// Processor 2 is busy
// Processor 3 is busy
// Processor 1 -
LS
// Purpose.
Chain of Responsibility design pattern
public class
ChainAfter {
interface Image { String process(); }
static class
IR implements Image { public String process() { return "IR"; }
}
static class LS implements Image { public String process() { return
"LS"; } }
static class Processor {
private static java.util.Random rn = new
java.util.Random();
private
static int nextId = 1;
private
int id = nextId++;
private Processor next;
public void add( Processor nextP ) {
if (next != null) next.add( nextP
);
else next = nextP;
}
public void wrapAround( Processor firstP ) {
if (next != null) next.wrapAround(
firstP );
else next =
firstP;
}
public void handle( Image img ) {
if (rn.nextInt(2) != 0) {
System.out.println( " Processor " + id + " is
busy" );
next.handle(
img );
} else
System.out.println( "Processor
" + id + " - " + img.process() );
} }
static public Processor setUp()
{
Processor root = new
Processor();
for (int i=0; i
< 2; i++) root.add( new Processor() );
root.wrapAround( root );
return root;
}
public static void main( String[] args )
{
Image[] input = { new IR(),
new IR(), new LS(), new IR(), new LS(), new LS() };
Processor chain = setUp();
for (int i=0; i < input.length;
i++)
chain.handle( input[i]
);
}}
// Processor 1
is busy
// Processor 2 is
busy
// Processor 3 is
busy
// Processor 1 - IR
// Processor 1 - IR
// Processor 1 is busy
// Processor 2 -
LS
// Processor 1 - IR
//
Processor 1 is busy
//
Processor 2 is busy
// Processor 3 - LS
// Processor 1 is busy
// Processor 2 is busy
// Processor 3 -
LS
// 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
abstract
class Component {
private
int value;
private Component next; // 1. "next" pointer in
the base class
public Component(
int v ) { this( v, null );
}
public Component( int v,
Component n ) { value = v; next = n;
}
public void setNext( Component
n ) { next = n; }
public void traverse() { System.out.print( value +
" " ); }
// 2. The
"chain" method in the base class always delegates to the next
obj
public void volunteer() { next.volunteer(); }
}
class
Primitive extends Component {
public Primitive( int val )
{ this( val, null ); }
public Primitive( int val, Component n ) { super( val, n ); }
public void volunteer() {
super.traverse();
// 3. Primitive objects don't handle
volunteer requests 5 times out of 6
if ((int)(Math.random()*100) % 6 != 0)
// 3. Delegate to the base class
super.volunteer();
} }
class Composite extends
Component {
private Component[]
children = new Component[9];
private int total = 0;
public Composite( int val ) { this( val, null ); }
public Composite( int val, Component n ) {
super( val, n ); }
public void
add( Component c ) {
children[total++] = c; }
public
void traverse() {
super.traverse(); // 1
for (int i=0; i < total; i++) // |
children[i].traverse(); // +-- 2
} // | |
// 3. Composite objects never handle volunteer // | +-- 4 5
public void volunteer() { // requests // |
super.volunteer(); // +-- 3
} } // | |
// | +-- 6 7
public class ChainDemo { // |
public static void main( String[] args )
{ // +-- 8 9
Component seven = new Primitive( 7
); //
Component six = new Primitive( 6, seven );
// tra: 1 2 4 5 3 6 7 8 9
Composite three = new Composite( 3, six ); // 4
three.add( six ); three.add(
seven ); // 4 5 6 7
Component five = new
Primitive( 5, three ); // 4 5 6 7 8
9
Component four = new Primitive( 4, five ); // 4 5 6 7 8
Composite two = new Composite( 2, four );
// 4 5 6 7
two.add(
four ); two.add( five ); // 4 5 6 7 8 9 4 5 6 7
Composite one = new Composite( 1, two );
// 4
Component
nine = new Primitive( 9, one ); // 4 5 6 7 8 9 4 5 6 7 8
Component eight = new Primitive( 8, nine
);
one.add( two ); one.add( three ); one.add( eight );
one.add( nine );
seven.setNext( eight );
System.out.print( "tra: " );
one.traverse();
System.out.println();
for (int i=0; i < 8; i++) {
one.volunteer();
System.out.println();
}
} }
//
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
public class ChainBidDemo {
static class Link {
private int id;
private
Link next; // 1.
"next" pointer
private static int theBid =
999; // 4. Current bid and
bidder
private static Link
bidder;
public Link(
int num ) {
id =
num;
}
public void addLast( Link l ) {
if (next != null) next.addLast( l
); // 2. Handle and/or pass on
else next = l;
}
public void bid()
{
int num =
((int)(Math.random() * 100)) % 9;
System.out.print( id + "-" + num + " " );
if (num < theBid) {
theBid = num; // 4. Current bid and bidder
bidder = this;
}
if (next != null) next.bid(); // 2. Handle and/or pass on
else bidder.execute();
// 5. The last 1 assigns the job
}
public
void execute() {
System.out.println( id + " is executing" );
theBid = 999;
}
}
static Link
setUpChain() {
Link first =
new Link( 1 );
for (int i=2;
i < 7; i++)
first.addLast( new Link( i ) );
return first;
}
public static
void main( String[] args ) {
Link chain = setUpChain();
for (int 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
//
Purpose. The number to be factored is
passed through a chain of Factor-
// Elements until none of them is able
to decompose the number any further.
import java.io.*;
public
class ChainContrib {
static class Memento {
private boolean[] done;
private int sp = 0;
private int[] factors = new int[10];
public Memento( int num ) {
done = new boolean[num]; }
public void add( int n ) {
factors[sp++] = n; }
public void
setDone( int i ) { done[i] = true; }
public boolean isDone() {
for (int i=0; i < done.length; i++) if ( ! done[i]) return
false;
return true;
}
public String toString() {
StringBuffer sb = new StringBuffer();
for (int i=0; i < sp; i++) { sb.append( factors[i] ); sb.append( ' ' ); }
sp = 0;
for (int i=0; i < done.length; i++) done[i] = false;
return sb.toString();
} }
static class FactorElement
{
private int index, divisor;
private
FactorElement next;
private static Memento
mem;
public
FactorElement( int i, int d, FactorElement fe ) {
index = i; divisor = d; next =
fe;
}
public void setNext( FactorElement fe ) { next = fe; }
public String getResults() { return mem.toString();
}
public void getFactors( int[]
num ) {
if (num[0] % divisor
== 0) {
mem.add( divisor
);
num[0] = num[0] /
divisor;
} else
mem.setDone( index );
if ( ! mem.isDone())
next.getFactors( num );
}
public static FactorElement setUp() {
int[] divisors = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31,
37, 41, 43, 47 };
int size =
divisors.length;
mem = new
Memento( size );
FactorElement last = new FactorElement( size-1, divisors[size-1], null
);
FactorElement current =
last;
for (int i=size-2; i
> -1; i--)
current =
new FactorElement( i, divisors[i], current );
last.setNext( current );
return current;
}
}
public static void main( String[] args ) throws IOException
{
BufferedReader rdr = new
BufferedReader( new InputStreamReader( System.in ));
int[] num = new int[1];
String str;
FactorElement root = FactorElement.setUp();
while (true) {
System.out.print( "Enter number: " );
str = rdr.readLine();
if (str.equals("0"))
break;
num[0] =
Integer.parseInt( str );
root.getFactors( num );
System.out.println( "
" + root.getResults() + "- " + num[0] );
} }}
// Enter number: 30
// 2 3 5 - 1
// Enter number: 31
// 31 - 1
// Enter number: 32
// 2 2 2 2 2 - 1
// Enter number:
127
// - 127
// Enter
number: 60
// 2 3 5 2 - 1
//
Enter number: 180
// 2 3 5 2 3 -
1
// Enter number: 216
// 2
3 2 3 2 3 - 1
// Enter number: 2310
// 2 3 5 7 11 - 1
// Enter number: 4620
// 2 3 5 7 11 2 - 1
// Enter number:
13860
// 2 3 5 7 11 2 3 -
1
// Enter number: 0