Arved Sandstrom said:
I don't understand enough about what you're trying to do to address the
"passing through" and "neighbours" idea properly. However, to invert the
logic a bit, you've clearly got the information to decide _whether_ to
call command.process()...otherwise (see above) you never could have
constructed a Command subclass to pass to your "process" method in the
first place. So, wherever _that_ logic is, where you construct a Command
subclass, is perhaps where the logic should be to hand off to another
"neighbour" ("broadcast" as you put it).
The question is not whether avoidance of »instanceof« is
possible technically, but whether the resulting code will
be more readable and maintainable than the code using
»instanceof«.
Here is an SSCCE using »instanceof«.
Maybe someone wants to rewrite it so as to remove »instanceof«?
(In this case, keep in mind, that the type of neighbor
objects (here: »other«) changes at run-time and is not
known at compile time, because components are intended
to be added as run-time plug-ins. At coding time, we only
know that »other« is a »Processor« and thus will accept
a »Command«.)
abstract class Command { public boolean seen = false; }
interface Processor { public void process( final Command command ); }
/*** The clock component ***/
abstract class ClockCommand extends Command {}
class QuitClockCommand extends ClockCommand {}
class AdjustClockCommand extends ClockCommand {}
class Clock implements Processor
{ public Processor other;
public void process( final Command command )
{ if( command instanceof ClockCommand )
{ if( command instanceof QuitClockCommand )
java.lang.System.out.println( "quit clock" );
if( command instanceof AdjustClockCommand )
java.lang.System.out.println( "adjust clock" ); }
else
{ if( !command.seen && other != null )
{ command.seen = true; other.process( command ); }}}}
/*** The counter component ***/
abstract class CounterCommand extends Command {}
class QuitCounterCommand extends CounterCommand {}
class IncrementCounterCommand extends CounterCommand {}
class Counter implements Processor
{ public Processor other;
public void process( final Command command )
{ if( command instanceof CounterCommand )
{ if( command instanceof QuitCounterCommand )
java.lang.System.out.println( "quit counter" );
if( command instanceof IncrementCounterCommand )
java.lang.System.out.println( "increment counter" ); }
else
{ if( !command.seen && other != null )
{ command.seen = true; other.process( command ); }}}}
/*** The controller ***/
public class Main
{ public static void main( final java.lang.String[] args )
{
final Clock clock = new Clock();
{ /* Build a graph of connected components: */
clock.other = new Counter(); }
{ /* Send commands to a component: */
clock.process( new AdjustClockCommand() );
/* You can send a counter command to a clock, too: */
clock.process( new IncrementCounterCommand() ); }}}
/* This will print:
adjust clock
increment counter
*/