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.
Related
Are there any advantages of using Tuples instead of creating a new class in Java?
I've seen something like this a few times
return Pair.of (username, password);. And I've always wondered what kind of advantages it has in relation to something like this return new Credentials (username, password).
Java doesn't have a (first class) notion of tuples. Some projects and libraries introduce types like Pair or Tuple2/Tuple3/Tuple4/... to make up for it, but this is often considered poor style in Java.
By contrast returning a clearly-defined type like Credentials that provides not just structure but also type safety and meaningful getters for your data you make your code clearer, safer, and easier to work with. The Auto/Value project in particular makes it quick and painless to create value-types, making tuple-esque types all but unnecessary.
A Pair (Apache) is immutable, for one. You cannot change it’s values after creation. Many people do in fact choose to create their own class and add methods as necessary.
In general it’s considered better practise to make your own class. You can validate parameters and so on and have the ability to add additional functionality if the need arises.
As dimo414 says, the Pair class is often encountered in 3rd party libs; it has two advantages:
it makes defining a separate class for each key/value pairing unnecessary; so you don't need to define a Credential class. Of course, this should only be used to temporarily store data, not to be used within your implementation model.
Even if you do have a Credential class already, usually Pair is immutable, while the Credential class may not be. That means that it may provide setUsername() and setPassword() methods which you don't always want; using a Pair class makes sure both key and value remain unchanged.
First post so I hope this is an appropriate type question for this site. If not I'd appreciate it if someone could direct me to a more appropriate place. I'm extremely new at programming. I did a bit in high school and have recently decided to relearn starting with making a text-based survival game in Java7 using Eclipse.
Right now I'm coding the location superclass. The particular function I need help with is this: it needs to be able to keep track of which of 9 regions the user currently "is in" (which is then used in a large number of other classes for many various purposes. The location class also includes functionality for accepting user input to move to a new region, among various other things.) The way I started this was by making a boolean variable for each region and whenever a transition should occur that variable is set to true. But now I'm wondering if this is the most efficient way to do this. I have to take String inputs, run a method to standardize various acceptable answers into one, and then run it through a switch statement that makes the corresponding boolean variable true?
Would it be simpler to simply keep track of the location with a single String variable that gets set as whatever region the player is in? Or would that be more likely to cause errors or complications when coding? Would an array better suit this need? edit: (I just want to thank you guys for people such an open and helpful community. Its really appreciated.)
BIG EDIT: I wanted to further elaborate on what the regions will eventually do. In each region there will eventually be a handful of places the user can go to that are generic with a small number of places unique to each location. Other major superclasses would be altered depending on what region the user is in (example: my "encounters" superclass would have variables that dictate how likely certain encounters are to happen (i.e. chance to a hostile attack) and these variables would be altered depending on the region) but also by other instances (The "Time" superclass would keep track of the day and time of day which would also effect the variables in "encounters".) The current plan was to make a class for each generic place (i.e. Walmart, technology store, grocery, public park, etc.) They would contain different properties depending on the region and would also effect classes like "encounters". I was going to have their properties defined by if/else & switch statements depending on what region the user was in. But now I'm realizing it would make more sense to define their properties when I create the object.
While a lot of people are steering me to enums, some are also suggesting I make classes for each region, (and I am also hearing about interfaces.) If I were to go with the 2nd route I have 3 questions: (a) If the region classes were all subclasses to "Location", then wouldn't I have a problem creating objects for all the generic places inside the region classes (i.e. Walmarts) because the Walmart class can only belong to one superclass? (If not what is the difference between an object being created in a class and the actual relationship between a superclass and its subclasses) (b) If I initialized each region as an object instead of simply recording it with a variable, how would I achieve the original task of remembering which region the user is in (for functions as simple as printing the region out to making alterations to variables in classes like "encounters"). Wouldn't I still need to have some sort of variable to identify the region? And if so, that what practical purpose does creating classes for the region accomplish? (I can see this might still let me make the code cleaner by housing the variables that interact with "encounters" instead of having to use if/else/switch statements inside the "encounters" class (also in this case how could I make the variables in the region classes interact with the variables in "encounters" since neither belong to each other) but anything else?) (c) Would it make more sense to create classes for every region or a single region class that gets defined differently when initialized and WHY?
Finally, I know I may have asked too many questions but could someone please explain to me the different utilities found in enums and interfaces (I'm especially interested in hearing about enums) and now that you know a little bit more, should I be using enums, interfaces, or some sort of classes for the regions? Thank you guys so much!
Enum is very recommended, as stated by Vasily Liaskovsky.
Using int is a great way as well. For example:
int currentRegion;
static final int region1 = 0;
static final int region2 = 1;
static final int region3 = 2;
etc...
Make sure the region1 etc are stated final, so their IDs cannot be changed afterwards, static reference could save memory if you're using multiple location superclass objects, also easier accessible outside the class.
This way to check if you're in a certain region, just use a if statement:
if(currentRegion == region1) {}
To set it:
currentRegion = region1;
Simple as that
I disagree with the usage of an enum here. An enum is great, but not extendable. What if you want to add another region?
So just create classes, and pass them around. They might hold some form of string as identifier (but you should load the proper name from a file that can be localized, anyways).
With a proper class, you can easily add new transitions betwen regions (make your region class a graph) and much more.
Region current = ...;
List<Transition> neighbours = current.getNeighbours();
foreach (Transition t : neighbours)
System.out.println("To the " + transition.getDirection() + " is the " + transition.getTargetName());
// prints e.g. "To the north is the shadowy jungle"
There are a lot of ways todo this, and in an OOP language, you should really try to get into the mindset of using objects instead of setting integer flags or else.
Take a look on enum.
If the list of 9 regions should not grow as game develops, you can describe each of them in hardcoded fashion also utilizing power of objects. Enums can have custom properties and methods weawing them into your architecture, and also enums provide some extra benefits such as == comparison and using in switch blocks.
EDIT
I don't understand why this future addition might make enums a less desirable route
The only way to add an option to enum is to rewrite its class source code. That is, enum options are defined statically and in larger projects when developers should deal with product versions, compatibility, delivering to end-users etc., this could be a pain. In fact, any change in source code of published project is undesirable, since it requires recompilation and full rebuild of at least one (in best case) application module.
The way to deal with it is to move modifiable data into some resource (this can be a file, database table, plugin or anything easily modifiable without full rebuild) and make your application to initialize itself on startup in runtime. Since from this point your program no longer knows that data in advance, statically, there is no way you could define enum describing that data. And in this scenario custom classes (Polygnome's answer) will do the job. Your program reads the resource, creates and initializes objects in runtime that describe your configuration and uses dynamic data.
IMHO, there is almost always tradeoff beween flexibility and complexity. You gain flexibility and freedom to modify region list, but you have to deal with complexity of dynamic solution. Or you decide to use much simpler enums understanding their limited extensibility.
Btw, in order of growing flexibility (and complexity):
raw primitives (int/String) | enums | custom classes
I have been reading a lot of posts on this site regarding the usage of constants.
Question:
When should I use Enums for constants, vs using classes or interfaces.
I see 2 key situations I am looking to address.
1. Global Constants used in a applications by multiple projects.
Example:
Common logging strings
Container references like a database mapping reference used in
WebSphere EAR's
2. Object Specific Constants
Example:
Employee pay rates for an Employee Object
From everything I have read this is what I think I have a grasp on and what I am looking for an opinion on.
For situation 1:
Design Approach: Use a final class and a static import.
Seen here: What is the use of interface constants?
For Situation 2:
Design Approach: Apply the use of Enums to represent those constants as a object.
Additional points to remember:
If the constant string belongs to the class and you only need the string value keep in the class that uses it
Don't use an Interface for situation 1. As mentioned in the link above as Constant Interface Anti-pattern.
.
Thanks in advance for thoughts and opinions.
Global constants as you put it should actually be in a properties file as it allows each application to configure them individually without a code modification. For object specific constants my general rule of thumb on Enum versus static final I typically lean towards how many elements there are to have and how related those elements are. If there is a big relation between them such as Suits in a deck of Cards then I would go for the enum. If it is default age for a user, then this becomes a final as there is no purpose to making it an enum as it would not need to be referenced in many areas. These are just some thoughts on each of the ways I have approached it.
Global constants used by different projects: Enum
Better to use Enum over public static final members in a class. More clean and easy to understand I guess.
Object specific constants: public static final members in Class. Because, they are needed only within the scope of the object, then no need to created a new Enum for that.
Nice read
Update (fixed broken link):
Making the Most of Java 5.0: Enum Tricks
Making the Most of Java 5.0: Enum Example
It sounds like almost everything you've listed for both numbers 1 and 2 belong in configuration files or database tables.
Do you want to re-compile code when your employee's get a raise or a page name changes?
Unless there is a compelling reason everything else that is constant should be modeled as an enum. This way you realize the benefits of fast object equality comparisons and you avoid problems associated String constants.
The scope of those enums however is application specific. If the enumeration is only used by a class that it should be a private enum. If it is shared by multiple classes then it should be in its own class definition file.
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.
We recently had a code review . One of my classes was used so that I could return/pass more than one type of data from/to methods . The only methods that the class had were getters/setters . One of the team's members ( whose opinion I respect ) said that having a class like that is bad practice ( and not very OOP ) . Why is that ?
There's an argument that classes should either be "data structures" (i.e., focus on storing data with no functionality) or "functionality oriented" (i.e., focus on performing certain actions while storing minimal state). If you follow that argument (which makes sense but isn't always easy to do) then there is nothing necessarily wrong with that.
In fact, one would argue that beans and entity beans are essentially that - data containers with getters and setters.
I have seen certain sources (e.g., the book "clean code") arguing that one should avoid methods with multiple parameters and instead pass them as a single object with getters and setters. This is also closer to the "smalltalk model" of named parameters where order does not matter.
So I think that when used appropriately, your design makes sense.
Note that there are two separate issues here.
Is a "struct-like" class sensible?
Is creating a class to return multiple values from a method sensible?
Struct-like classes
An object class should -- for the most part -- represent a class of real-world objects. A passive, struct-like java bean (all getters and setters) may represent a real-world thing.
However, most real-world things have rules, constraints, behaviors, and basic verbs in which they engage. A struct-like class is rarely a good match for a real-world thing, it's usually some technical thing. That makes it less than ideal OO design.
Multiple returns from a method
While Python has this, Java doesn't. Multiple return values isn't an OO question, per se. It's a question of working through the language limitations.
Multiple return values may mean that an object has changed state. Perhaps one method changes the state and some group of getters return the values stemming from this state change.
To be honest, it sounds fine to me. What alternative did the reviewer suggest?
Following OOP "best practices" and all is fine, but you've got to be pragmatic and actually get the job done.
Using Value Objects like this (OO speak for 'struct') is a perfectly legitimate approach in some cases.
In general, you'll want to isolate the knowledge needed to operate upon a class into the class itself. If you have a class like this, either it is used in multiple places, and thus can take on some of the functionality in both of those places, or it is in a single place, and should be an inner class. If it is used in multiple ways, but in completely different ways, such that there is no shared functionality, having it be a single class is misleading, indicating a shared functionality where there is none.
However, there are often specific reasons for where these general rules may or may not apply, so it depends on what your class was supposed to represent.
I think he might be confusing "not very OOP" for bad practice. I think he expected you to provide several methods that would each return 1 value that was needed (as you will have to use them in your new class anyway that isn't too bad).
Note that in this case you probably shouldn't use getters/setters, just make the data public. No this is "not very OOP" but is the right way to do it.
Maybe Josh Bloch offers some insight into this here.