I want to use visitor pattern to extend functionality of classes from external library. The main problem that I can't add any new code to that library. Let's consider simple example.
External elements, which require functionality extension will be represented as tools for home work
public interface Tool {
String name();
}
public record Saw(String name, String purpose) implements Tool {}
public record Screwdriver(String name, String nozzle) implements Tool {}
public record Wrench(String name, int size) implements Tool {}
And new functionality, which I want to add will be represented as workers
public interface Worker<T extends Tool> {
Class<T> getToolClass();
void doWork(T tool);
}
Saw worker
public class SawWorker implements Worker<Saw> {
@Override
public Class<Saw> getToolClass() {
return Saw.class;
}
@Override
public void doWork(Saw tool) {
System.out.println("Sawing with " + tool);
}
}
Screwdriver worker
public class ScrewdriverWorker implements Worker<Screwdriver> {
@Override
public Class<Screwdriver> getToolClass() {
return Screwdriver.class;
}
@Override
public void doWork(Screwdriver tool) {
System.out.println("Tightens screw with " + tool);
}
}
Wrench worker
public class WrenchWorker implements Worker<Wrench> {
@Override
public Class<Wrench> getToolClass() {
return Wrench.class;
}
@Override
public void doWork(Wrench tool) {
System.out.println("Tightens bolt with " + tool);
}
}
And main class to start the show
public class Main {
public static void main(String[] args) {
List<Tool> tools = List.of(
new Saw("hand saw", "for gardener"),
new Saw("chainsaw", "for forester"),
new Screwdriver("torque screwdriver", "line"),
new Screwdriver("powered screwdriver", "cross"),
new Wrench("open-end wrench", 12),
new Wrench("combination wrench", 32));
Map<Class<? extends Tool>, Worker> workers = Stream.of(
new SawWorker(),
new ScrewdriverWorker(),
new WrenchWorker()
).collect(Collectors.toMap(Worker::getToolClass, Function.identity()));
tools.forEach(tool -> workers.get(tool.getClass()).doWork(tool));
}
}
What do you think about such implementation of the pattern? Is it possible to upgrade this solution with use of java8 lambdas? And will it look easier and clearer?
Aucun commentaire:
Enregistrer un commentaire