aspose file tools*
The moose likes Java in General and the fly likes Avoiding if/else constructs Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Java 8 in Action this week in the Java 8 forum!
JavaRanch » Java Forums » Java » Java in General
Bookmark "Avoiding if/else constructs" Watch "Avoiding if/else constructs" New topic
Author

Avoiding if/else constructs

David Follow
Ranch Hand

Joined: Oct 16, 2001
Posts: 223
Hi all,
say I have a web application (e.g. made with Struts) where
I have to respond on a certain item. Say "color".
The problem is that I have to cover all the colors.
Eventually I will end up having a huge list of nested if/else statements, e.g.
if(color.equals("red"))
forward = ....;
else if(color.equals("blue"))
forward = ....;
else if(color.equals("green"))
forward = ....;
else if(color.equals("white"))
forward = ....;
else if(color.equals("black"))
forward = ....;
else if(color.equals("yellow"))
forward = ....;
//....and so forth.
Is there a better way of doing that?
Can I use a pattern (e.g. command pattern) that does a better job?
What about polymophism? The thing is that I don't want to make it
too complicated. All I want to do is get rid of the huge if/else structure.
Any ideas?
TIA, Misos
Joe Ess
Bartender

Joined: Oct 29, 2001
Posts: 8718
    
    6

Why don't you declare forwards (action? My Struts is rusty) for each of the colors (or some name based on the color)? That way you just call forward(someName+colorName) or something like that. Of course, should someone somehow submit a name that isn't covered in your Struts config file. . .


"blabbing like a narcissistic fool with a superiority complex" ~ N.A.
[How To Ask Questions On JavaRanch]
rom chatterjee
Ranch Hand

Joined: Dec 11, 2001
Posts: 46
Dont know if this too hacky, but you could extend Color adding static IDs, eg MYColor.RED_ID=1, MYColor.BLUE_ID=2, and then switch on the ID.


Rom Chatterjee<BR>Sun Certified Java Programmer
Stan James
(instanceof Sidekick)
Ranch Hand

Joined: Jan 29, 2003
Posts: 8791
If the values you are assigning are singletons or Strings or something simple, you could cache a bunch of them in a HashMap keyed by the color name.

If you have to create a new thing every time, you might cache class names.

Either way, you might have an initialization routine that loads up the map from configuration data, so you can add new things without opening up the code. Hope that helps!
[ October 30, 2003: Message edited by: Stan James ]

A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Dont know if this too hacky, but you could extend Color adding static IDs, eg MYColor.RED_ID=1, MYColor.BLUE_ID=2, and then switch on the ID.
If you have a class for Color, then you also might just make this forward thing an instance variable in the class. Then no need for a switch at all. But I have no idea if that would make sense for your design. And I don't know much about struts; Joe's advice may well be more applicable there. But one other possibility here is to put all the different forwards into a Map:
This is well-suited to a situation where you have a large number of options, as the get() method is a constant-time operation. You can also easily load the forewardMap from a file of some sort, for greater flexibility. Of course struts may already have somethign like this somewhere for all I know...


"I'm not back." - Bill Harding, Twister
David Follow
Ranch Hand

Joined: Oct 16, 2001
Posts: 223
Hi all,
thanks for all the good ideas.
One more thing, it doesn't really have to be Struts, it's more or less a general thing where I would like to avoid large if/else structures.
To make things even more complicated my if/else can look something like this:

Any ideas on this one?
How could I solve this with a HaspMap?
TIA, Misos
Stan James
(instanceof Sidekick)
Ranch Hand

Joined: Jan 29, 2003
Posts: 8791
Now you're getting to where polymorphism comes in handy. The Command pattern talks about encapsulating an action in an object. So let's make a different class for each different action and initialize a set of them in a factory class:

Now when somebody gives you a color:

That doesn't really handle the && and || stuff you showed. BTW: The && you showed will never be true. Right?
This principle is alive in the "front controller" pattern like Struts. Given an inbound GET or POST request, get the right servlet or command from a factory and execute it. There the configuration is in XML instead of the kind of hard-coded factory initialization I showed. The whole business of decoupling and avoiding giant case statements can be a lot of fun!
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
That doesn't really handle the && and || stuff you showed. BTW: The && you showed will never be true. Right?
Ignoring the &&, the || can easily be handled with something like
David Follow
Ranch Hand

Joined: Oct 16, 2001
Posts: 223
Originally posted by Stan James:
Now you're getting to where polymorphism comes in handy.

Hi, this may be true, but in my if/else struct all I have to do is add
a line or two to do my thing. With the polymorphism approach I will have
to write a separate class of every potentially "little thing" I want to do.
Now which one will be more readable? The design of the polymorphism approach
may be nicer but from a point of readability (and eventually lines of code)
the complex if/else struture is in my opinion more obvious.
What do you think?
Loren Rosen
Ranch Hand

Joined: Feb 12, 2003
Posts: 156
If you really have just one place where the if/else occurs that it's certainly arguable that using polymorphism is over-engineering. But what usually happens is that the same if/else ends up in dozens of places, and the result is a lot harder to maintain that a set of subclasses.
Stan James
(instanceof Sidekick)
Ranch Hand

Joined: Jan 29, 2003
Posts: 8791
Yes, adding classes and configuration seems like (ok, it IS) overkill for simple situations, like a one-man project. But note you said you have to open up the code and add a line. Every time you open it, your manager might insist you regression test the whole system to make sure you didn't break it. And you know that guy at the of the aisle will break it every time he opens it. Ouch! Or maybe you'd like to sell your class in compiled form. I could buy it and add more color-action combos in configuration file without ever seeing the source. Cool, no?
You do have to learn to see the line between beautiful theory and getting the job done. This is not easy, because it moves on every assignment. XP has a precept to Do The Simplest Thing That Can Possibly Work. Start there. Refactor goodness in when the risk of that guy down the aisle starts to bother you.
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
This also depends on how many different types of behavior you really have here. If you have 100 different color names that need to be mapped to 100 different method calls, then writing 100 different classes for this to take advantage of poymorphism is proabably overkill. Then again, writing 100 different method calls isn't too great either; I'd be looking hard to see if there isn't some better way find similarities in the behavior of the different method calls, which might suggest some refactoring which is more readable. Maybe some of those method calls are identical except they use different numbers inside? Then make the numbers parameters which can be set by a constructor, so maybe you can have something like

(I'm just making up numbers here; no idea what they might mean.)
And if you have 100 different colors that map to, say, 5 different behaviors, then writing 5 short classes (plus one interface) and putting 100 entries in a Map is probably a pretty good way to go.
Polymorphism may not be the end-all solution here, but I think it's at least worth considering.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Avoiding if/else constructs
 
Similar Threads
Number Combinations
Exact Front Controller In Realtime
pattern search
Html glass pane
Problems with servlet filter