Should enum objects be stateless? - java

As by design an enum constant in java is a singleton, and for sake of concurrent usage I normally create stateless enum instances and use method parameters to inject the data as needed.
Example:
Currently I am creating a REST service which has Operations (implemented as an enum using a variant of the strategy pattern).
public enum Operation {
DO_THIS() {
public Result doSomething(Object theData) {
}
} ,
// Other Operations go here
;
public abstract Result doSomething(Object theData);
}
Now I want to collect data about how often an operation has been called and how often it succeeded and the like.
I could save the state externally when using the enum instance but it rather seems that the state should be saved in the Operation as the operation should contain it's own state.
Now my general question is:
Is a stateful enum instance (besides from concurrency issues) a bad design?

I think it violates the Principle of Least Astonishment.
People expect the common usage of enums as they were originally designed - as constants or tokens, and not as general purpose classes with state.

Yes. And by 'yes' I mean 'Always'.
If you want to collate stats on the number of operations called, implement some observability.

Any form of mutable static is a sin. (Well, you might get away with non-leaky caches, some lazy initialisation and forms of logging.)

A stateful enumeration is an oxymoron, even an anti-pattern!
http://en.wikipedia.org/wiki/Enumeration
An enumeration is a collection of items that is a complete, ordered listing of all of the items in that collection. The term is commonly used in mathematics and theoretical computer science to refer to a listing of all of the elements of a set. In statistics the term categorical variable is used rather than enumeration. The precise requirements for an enumeration (for example, whether the set must be finite, or whether the list is allowed to contain repetitions) depend on the branch of mathematics and the context in which one is working.
Enumerations have a finite number of values, which are supposed to be constant, which they are.
However, the fact that they are "first class" Java Objects totally goes against the grain of the intention or spirit of an enumeration.
If any kind of state is required, the enum (as mentioned earlier) should hold state in an Aspect or the offending enum, should at the very practical least, hold a reference to a delegate class holding state. Understanding "separation of concerns" will help.

This seems like a bad use for enums - why not just go with a base abstract class with a new subclass for each operation?

I entirely agree with mparaz that it violates the Principle of Least Astonishment. People expect enums to be constants.
You can almost certainly work round the logging thing, by something like:
DO_THIS() {
public Result doSomething(Object theData) {
MyUtilClass.doSomething(Object theData);
}
}
and put your logging in the other class.
HOWEVER if you can't work round this, the Principle of Least Astonishment is a guideline; you can violate it PROVIDED you give users of the class enough warnings about what is going on. Make sure the Enum declaration contains a BIG notice saying that it is mutable, and describing exactly what the mutability is. The Enum should still work; it's doing reference comparison against to single instance to test enum values.

There is a case which would probably justify it.
An enum can implement an interface, usually with the particular use case in mind which lets you create
on runtime/openly "some other types of the enum class" in a dynamic fashion, to name it someway.
That means that enum "singleton" instances can be forced to implement some mutable-intended method signatures (as setters), which of course, you still can hide with an empty code or a NotSupportedException.
Luckily, final methods in an interface don't allow any possibility to change state. That would have been the sole "understandable" case I could come up with.

Related

When to use Enum class in java?

It may be very obvious questions, but is it good to use Enum class if you know that the list of values will keep increasing?
Let's say you define an Event Enum first it contains only [Poo, Too] then as we know we always have some new requirement it becomes [Poo, Too, App, Laa] and that keep changing again and again,
So what is the best approach in this case?
tl;dr
If the entire set of possible values is known at compile-time, use enum.
If values can be added or dropped while your system is in use (at runtime), then you cannot use an enum. Use a Set, List, or Map instead.
Known at compile-time
An enum is appropriate when the domain (set of all possible values) is known at compile-time.
If this year your company is offering two products ( Poo & Too ), then make an enum for those two elements.
public enum Product { POO , TOO }
Next year, your company decides to grow their product offerings by adding App & Laa. As part of a planned deployment, add two more objects to your enum.
public enum Product { POO , TOO , APP , LAA }
By the way, notice the naming conventions. The enum has a regular class name (initial cap). The objects being automatically instantiated are constants, and so are named in all-uppercase.
Also, be aware that the enum facility in Java is quite flexible and powerful, much more so than the usual naming-a-number enum scheme seen in most languages. You can have member variables and methods and constructors on a Java enum. For example, you can add a getDisplayName method to provide text more appropriate to a user-interface than the all-caps object name, as seen in DayOfWeek::getDisplayName. You can add quite a bit of functionality, such as ChronoUnit.between.
What you cannot do at runtime with an enum in Java is add or remove objects. Thus the requirement that you know your domain at compile-time. However, when working with a group of enum objects, you can use the highly-optimized EnumSet and EnumMap classes.
Known at runtime
If you cannot determine the domain at compile-time, if users can add or remove elements at runtime, then use a collection such as a List, Set, or Map rather than an enum.
Singleton
Though not originally intended as a purpose of Enum in Java, an enum happens to be the safest (and simplest) way to implement the Singleton design pattern.
This approach to a singleton is explained in the famous book Effective Java by Dr. Joshua Bloch, et al. Using an enum solves multiple obscure technical problems with other approaches to a singleton.
Your question is pretty generic and I'm pretty sure there is no single right answer. But judging based on spring* tags, I suppose you might be asking about enums in DTOs that being sent over your system in serialized form. If that's the case, I would recommend to choose String in DTO, while inside single app it's ok to use enum. Then you would just care about deserialization/conversion in a factory manner, having ability to handle unknown/missing constant gracefully by logging/providing fallback or meaningful error.
It depends on a case-by-case situation and your question doesn't have much context. However, I do recommend using ENUMs for many cases, including if you expect the list of ENUMs to increase.
Some reasons to use them are:
It creates a definite guide of ENUM elements that can be used throughout your code. It eliminates uncertainty over what something is named or what it is. For example ENUM that contains list of animals, or enum of "something".
Its easy to refactor later if you need to change anything.
I'm sure there are many more reasons, I find it like a table of contents sometimes. For many cases, you can completely avoid it and be fine but I think its better to use it in general if you're on the fence.

enums to do the computation

Can we pass objects to enum abstract methods and do a computation in enums? Here is a scenario, I have four constants and each one have their own value assigned to it. Based on the constants I will do the computation in my method.. Instead I would like to do the computation in enum and would like to get the response. To do the computation in enum I have to pass two/three reference objects to the enum methods...
ex: Consider school as enum, constants are TEACHER(LOWLEVELACCESS), STUDENT(NOACCESS), OFFICEADMIN(OFFICEACCESS).
In enum, I have abstract method process which is receiving USER POJO , strings as arguments and update some fields in the object and return the same USER POJO (with updated) to the caller. By this I can sync up the constants and their logic in enum itself.
So my question,
Is it alright to have this implementation in enum? (I have seen most of the examples treat enums to store constant values not using them for any computation)
This computation can be done by using methods in classes, what is the benefit if I do the computation in enum methods?
Is it possible to create getter/setter method in enum?
Thanks In Advance!!
IMHO:
Is it alright to have this implementation in enum?
Yes - I do it all the time.
enum Ops implements Op {
Nop{
#Override
public int filter(int old, int now) {
// Unchanged.
return now;
}
},
Diff{
#Override
public int filter(int old, int now) {
return a(now)
| (Colour.MidGrey + (r(now) - r(old))) << 16
| (Colour.MidGrey + (g(now) - g(old))) << 8
| (Colour.MidGrey + (b(now) - b(old)));
}
};
}
This computation can be done by using methods in classes, what is the benefit if I do the computation in enum methods?
The code for the functionality is in one place. This is always a good thing.
Is it possible to create getter/setter method in enum?
Yes - but don't. Remember that there is one instance of each enum for the lifetime of your code. Adding/removing functionality on a global object is very likely to hurt you later.
Is it alright to have this implementation in enum?
It is a design choice.
Enum brings some advdantanges to provide service operations.
Enum values are singletons out of the box, these are self explanatory, there are memory efficient, etc... but have also some limitations, you cannot directly derive from an enum, so you should introduce an interface behind the enum if you want to be able to test your code and avoid coupling the client classes that do the computation with the enum ... if later you change your mind about the enum usage.
This computation can be done by using methods in classes, what is the
benefit if I do the computation in enum methods?
You reason in terms of objects. You don't need to create a service and indirection in the code since the enum that is a domain object does the computation.
The enum values and the processings associated make part of the same concern. So, gathering them is not necessary a bad smell.
Nevertheless, be aware if you start to write a lot of processing that do very different things in the enum methods, you should probably get them out the enum.
This is a bad smell as the enum should not become a god object.
Is it possible to create getter/setter method in enum?
Providing data, yes but setting data of the enum : no, you must not.
Otherwise you build a stateful service and you risk to finish with synchronization concerns.
Enums are defined to be final. Computations are allowed as far as the result is equal for the same input.
You also can modify the input instance, but you should not define any setter in your enum due the enum is not immutable in that case.
See also Example 8.9.2-4 here

Java Enum<T> vs T as variable type

Is there any difference between this declaration
Thread.State state = Thread.State.NEW;
and that
Enum<Thread.State> state = Thread.State.NEW;
in Java? Instead of the second option is a bit longer?
It's the same case as comparing between:
Child o = someChild;
and
Parent o = someChild;
Enum is the parent class of all enum types. Therefore, with the second line, the code cannot contain references to specific members of Thread.State, specifically the members described in this section of the language spec.
Is there any difference ....
In practice, in this particular case, probably no.
In theory, Thread.State is a subtype of Enum<Thread.State>. If Thread.State declared (non-private) fields or methods, then you could use them via the first declaration of state, but not the second one.
In general, the first form is preferable ... for that reason.
Also, I don't think you would be able to see an enum's static methods values() and valueOf via the variable declared in the second declaration; e.g.
state.valueOf("BLOCKED")
However, calling a static method via an instance reference is bad style.
Two practical differences (as opposed to language-lawyerly reasons) that come to mind:
If you declare state as an Enum<Thread.State>, then you won't be able to pass it to any methods that expect a Thread.State.
If you declare state as an Enum<Thread.State>, you'll leave the reader — whoever needs to touch this code in the future — wondering why you've written it that way.
Neither of these is a terribly deep reason; we could easily imagine a parallel universe where most people used Enum<Thread.State> instead of Thread.State, just as (in our universe) most people use List<...> instead of ArrayList<...> (when possible). But since most people don't do that in our universe, you're better off just following the common pattern, to minimize the risk of confusion and accidental incompatibility.
Incidentally, in case this is going to be your next question . . . the main situation where you would use Enum is when you want to write something generic that works for many different enum types. An example of this in the JDK is EnumMap<K extends Enum<K>,V>, which is a special map implementation that gets space and performance benefits out of knowing that its keys are enum values.
(And note, incidentally, that you can't write EnumMap<Enum<Thread.State>, String>, because Enum<Thread.State> doesn't extend Enum<Enum<Thread.State>>. Instead, you must write EnumMap<Thread.State, String>. So this is an example of difference #1 that I mentioned above: if you declare state as an Enum<Thread.State>, then you can't use it as a key in an enum-map.)

How to set cardinalities in Java field?

Let us suppose we have the following class:
public class MyClass{
List<String> list;
void method() {
}
}
Each object of this class has a list of strings, but what if we want to set the cardinality? For example, I want to force this class to have at least 2 strings in that list.
Is there a general pattern to represent the cardinalities on fields?
You simply need to make sure that there are at least 2 elements in list, by some means. There is no standard or simple way of doing this.
This is known as an invariant of the class. It is your responsibility as the person who writes the class to ensure that this invariant is preserved at all times. In particular:
You need to document the invariant that there are at least 2 elements in the list.
You need to ensure that the list contains at least two elements by the time the constructor finishes. The instance should be "valid" (in the sense that its documented invariant are true) when the constructor finishes.
You need to ensure that all code within the class honors the invariant when it manipulates the list - you are allowed to temporarily make it invalid, but you must ensure that it is not possible to observe your instance in an invalid state.
In the single-threaded cases, this simply means that the invariant must be true once the public method returns (note that this includes if an exception occurs); but if your code is designed to be used in a multithreaded way, you must also ensure that no thread can ever see your instance in a state where the invariant is false (e.g. you may need synchronized blocks, or ensure that updates are atomic).
You need to ensure that subclasses of your class are unable to make the invariant false; or document clearly that it is the responsibility of people writing subclasses to ensure that the invariant remains true.
There is a great item in Effective Java 2nd Ed about this: "Design and document for inheritance or else prohibit it".
You need to ensure that nothing outside your class is able to access the reference to the list. For example, your code makes the list visible to other classes in the same package - any of these classes could call theInstance.list.clear(), and invalidate your invariant.
It's pretty hard to prevent this absolutely - for example, it could be possible for malicious actors to invalidate the invariant using reflection. You can prevent this, but it's a question of weighing the effort of identifying and blocking such methods vs the actual cost of the invariant becoming false (this strongly depends upon how this class is used).
By far the easiest way to enforce an invariant is on an immutable class. If it's not possible to change the observable state of an instance, it's not possible to invalidate the invariant. Then, all you need to worry about is a) making sure that the class is immutable; b) making sure that the invariant is true once the constructor returns. All of the other points above then simply fall away.
Is there a general pattern to represent the cardinalities on fields?
Obviously, you can represent the cardinalities using integer fields, either in the objects themselves, or at the meta level. But that's not much help if you cannot enforce them.
There is no general pattern for that. #Andy Turner's answer provides a good summary of the alternatives on enforcement of cardinalities. I just want to add a couple of points:
Attempting to enforce the cardinality constraints via static typing is unlikely to work. The Java type system is not rich enough to do this in a pleasant way1.
Construction of objects that have fields that have minimum cardinalities can be tricky, especially if there are potentially circularities involving those fields.
One way to deal with construction is to separate the lifecycle of the objects into a "construction" phase and a "completed" phase. During the construction phase, the constraints are relaxed, to allow the construction to be performed in stages. At some point, a "completed" switch is "flipped". At that point 1) the cardinality constraints are checked, and 2) the behavior of mutating operations is changed to prevent changes that would violate cardinality.
This can be implemented using public constructors and a public method to "flip the switch". Alternatively, you can implement this using the builder pattern; e.g.
make the constructors private
use alternative private means to side-step the cardinalities while building
check the cardinalities and flip the switch (it one is needed) in the build() method.
Another approach is to allow fields to be below cardinality, but only allow items to be added to the fields when they are in that state. In other words, this is the "flip the switch" approach without an explicit switch. The downside is that a client needs to test if the cardinality constraint is in force yet; i.e. the constraint is weak.
1 - In theory, you could implement a ListOfTwoOrMore interface, etcetera, but that would bring a raft of new problems.
One way to do that is use a different type for the field. Now it has type List<String> which is a collection that can contain 0 or more elements. You can change it to a type which represents a list that contains 2 or more elements.
You could use var-args in constructor.
public MyClass(String s1, String s2, String... rest){
}

Defining states for a FSM with n states. (java)

I have never worked with enum State before and recently came across it, I've found that to define a FSM where YOU, the programmer, knows the states the code is something like this:
enum States {state0, state1, state2}; //an example of a state machine with 3 states as defined by the programmer.
but I want to be able to define a FSM where the user decides how many and what states there are, is there a way to do this?
You cannot use enums here, which have a fixed size, but I guess you can do something like this :
public class StateMachine {
// it is up to you to define what a State and a Transition are
private Set<State> possibleStates;
private Set<Transition> transitions;
private State currentState;
// methods for adding and removing states
// ...
// methods for adding and removing transitions
// ...
}
Unfortunately, there is no great way to make run-time enums. There are, however a few other options:
Use an int to represent your state. This is simple and efficient, but can be confusing and difficult to understand later, as an int doesn't tell you much about what the state means. This can be partially mitigated by storing a map from Integer(state) to String (description of that state)
Create an immutable class to represent a state, or wrap an existing one like String. Make instances of the class only available through a static factory method which restricts the states given out to the subset you need, and internally keep a set of all instances, providing them when the same state is asked for twice from the factory method.This will allow equality comparison by reference, and creates similar semantics to enums.
There is the separate problem (which arises on both options) of deciding on action based on state, because the state is only defined at runtime, you cannot use a switch statement. A linear search, equivalent to chained if statements, scales poorly with the number of states. This problem can be solved by creating a hash table (or binary tree, if you wish) from states to whatever code you want to execute: (Java 8)
HashMap<State, Function<State, State> stateTransitions;
This system provides enum-like semantics at runtime, with reasonably good (constant time "switch") efficiency.

Categories