I am working on a game that requires resolution actions depending on the object a ball collides with.
A lot of code within the resolution method applies to all of the different types of objects that could be hit but some is also specific to a particular object type.
The pseudo code looks like this:
resolve (Object a) {
if (some test) {
if (Object a is rect) {
// do one thing
} else {
// do something else thing
} else if (another test) {
if (Object a is rect) {
// do one thing
} else {
// do something else thing
} else if (third test) {
if (Object a is rect) {
// do one thing
} else {
// do something else thing
}
}
However, to a newbie, this feels kind of cluttered (because of the tests for object type within each if clause) but I can’t quite figure out how to improve it ? I could override the method and have behavior based on the subclass that is passed to it but then I end up with a lot the same code in both methods.
This method tests the current location of the ball (top, bottom etc) and adjusts the balls velocity accordingly. If object is a rectangle, the new velocity is different to say a circle.
Can anyone offer any assistance?
As suggested the visitor pattern is a good idea as it supports modularisation of code. This is because the code for each test is kept its own class and method, thus helping to prevent methods becoming overly long and complex.
It now also means you do not have to check if an Object is a Rectangle or not as this is done by the a technique known as double dispatch. Whereby the GameObject knows what instance of a class it is and therefore calls the appropriate resolve method on the Visitor.
It also helps maintainability as if you need to treat another subclass of GameObject specifically then you first change the ResolveVisitor interface and then start changing the concrete implementations of the visitors. If you forget one by accident then compiler will not let you compile the code and point to the problem.
Here is a verbose example of the visitor pattern: