0

I'm Working with php and we using enum's by create an Abstract class that mocking enum behavior - but my question is cross-languages.

Where all the helper functions like toString, getEnumTypes, checkValidValue, etc... should be, in a dedicated utility class: EnumUtil or in the AbstractEnum it self (all enums extends AbstractEnum so all enum have those functions)

And if the answer it in the AbstractEnum itself in which cases I should create a utility class?

P.S: This is a general question but I focused it with a real life example.

2
  • I'm not clear what you mean by "enums" with respect to PHP. Are you using an abstract base class, with concrete child classes, in combination with protected and private constructors on those classes to give you only certain instances of those classes? Jul 19, 2017 at 14:56
  • 1
    We are using a class like that one: AbstractEnum, so we don't have instances of enums rather than we using it as static class
    – Michael
    Jul 19, 2017 at 16:46

3 Answers 3

4

If the functions are meaningful for all enums, then use the base class.

"Utility classes" in general should be avoided. Or to put it another way, if you can only think of the name FooUtility for a class, then the functionality probably belongs in Foo rather than in a seperate class.

Edit: Obviously this depends on your definition of "utility class", since it is not a term with an absolute definition. But if the sole purpose of a class is to provide utility functions for operations on another class - as in your example - then the functions belongs on that class. Only justification I can think of for a separate class is utility functions for a sealed class.

7
  • Sorry, had to downvote because of the bad advice that utility classes should be avoided. See my answer with a well-justified problem where the natural solution is to use in fact a utility class for utilities operating on objects implementing a given interface. As John Carmack has said, "Sometimes, the elegant implementation is just a function. Not a method. Not a class. Not a framework. Just a function."
    – juhist
    Jul 19, 2017 at 13:42
  • 1
    @juhist: I'm not sure the Carmack quote can be used to justify creating a redundant class. That said, "Utility classes" can be justified depending on the purpose of the class (I don't think there is an objective definition of the term "utility class" anyway.). But if a class only works as a utility for another class, as in the question, then it is superfluous. Only justification I can think of is for extension methods for a sealed class.
    – JacquesB
    Jul 19, 2017 at 15:15
  • "Utility class" is a phrase I have only ever heard used to collect common functionality across classes, not a place to stuff code because a single class became larger. Jul 19, 2017 at 16:21
  • Thanks, @JacquesB what do you think about FileUtil? do you think it's a problematic too? yes, we can vreate a File class that have path, size and whatever but most of the time we just need to do operations like rename or getSize and not really need a full (heavy?) object.
    – Michael
    Jul 19, 2017 at 16:56
  • @Michael: If you are talking about static methods versus instance methods, this is an independent issue.
    – JacquesB
    Jul 20, 2017 at 7:13
0

Any and all methods which make sense to be applied directly to a enum value should be in AbstractEnum such as toString. Static methods like retrieving a value from a string (valueOf in Java) could either be placed in a helper class or placed directly in the derived enum class (though I would avoid placing it in AbstractEnum for simplicity's sake).

Ideally, the constructor of AbstractEnum and all derived classes would be protected and instantiated only by the class itself in a static fashion, so that there's no possibility of checking equality between separate instances of the same "enum value".

However as a general rule of thumb, you should place methods in AbstractEnum only as long as it makes sense to call that method on a specific instance.

0

I would disagree with the generally accepted wisdom that utility classes should be avoided. Using Java here as an example, but I'm sure the idea applies to other languages as well.

Consider, for example, a data type of which you need both mutable (for performance) and immutable (for hash table keys, sets, other kinds of correctness problems, etc.) variants: a complex number. So, you have Complex (immutable) and ComplexBuffer (mutable). Now it would be foolish to write four versions of the subtraction fuctionality (Complex - Complex, ComplexBuffer - Complex, Complex - ComplexBuffer, ComplexBuffer - ComplexBuffer), so you will want to create a common interface ComplexNumber shared by Complex and ComplexBuffer. The ComplexNumber interface has getReal() and getImag() methods.

Now, to subtract two ComplexNumber implementing objects, you will define a class ComplexUtils and a static method public static Complex sub(ComplexNumber, ComplexNumber). So, there you have it: a problem where the best solution is to actually use a utility class. Of course, for performance you will have also ComplexBuffer.subInPlace(ComplexNumber) that creates absolutely no new objects.

So, don't follow blindly the advice that utility classes should be avoided. As John Carmack has said:

Sometimes, the elegant implementation is just a function. Not a method. Not a class. Not a framework. Just a function.
6
  • 1
    But you are creating a new class, the utility class. Why can't you add the methods in question to the base class?
    – JacquesB
    Jul 19, 2017 at 14:34
  • It's a base interface, not a base class. Interfaces cannot have methods.
    – juhist
    Jul 19, 2017 at 14:35
  • The other alternative is to eliminate the mutable Complex entirely. And this is typically what is done. Perhaps your example would make more sense with a different type. In this case you have collected common code into a utility class, whereas in the original question, it appears that the utility class had code used by only a single other class. Jul 19, 2017 at 16:25
  • In any case this could be solved more elegantly by using a base class or some other device (default interface methods in Java?). There is no reason the consumer of complex numbers should need to know about "ComplexUtils" if they already have a complex number instance.
    – JacquesB
    Jul 19, 2017 at 16:31
  • I think you could replace ComplexNumber with CharSequence, Complex with String, ComplexBuffer with StringBuffer / StringBuilder and the example then makes more sense if you don't care about complex number micro-optimizations like I do. The place to add a newly written character sequence algorithm would be appropriately called CharSequenceUtils.
    – juhist
    Jul 19, 2017 at 16:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.