CS 696: Advanced OO
| Chain of Responsibility | slide # 1 |
| ...Intent | slide # 1 |
| ...When to Use | slide # 1 |
| ...Participants | slide # 3 |
| ...Implementation Issues | slide # 4 |
| Interpreter | slide # 7 |
| ...Consequences | slide # 10 |
| ...Implementation | slide # 10 |
When you want to issue a request to one of several objects without specifying the receiver explicitly
When the set of objects that can handle a request should be specified dynamically



abstract class HardCodedHandler
{
private HardCodedHandler successor;
public HardCodedHandler( HardCodedHandler aSuccessor)
{ successor = aSuccessor; }
public void handleOpen()
{ successor.handleOpen(); }
public void handleClose()
{ successor.handleClose(); }
public void handleNew( String fileName)
{ successor.handleClose( fileName ); }
}
abstract class SingleHandler
{
private SingleHandler successor;
public SingleHandler( SingleHandler aSuccessor)
{
successor = aSuccessor;
}
public void handle( String request)
{
successor.handle( request );
}
}
class ConcreteOpenHandler extends SingleHandler
{
public void handle( String request)
{
switch ( request )
{
case "Open" : do the right thing;
case "Close" : more right things;
case "New" : even more right things;
default: successor.handle( request );
}
}}
abstract class SingleHandler
{
private SingleHandler successor;
public SingleHandler( SingleHandler aSuccessor)
{successor = aSuccessor; }
public void handle( Request data)
{ successor.handle( data ); }
}
class ConcreteOpenHandler extends SingleHandler
{
public void handle( Open data)
{ // handle the open here }
}
class Request
{
private int size;
private String name;
public Request( int mySize, String myName)
{ size = mySize; name = myName; }
public int size() { return size; }
public String name() { return name;}
}
class Open extends Request
{// add Open specific stuff here}
class Close extends Request
{ // add Close specific stuff here}
interface ArithmeticExpression
{
public Number evaluate( Context data);
}
class BinaryOperator implements ArithmeticExpression
{
private ArithmeticExpression leftOperand;
private ArithmeticExpression rightOperand;
private String operator;
public BinaryOperator( String anOperator)
{ operator = anOperator;}
public void setLeftOperand(ArithmeticExpression anExpression)
{
leftOperand = anExpression;
}
public void setRightOperand(ArithmeticExpression anExpression)
{
rightOperand = anExpression;
}public Number evaluate( Context environment)
{
Number right = rightOperand.evaluate( environment );
Number left = leftOperand.evaluate( environment );
switch ( operator )
{
case "*": return right * left );
case "+": return right + left );
etc.
}
}
}
class Constant implements ArithmeticExpression
{
private Number value;
public Constant( Number aValue)
{ value = aValue;}
public Number evaluate( Context environment)
{ return value; }
}
class Variable implements ArithmeticExpression
{
private String name;
public Variable( String aName )
{ name = aName; }
public Number evaluate( Context environment)
{ return environment.getValueOf( name );}
}class Context
{
private Hashtable variables = new Hashtable();
public void setValueOf( String name, Object value)
{
variables.put( name, value);
}
public void getValueOf( String name)
{
return variables.get( name);
}
} Implementing the grammar is easy
Complex grammars are hard to maintain
Adding new ways to interpret expressions