Let's say I have a package called 'animal' including Animal parent class, Cat extends from Animal, Dog extends from Animal, also. Animal, however, is designed like this:
class Animal {
int amount;
Animal next; // Then a constructor initializes these.
drinkWater(int n) { ... }
}
Cat & Dog classes follow this structure:
class Cat extends Animal {
Cat(int amount, Animal next) {
super(amount, next);
}
@Override
drinkWater(int n) { .. }
}
Each of them has the method, drinkWater() like this:
public void drinkWwater(int n) {
amount -= n;
if (amount < 0) amount = 0;
if (next != null) next.drinkWater(n);
}
What I am trying to do now here is I created a 'linked list' of animals, each of them drinking water in sequence. However, let's say, if a cat drinks n amount of water, it passes n+1 amount of water to its.next
My purpose is finding a solution to overcome the problem that 'don't touch the original animal package, but change behavior of drinking water each one of them'. I have come with that 'famous' naive solution with a class:
class InvokeStaticTypeBDrink {
static void typeBdrink(Animal animal, int n) {
animal.amount -= n;
if (animal.amount < 0) animal.amount = 0;
if (animal.next != null) {
if (animal instanceof Cat)
InvokeStaticTypeDrink.drinkWater(animal.next, n+1);
else if (animal instanceof Dog)
InvokeStaticTypeDrink.drinkWater(animal.next, n-1);
else
InvokeStaticTypeDrink.drinkWater(animal.next, n);
}
}
}
Then, I started to research. Because this really looked quick and dirty solution.
So, I found that design pattern called 'Visitor Pattern'. Well, pretty cool pattern which solves the problem with double dispatch, but there is a problem on my side: Visitable interface (which declares accept() method) should be 'implement'ed by the original Animals. However, my goal is 'do NOT to do any modification on original animal package, but do change the drinking water behavior'. I am pretty sure I am missing something.
So, do you think with a little bit hack, Visitor Pattern would still work or another pattern/solution would be better? Thanks.