Harish Nair
Harish Nair

Reputation: 189

Use of strings vs enums as parameter of factory method?

I was recently reading this blog https://blog.cleancoder.com/uncle-bob/2021/03/06/ifElseSwitch.html and this paragraph confused me:

Be careful with that token x. Don’t try to make it an enum or anything that requires a declaration above the red line. An integer, or a string is a better choice. It may not be type safe. Indeed, it cannot be type safe. But it will allow you to preserve the component structure of your architecture.

If we declare an enum in the higher level module, wouldn't it still be that the low level module depends on the high level module? If so, then what is wrong in using an enum in this case?

Upvotes: 2

Views: 612

Answers (2)

Robert Martin
Robert Martin

Reputation: 2933

The direction of the dependency is fine. There is another problem, though. When a new enumerator is added due to a change in the requirements, both sides of the boundary have to change. This violates the open-closed principle. We want to be able to make changes that do not affect the higher level side of the boundary.

If you use a string, instead, then adding the new condition below the line does not force any change above the line.

You may rightly ask how the high level side learns about the strings. It turns out that the high level side can ask the low level side for all the relevant strings.

Thus, by using strings, instead of enums, you can protect the high level code from changes to the lower level requirements.

Upvotes: 4

Mark Seemann
Mark Seemann

Reputation: 233317

The only person who can definitely answer that question is Robert C. Martin himself, but I'll try to make an attempt.

As far as I understand it, the implied scenario is that the $input parameter represents run-time input, which is inherently not type-safe.

In many application architectures, there's a boundary where the software 'meets the real world'. In a primitive application, you may ask the user to type 0 for male and 1 for female. In a console application, you're not even going to receive an int - you'll get a string.

In a web application you easily run into a similar problem. Even if you make a nice GUI with, say, radio buttons, you can't fully trust that some malign user wouldn't try to circumvent the GUI to instead give you a raw string - or, that a bug somewhere else in the code is going to do something to a similar effect.

Introducing an enum isn't going to change that. You'll still have to parse the raw string into an enum value. If the next thing you do is then to switch on the enum to produce a polymorphic object, you might as well dispense with the intermediary step, and hence, with the enum.

This discussion is reminiscent of Alexis King's great blog post Parse, don't validate, which makes a similar point: turn something less-structured into something with a better structure.

Upvotes: 5

Related Questions