intelliproject logo

Location: Desktop development - Java    License: The Apache License, Version 2.0

Working with Enums without using Switch / If

Posted by Matthias Rothe

Shows how you can use enum methods to avoid using switch / if

Skill: Intermediate

Posted: 18/06/2009

Views: 667

Rating: 5.00 /5

Popularity: 1.51

Sign Up to vote for this article

Introduction

This article shows you how to use enum element methods to avoid using switch statements when working with enums. Following this advice will greatly simplify and clearify your code. Before we start one word about using if statements in the cases covered by this article: Don't do it. Ever. Agreed? Then let's get to it.

The usual approach

Usually if you have an enum type and want to do something different for each of its elements you'd use a switch statement to find the code to execute in a certain sitation. An example of this approach might look like this:

Doing it this way comes with a few drawbacks, though.

First, it looks bad. With our example enum type just having three elements it might actually still be considered alright. But imagine having not three but thirty elements there. The switch statement would grow enormously and you'd get lost in it in no time. The purpose of the method isn't clear and easily understood as code that executes business logic gets entangled with a lot of scaffolding code.

Second, it's hard to test. Depending on how the code that's going to be executed for each element is structured it might be hard to impossible to test it in isolation. Instead of being able to write tests exercising the business logic code of each element separately you'd have to write a lot of tests exercising the switch statement and the business logic code. This also doesn't really help to quickly get an understanding of what the tests are meant for.

Third, it's hard to extend. Imagine you want to add another element to the enum type. We might want to also be able to draw rectangles with rounded corners. So you add the element to the enum type. However, you forget to extend the switch statement with the new element for some reason. No one reminds you to do it and it might take ages until the omission makes itself noticed at runtime, if at all. But even if you remember to also change the switch statement you'll have to edit at least two classes to simply add one element. To me that sounds like a bad design. And it gets worse: Imagine not having one but several switch statements working on the same enum type. You'd have to keep them all up to date - without anybode reminding you. Sounds bad? Thought so. ;-)

Last but not least, it's not a good object oriented style. Object orientation is all about working with and on objects using its cornerstones to the fullest. Just to bring them back to mind, these are polymorphism, encapsulation and inheritance. While using a switch statement this way is as good a style as you'll get it in procedural programming, object oriented programs can do a lot better. The remainder of this article will show you how.

The better way

So, just how can we avoid those switch statements? It all comes down to moving the business logic code for each enum type element where it really belongs: to the element.

Elements of enum types can have their own methods and implement methods declared as abstract at the enum type as such. Using this our code changes to:

See, how short, precise and easy to understand the drawShape() method of the class ShapeDrawer suddenly becomes? All that's left is one single line of code. Can't get better than that, right?

But not only that. The code in that method will never have to be changed, no matter how many elements we might have in our enum type some day. Due to the polymorphism employed here, the call to shape.draw() will always be executed on the right element of the enum type. This is what good object oriented style is about.

Also, it's very easy to extend our enum type now. All we do is adding the element. The compiler will tell us instantly that we need to implement the draw() method. No chance for surprises at runtime anymore. If there were any other methods replacing previous switch statements, the same would apply. So all you'll ever need to edit is the enum type - and you'll be reminded of it each single time. Pretty cool, eh?

Furthermore it becomes a lot easier to write tests that exercise the code for each enum type element in isolation. Each draw() method becomes a target for test methods dedicated to it. This makes the intention of each test method a lot clearer.

Points of Interest

If you want to substitute the default section of the switch statement in the new approach, just implement the draw() method at the enum type level, instead of declaring it abstract.

License

This article, along with any associated source code and files, is licensed under The Apache License, Version 2.0

About the author

Matthias Rothe

Having completed an computer science study course last year in September I'm currently working as a Java developer in Munich, Germany.

As many other folks interested in computers I've had quite some experience programming in the desktop and web environments even before studying.

If I'm not at work, you might find me at my local church, where I'm a part of the youth leadership team; programming on various private projects, the most prominent currently being the RedRoo project at http://sourceforge.net/projects/redroo; or hanging out with friends.

Location: Germany
Ocupation: Java Developer
Home page: http://www.matthiasrothe.com

Sign up to post message on the article message board!