I am reviewing some code(Java) and making changes based on a business logic flow chart. The current code relies on a large amount of if statement’s – something I want to try and move away from. I have been reading about Polymorphism and being trying to wrap my head around how to apply it to my situation. I can make it work for a single level of conditionals, but struggling to extend it further across multiple conditional levels. The code will be executed at run time, with this ‘Logic’ method being passed the variables from a previous step.
Contrived Example:
We have 2 Zoo’s, ‘Zoo A’ and ‘Zoo B’, and ‘Home’. Each of these is a ‘Place’. In each Zoo we have 4 ‘locations’, ‘North’, ‘South’, ‘East’ and ‘West’. ‘Home’ only has one location.
We want to assign a ‘destination’ to a person on where they should go based on a few variables.
These variables are:
‘Place’, which correlate to our places (Zoo A, Zoo B, Home).
‘Direction’, which correlate to our locations, (N,S,E,W).
Flow Chart:
|----- | 'HOME'
|Place?| ----- > *destination = 'home'*
|----- |
Zoo A | Zoo B
|---------------|----------------------------------------|
|----------| |----------|
|Direction?| |Direction?|
|----------| |----------|
| North | North
----------- *destination = 'Zoo A North' ----------- *destination = 'Zoo B North'
| East | East
----------- *destination = 'Zoo A East' ----------- *destination = 'Zoo B East'
| South | South
----------- *destination = 'Zoo A South' ----------- *destination = 'Zoo B South'
| West | West
----------- *destination = 'Zoo A West' ----------- *destination = 'Zoo B West'
So If Person X has a Place of Zoo A and a Direction of South they should have a Destination of ‘Zoo A South’
I have code that is currently pretty ugly using If statements:
if(Place = 'HOME')
destination = 'HOME'
if(Place = 'Zoo A')
if(Direction = North)
destination = 'Zoo A North')
if(Direct = East)
destination = 'Zoo A East')
...
if(Place = 'Zoo B')
if(Direction = North)
destination = 'Zoo B North')
if(Direct = East)
destination = 'Zoo B East')
...
I could turn this in to nested switches with the variables as ENUMs. But I am trying to avoid the if – else / switch reliance as I have a bad habit of falling into it. I experimented with using a Factory Design to generate Place classes, then used Polymorphism on each location and destination but it started to get overly complicated in my head. Is it even worth moving away from if/switches? Am I just trying to over engineer it?
Any suggestions on how to tackle logic flows like this?
Thanks
This could be modelled like this:
Place, with methodcalculateDestination(Person). Place can consist of other places inside of it.Placesubclasses forZooandZooQuadrant(naturally, as these are actual places).Personobject has values forcurrentPlaceandcurrentDirectionNow you’d instantiate objects of these classes to represent your situation:
When you want to get the destination, you would call
world.calculateDestination(myPerson)calculateDestination(Person)is the polymorphic method. Each level in the inheritance hierarchy will override it according to the specific semantics of that class.Placewill have a generic implementation that will test if thePersoninstance is currently at that node (by testing against thePerson‘s value forcurrentPlace) and if not, it will callcalculateDestinationon each of its children and return that.Zoos will need to check ifcurrentPlace == this, and if so, callcalculateDestinationon each of its quadrants and combine any positive result with its own to returnthis.name + quadrantResult.ZooQuadrantjust needs to check if thecurrentDirectionis equivalent to its own direction, and return a value accordingly.Note: this is just to illustrate how polymorphism may work, there may be better implementations. Also, here we’re using both polymorphism and recursion, the two are independent.
EDIT:
As for whether the added complexity is warranted, that depends! Here we’re working with a simple example with an object graph that is quite small. As soon as you have tens of zoos, have to add more quadrants in those zoos, or extra levels of decisions need to be made (if for example each quadrant has subquadrants), the nested if-else-if method (procedural) gets really hairy really quickly, whereas the object oriented approach remains maintainable and understandable.
Like everything, if you foresee that decisions are going to get that complex, go with the OO approach. Otherwise, keeping it simple trumps beauty every time: use the right tools for the right problems.