public interface UnitVisitor {
void visitSoldier(Soldier soldier);
void visitSergeant(Sergeant sergeant);
void visitCommander(Commander commander);
}
public class CommanderVisitor implements UnitVisitor {
private static final Logger LOGGER = LoggerFactory.getLogger(CommanderVisitor.class);
@Override public void visitSoldier(Soldier soldier) { }
@Override public void visitSergeant(Sergeant sergeant) { }
@Override public void visitCommander(Commander commander) { LOGGER.info("Good to see you {}", commander); } }
public class SergeantVisitor implements UnitVisitor {
private static final Logger LOGGER = LoggerFactory.getLogger(SergeantVisitor.class);
@Override public void visitSoldier(Soldier soldier) { }
@Override public void visitSergeant(Sergeant sergeant) { LOGGER.info("Hello {}", sergeant); }
@Override public void visitCommander(Commander commander) { } }
public class SoldierVisitor implements UnitVisitor {
private static final Logger LOGGER = LoggerFactory.getLogger(SoldierVisitor.class);
@Override public void visitSoldier(Soldier soldier) { LOGGER.info("Greetings {}", soldier); }
@Override public void visitSergeant(Sergeant sergeant) { }
@Override public void visitCommander(Commander commander) { } }
public abstract class Unit {
private Unit[] children;
public Unit(Unit... children) { this.children = children; }
public void accept(UnitVisitor visitor) { Arrays.stream(children).forEach(child -> child.accept(visitor)); } }
public class Commander extends Unit {
public Commander(Unit... children) { super(children); }
@Override public void accept(UnitVisitor visitor) { visitor.visitCommander(this); super.accept(visitor); }
@Override public String toString() { return "commander"; } }
public class Sergeant extends Unit {
public Sergeant(Unit... children) { super(children); }
@Override public void accept(UnitVisitor visitor) { visitor.visitSergeant(this); super.accept(visitor); }
@Override public String toString() { return "sergeant"; } }
public class Soldier extends Unit {
public Soldier(Unit... children) { super(children); }
@Override public void accept(UnitVisitor visitor) { visitor.visitSoldier(this); super.accept(visitor); }
@Override public String toString() { return "soldier"; } }
public class App {
public static void main(String[] args) {
var commander = new Commander( new Sergeant(new Soldier(), new Soldier(), new Soldier()), new Sergeant(new Soldier(), new Soldier(), new Soldier()) ); commander.accept(new SoldierVisitor()); commander.accept(new SergeantVisitor()); commander.accept(new CommanderVisitor());
} }
|