Refactoring: Replace Enum with Polymorphism

Jason Larsen
Aug 8, 2016 · 2 min read

Enums in Swift are greatlove me some sweet, sweet enums. However, as with all great things, one can go too far.

Let’s look at the following contrived example:

yo, dawg, I heard you like enums so I put an enum inside your enum!

I’ve seen a lot of enums like this. Well, not animals maybe. But you know what I mean.

Let’s do a mental exercise: how do you add a fox to your list of animals? Pretty straightforward: add a new case, the compiler will tell you your cases are no longer exhaustive and you fill out those cases… and done.

Unless you’re switching on it somewhere else in your code. Then you have to update those too.

And if you have lots of vars/funcs… That’s a lot of work to add a case to to each.

And now that you look at it, there’s a lot of duplicate code involved to setup the switches and define all the cases.

And can you imagine what will happen if you have to throw logic and associated types into the mix?

This could get unwieldy quickly.

Let’s Rewind

Why are we using an enum in the first place? Is it just because I want a way to group lots of the same type together that have the same properties?

There is a way to do this that has existed since the dawn of time: protocols.

This ancient refactoring technique is known as Replace Conditional with Polymorphism, and it can make your code cleaner, if you will let it in your heart. But I’ll call it Protocol Oriented Programming so we can get people to use it and increase traffic to this article.

As you can see:

  1. We remove lots of duplicate switch code.
  2. Adding a new case is as simple as adding a new type — no need to refactor other methods. This is the Open/Closed Principle.
obligatory joke

When Should You Use Enums?

As I said before, enums are great. You just need to use them appropriately. They are great for scenarios where you specifically do not want flexibility, or awesome things like ADTs.

Notice that when we refactored we kept an AnimalSize enum lingering around; we only ever want those 3 types, so that’s a good use case for an enum.

So, ask yourself first:

“Do I know all cases and want to make sure every possibility is accounted for—but never more?”

If so, you very well might want to use an enum!

Conclusion

Enums are an awesome, essential part of Swift, but it seems that this new shininess can sometimes lead to using enums where they aren’t the best fit.

Let us go forth and use enums greatly, but also not forget the lessons of the past.

Further Reading

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store