Enum practices - Define inside a class/separately, make public/private - java

What is a good practise when defining an enum?
For example, I have a Person class. For this class I have chosen to use an enum which has the values MALE and FEMALE.
Should the enum be defined inside the Person class or separately? Should the enum be defined as private or public? Also, do you have any further advice that would make using an enum as flexible as possible?

IMHO, make it a public static enum inside class Person.
The reason is the enum Gender applies only to Person, so put it in there so they're bound together (Gender has no use without the context of a Person).
The upside:
less class bloat
if you move Person to another package/project, Gender will always come with it
Person, who is the only user, has "control" of it and may alter it as it wants, eg
adding private List<HealthIssue> genderSpecificHealthIssues;
adding more enums, eg TRANSGENDER, INTERSEX, or whatever
The only downside is you must use a static import to use it, ie import static com.company.Person.Gender.*;.
This pattern is seen in many JDK classes, such as Calendar which defines the many date-related constants it uses inside the class.

For full flexibility, add it to a static class. But of course this is only and solely for enums that need to be used throughout the entire application. For local and specialized enums, it's better to keep them 'close' to where they'll be used. Exampli gratia, I have an IPHandler class that makes the handling, parsing and translating IPv4 and IPv6 addresses transparent for the class user (IPHandler is a static class). It has one enum, IPType, with values IPv4 and IPv6 that are only used within IPHandler for several operations. Since it's not used anywhere else, it's been defined within the IPHandler class.

Related

Is this proper enum practice in Java?

I just started learning enums in Java and although the concept seems straightforward, its application isn't really intuitive to me. I see that I can put enums inside of classes although they are classes themselves.
I also saw online some people say you can only have one enum in a class, or that you shouldn't put all enums in a single class unless they are put private.
Thus, I'm a bit confused, would this piece of code be a proper writing of enum?
Thanks.
public class AirCraft
{
private AirType type;
private AirFixTime maintainTime;
private enum AirType
{
HELICOPTER,
AIRLINE,
BALLOON,
GLIDER;
}
private enum AirFixTime
{
WEEKLY,
MONTHLY,
YEARLY;
}
}
Technically, your code is properly written. Uses of enums depends of the functionality. Remember that the access modifiers are used to manage what you going to share or show to others. Right now your code is correct if the enums is going to be used just inside AirCraft.
Take a look at this
You have a choice of three places to put an enum definition.
Class of its own.
Nested within another class.
Locally, within a method (Java 16, now previewed in Java 15)
Context is key
You can place your enum definition anywhere that makes sense to you. It all depends on context.
If your enum is meant to be used in other code, on its own, put the enum in its own class.
If the enum really only makes sense when used within the context of a
particular class, then nest the enum.
If the enum objects are used only within the parent class’ own source code, make the enum definition private.
If the enum objects might be used by outside code working with objects of the parent class, make the nested class public. For example, a report building class might want to sort aircraft parts by their assigned AirCraft.Color enum object, to gather together all the safety-orange parts.
For example, consider the Month and DayOfWeek enum classes built into Java as part of the java.time classes. These enum definitions live in their own separate classes because they may be used in many different contexts, without the involvement of other java.time classes. These enums could be used on their own in workflow apps, sales reports, accounting apps, and more.
In contrast, imagine a UI framework tracking mouse events. There we might find a Event enum for mouse events, defining objects named HOVER, CLICKED, and DRAGGED. This enum would best be housed within the Mouse class as it only has meaning within the context of the outer mouse-handling class.
Another example, colors.
An enum listing all the standard colors named in Cascading Style Sheets (CSS) should be in its own class, as many kinds of code may use that.
An enum listing colors used in color-coding parts of your aircraft should be nested within the AirCraft class, its only sensible context.
Usages:
myWebPage.setBackground( CssColor.DARK_SLATE_GREY ) ; // This enum could be used on its own with many classes in different frameworks. So define enum in a separate class..
myAircraft.getEmergencyStopButton().setColor( AirCraft.Color.SAFETY_ORANGE ) ; // This enum is only ever used in contexts using its parent class, so nest the enum definition.
If nesting, think about your naming. I would likely name the enum Color rather than AircraftColor, because the nested notation AirCraft.Color.x makes clear the context. On the other hand, some folks like to use a static import to be able to use Color.x without the AirCraft. prefix (not my preference).
Local enums
New in Java 16 will be local enums (previewed in Java 15). That means enums defined within a method.
This new feature seems to be documented only as a mention within the new Records feature: JEP 384: Records (Second Preview).
private void demoLocalEnum ( )
{
enum Color { PURPLE , SAFETY_ORANGE }
System.out.println( Color.PURPLE ) ;
}
As we can see in this screenshot, the enum only exists within the method containing its declaration. A sibling method on the same class does not know of the enum’s existence. In this example, trying to use the enum within another method generates an error within the IDE’s code editor.
Use this where your enum makes sense only within one chunk of code. If your enum is only used within a single method, then declaring it as a nested class draws undue attention. Being tucked away inside that method is more tidy.

Static final field in a class vs Interface field in java

I need to create a 100 or more static final constants in my application and I can achieve this is following two ways as per my understanding:
Creating a simple java class and create static final field in that
Creating an interface an put all variable in that because all field in an interface is implicitly static final
I have these question in above approach:
Which one is right approach to achieve this?
Which one is memory efficient approach?
Is there any design pattern to achieve this?
You can refer to many books about the topic.
I will quote a good one: "Effective Java"
Item 19: Use interfaces only to define types
The constant interface pattern is a poor use of interfaces. That a
class uses some constants internally is an implementation detail.
Implementing a constant interface causes this implementation detail to
leak into the class’s exported API. It is of no consequence to the
users of a class that the class implements a constant interface
you can even check where JDK mostly constants are declared..
Math.PI for example is declared in the class Math and not in an interface
and as an exception you can see constants like in the java.io.ObjectStreamConstants but again the Books are there to help:
From effective java again:
There are several constant interfaces in the Java platform libraries...
These interfaces should be
regarded as anomalies and should not be emulated.
I would not be thinking should they be in an interface or class, but more about the constants and their meaning.
I would not recommend putting all your constants in one place for the sake of keeping them together. If for instance a constant is directly related to a class then would say put it in that class. I have worked with code where all the constants ate bundled into one class, and I don't thing it is a good approach.
Have you considered approach with ENUM or it doesn't fit in your case?
I think, the approach with ENUM can gives you some benefits over constants.
Why use Enums instead of Constants?
I think that convenient way is to keep them in one place, if they are have common nature. Anyway, they should be grouped by some attribute. You can create class for them like this:
public final class Consts {
public static class GroupA {...}
public static class GroupB {...}
//and so on
}
With groups this class becomes much readable and a little bit better manageable. About memory consumption, try to use primitives for your constants, because they do not require additional space for meta information.
You can create Final or static constraint much as you like just by declaring field inside interface class so i would like to go with your option number 2

Final class with private constructor, what is the design principle

I was recently going through one of the Netflix open source project
There I found use of both final class along with private constructor. I fully aware that
final is to avoid inheritance
private is to disallow instantiation
But m just curious to know why they are both used together. Although methods are static, so we can use them without instantiation but still eager to know design principle behind it.
With this code you will have this features
Not allow anyone subclass (extends) your class
Not allow instantiating your class
Making a variables or classes final increase the performance (not much, but it does and used as common practice in big projects will make a difference)
In this case I can't see a singleton pattern to get an instance, so, IMHO, you're looking to a helper/util class in the Netflix API, where the developer team used some standard practices to ensure users use their classes in the correct way:
StaticFinalClassExample.methodYouWantToCall();
Also, looking at the class you linked:
/**
* This class consists exclusively of static methods that help verify the compliance of OP1A-conformant....
*/
And:
//to prevent instantiation
private IMFConstraints()
{}
ADD ON:
If you want further info, take a look at Item 4 from Joshua Bloch's Effective Java (2nd Edition):
Item 4: Enforce noninstantiability with a private constructor
Occasionally you’ll want to write a class that is just a grouping of static methods and static fields. Such classes have acquired a bad reputation because some people abuse them to avoid thinking in terms of objects, but they do have valid uses.
They can be used to group related methods on primitive values or arrays, in the manner of java.lang.Math or java.util.Arrays.
They can also be used to group static methods, including factory methods (Item 1), for objects that implement a particular interface, in the manner of java.util.Collections.
Lastly, they can be used to group methods on a final class, instead of extending the class.
Such utility classes were not designed to be instantiated: an instance would be nonsensical. In the absence of explicit constructors, however, the compiler provides a public, parameterless default constructor. To a user, this constructor is indistinguishable from any other. It is not uncommon to see unintentionally instantiable classes in published APIs.
Attempting to enforce noninstantiability by making a class abstract does
not work. The class can be subclassed and the subclass instantiated. Furthermore, it misleads the user into thinking the class was designed for inheritance (Item 17).
There is, however, a simple idiom to ensure noninstantiability. A default constructor is generated only if a class contains no explicit constructors, so a class can be made noninstantiable by including a private constructor.
That class consists of static so called "utility" methods, and therefore you don't need an instance of it, and further, it's WRONG to try to get an instance of it. The class is final so that a client developer doesn't have the option of coming along and extending the class, because that would be against the intention of the original class.
There are basically 2 uses for private constructors: to tightly control instantiation in the case of a class that you want to restrict creation of (for example, if it requires a ton of resources). In this first case, you have to provide static factory methods that create an object for the client.
ie:
public static IMFConstraints getInstance()
The other case is if it's never valid to make an instance. In that case, you provide static methods, which are called on the class itself. ie:
public static void checkIMFCompliance(List<PartitionPack> partitionPacks)
You would call the above method like so:
// your cool client code here...
IMFConstraints.checkIMFCompliance(myPartitionPacks);
// more of your awesome code...
The class you linked is the latter case.

Reasoning behind not using non-implemented Interfaces to hold constants?

In his book Effective Java, Joshua Bloch recommends against using Interfaces to hold constants,
The constant interface pattern is a poor use of interfaces. That a class uses some constants internally is an implementation detail. Implementing a constant interface causes this implementation detail to leak into the class’s exported API. It is of no consequence to the users of a class that the class implements a constant interface. In fact, it may even confuse them. Worse, it represents a commitment: if in a future release the class is modified so that it no longer needs to use the con-stants, it still must implement the interface to ensure binary compatibility. If a nonfinal class implements a constant interface, all of its subclasses will have their namespaces polluted by the constants in the interface.
His reasoning makes sense to me and it seems to be the prevailing logic whenever the question is brought up but it overlooks storing constants in interfaces and then NOT implementing them.
For instance,
public interface SomeInterface {
public static final String FOO = "example";
}
public class SomeOtherClass {
//notice that this class does not implement anything
public void foo() {
thisIsJustAnExample("Designed to be short", SomeInteface.FOO);
}
}
I work with someone who uses this method all the time. I tend to use class with private constructors to hold my constants, but I've started using interfaces in this manner to keep our code a consistent style. Are there any reasons to not use interfaces in the way I've outlined above?
Essentially it's a short hand that prevents you from having to make a class private, since an interface can not be initialized.
I guess it does the job, but as a friend once said: "You can try mopping a floor with an octopus; it might get the job done, but it's not the right tool".
Interfaces exist to specify contracts, which are then implemented by classes. When I see an interface, I assume that there are some classes out there that implement it. So I'd lean towards saying that this is an example of abusing interfaces rather than using them, simply because I don't think that's the way interfaces were meant to be used.
I guess I don't understand why these values are public in the first place if they're simply going to be used privately in a class. Why not just move them into the class? Now if these values are going to be used by a bunch of classes, then why not create an enum? Another pattern that I've seen is a class that just holds public constants. This is similar to the pattern you've described. However, the class can be made final so that it cannot be extended; there is nothing that stops a developer from implementing your interface. In these situations, I just tend to use enum.
UPDATE
This was going to be a response to a comment, but then it got long. Creating an interface to hold just one value is even more wasteful! :) You should use a private constant for that. While putting unrelated values into a single enum is bad, you could group them into separate enums, or simply use private constants for the class.
Also, if it appears that all these classes are sharing these unrelated constants (but which make sense in the context of the class), why not create an abstract class where you define these constants as protected? All you have to do then is extend this class and your derived classes will have access to the constants.
I don't think a class with a private constructor is any better than using an interface.
What the quote says is that using implements ConstantInterface is not best pratice because this interface becomes part of the API.
However, you can use static import or qualified names like SomeInteface.FOO of the values from the interface instead to avoid this issue.
Constants are a bad thing anyway. Stuffing a bunch of strings in a single location is a sign that your application has design problems from the get go. Its not object oriented and (especially for String Constants) can lead to the development of fragile API's
If a class needs some static values then they should be local to that class. If more classes need access to those values they should be promoted to an enumeration and modeled as such. If you really insist on having a class full of constants then you create a final class with a private no args constructor. With this approach you can at least ensure that the buck stops there. There are no instantiations allowed and you can only access state in a static manner.
This particular anti-pattern has one serious problem. There is no mechanism to stop someone from using your class that implements this rouge constants interface.Its really about addressing a limitation of java that allows you to do non-sensical things.
The net out is that it reduces the meaningfulness of the application's design because the grasp on the principles of the language aren't there. When I inherit code with constants interfaces, I immediately second guess everything because who knows what other interesting hacks I'll find.
Creating a separate class for constants seems silly. It's more work than making an enum, and the only reason would be to do it would be to keep unrelated constants all in one place just because presumably they all happen to be referenced by the same chunks of code. Hopefully your Bad Smell alarm goes of when you think about slapping a bunch of unrelated stuff together and calling it a class.
As for interfaces, as long as you're not implementing the interface it's not the end of the world (and the JDK has a number of classes implementing SwingConstants for example), but there may be better ways depending on what exactly you're doing.
You can use enums to group related constants together, and even add methods to them
you can use Resource Bundles for UI text
use a Map<String,String> passed through Collections.unmodifiableMap for more general needs
you could also read constants from a file using java.util.Properties and wrap or subclass it to prevent changes
Also, with static imports there's no reason for lazy people to implement an interface to get its constants when you can be lazy by doing import static SomeInterface.*; instead.

Constant Parameter Design

I am working with a Class that contains constants or parameter values that all classes can reference for example;
public class Parameters {
public static final String JUMP_TO_VALUE = "Parameters.JUMP_TO_VALUE";
public static final String EXCEPTION_ID = "Parameters.EXCEPTION_ID";
}
Some of the foundation classes in my application will use the parameter values in the Parameters class like so:
mapOfValues.put( Parameters.JUMP_TO_VALUE, "some_value")
This is simple enough I have some basic values in Parameters that most of my base classes will use them. There will be many situations where I will need to add addition parameters to the Parameters class, but I don't want to over populate or pollute the Parameters class ever time a new parameter is identified. I would rather create some subclass of Parameters like:
public class NetworkParameters extends Parameters {
public static final String HOST_NAME = "NetworkParameters.HOST_NAME";
public static final String POST_NUM = "NetworkParameters.PORT_NUM";
}
Some of my specific classes will use the values that are contained in this class versus putting them in the Parameters class.
These specific classes that need HOST_NAME for example I don't want them to reference the NetworkParameters class but rather the Parameters class.
I am sure people have done this before but I am looking for advice on how best to implement this design.
It is simply not possible, in the exact way you describe it.
When you reference static objects, you refer to the class that those objects are declared in. Quite simply, if you declare a constant in the NetworkParameters class, it does not exist in the Parameters class and is not accessible as such.
Separating vast numbers of parameters into different containing classes (which don't need to be subtypes of each other as this achieves nothing) is quite good practice and often used. Why do you have such an aversion to just using NetworkParameters.POST_NUM, as this is the name of the parameter and sounds completely sensible to me?
One thing that may help you (depending on your own tastes) is to use Java 5's static import feature. If, at the top of a class file, you declare
import static the.package.name.Parameters.*;
import static other.package.NetworkParameters.*;
then you will be able to use all of the constant names from both classes without any prefix at all. This is often quite nice when it's obvious what comes from where - but it can become a nightmare if you're statically importing from a few classes, especially if you don't have an IDE to work out the reference for you.
But again - why do you want to reference them as Parameters.FOO, but want them to live in a separate class? Either approach (everything in one file, different constants in different files) is good and fine if you do it completely, but you can't magically change the laws of Java references because you don't like the look of them. :-)
I don't think you would be overdoing it by putting a lot of constants in a single file. Just keep it well organized with good formatting and documentation. I dont think subclassing is want here. A subclass implies a certain relationship among objects. First off, you aren't really creating an object, so creating a subclass does not really fit the model here. Also, using a subclass here may just complicate things. For example, you will have to import multiple java files if you want to use several types of constants in another class.
Are you sure you want to be embedding these values in your code?
They sound to me like the kind of data you want to place in a configuration file, so they can be change easily without the code needing to be recompiled. A simple hash of name-value pairs from a configuration file, wrapped to be accessible in the way you need them to, might be a more flexible approach to the same problem.

Categories