The right and wrong approach to writing Java Enums - java

Recently, I've discovered this code of the following structure:
Interface:
public interface Base<T> {
public T fromValue(String v);
}
Enum implementation:
public enum AddressType implements Base<AddressType> {
NotSpecified("Not Specified."),
Physical("Physical"),
Postal("Postal");
private final String label;
private AddressType(String label) {
this.label = label;
}
public String getLabel() {
return this.label;
}
#Override
public AddressType fromValue(String v) {
return valueOf(v);
}
}
My immediate reaction is that one cannot create an instance of an enum by deserialization or by reflection, so the fromValue() should be static.
I'm not trying to start a debate, but is this correct? I have read, Why would an Enum implement an interface, and I totally agree with the answers provided, but the above example is invalid.
I am doing this because the "architect" doesn't want to take my answer, so this is to create a strong argument (with facts) why the above approach is good/bad.

Your Base interface does not declare valueOf and the fromValue method is indeed implemented. I see no reason why this code should not compile. If you are referring to the valueOf call inside fromValue, that is a call of a static method defined for every enum. I would have to agree, though, that the design of it is quite misguided as you need an arbitrary member of the enum just to call fromValue and get the real member.
On the other hand, in a project that I'm doing right now I have several enums implementing a common interface. This because the enums are related and I want to be able to treat them uniformly with respect to their common semantics.

In my opinion this design is wrong. In order to use valueFrom() one has to get an instance of this enum beforehand. Thus, it will look like:
AddressType type = AddressType.Postal.valueFrom("Physical");
What sense does it make?

Your Base interface seems to serve a whole other purpose (if any).
It is probably meant to be a String-to-T-converter, since it generates a T from a String. The enum is simply wrong if it implements this interface (#yegor256 already pointed out why). So you can keep the enum and you can have some AddressTypeConverter implements Base<AddressType> which calls AddressType.valueOf() in its fromString() method.
But don't get me wrong: enums implementing interfaces are NOT a bad practice, it's just this particular usage that is completely wrong.

Related

Java Interface that forces implementation of an enum - How to approach?

I have a situation where I would like to used an instance of an object called Abstraction, which would be a Java interface looking something like:
public interface Abstraction {
public enum Actions {
}
}
The idea being that any class implementing Abstraction has to implement enum Actions (I realise this doesn't work).
A class implementing the interface may look like:
public class AbstractionA implements Abstraction {
public enum Actions {
f, c, r, a
}
}
In another class I would want to create an Abstraction object like:
Abstraction abs = new AbstractionA();
and then be able to access the enum values applicable to the Abstraction object created, e.g.
abs.Action.r;
I realise my approach to this is all wrong but cannot see an appropriate way to handle this type of situation. How can I implement something like this where different implementations of the interface have a varying subset of the options I would generally want to put in an enum?
Perhaps I can implement the enum with all possible options in the interface and then somehow restrict implementations of the interface to using a subset of those enum values?
EDIT:
Another example implementation might be
public class AbstractionB implements Abstraction {
public enum Actions {
f, c, b, r, a
}
}
I think I have figured out a way forward with this:
public interface Abstraction {
public enum Actions {
f, c, b, r, s, a
}
public Actions[] availableActions();
}
Then implement with:
public class HunlAbstractionA implements Abstraction{
#Override
public Actions[] availableActions()
{
Actions[] actions = new Actions[] {Actions.f, Actions.c, Actions.r, Actions.a};
return actions;
}
}
This way I have access to all possible actions listed in the interfaces enum and can make checks to ensure an Action to be dealt with is one of the availableActions for the created class.
Recommendation
I'd recommend the following approach.
This approach uses a combination of generics and reflection to help explicitly indicate the need to implement or choose an appropriate enum, it also gives you the option of preserving information about the enum type whilst hiding all other information about the specific Abstraction implementation.
/**
* An abstraction with an implementation-defined enum
* #param <E> your custom enum.
*/
interface Abstraction<E extends Enum> {
//this gives you the enum constants as a list
Class<E> getEnumType();
}
class AbstractionA implements Abstraction<AbstractionA.EnumA> {
enum EnumA {
FOO,
BAR
}
#Override
public Class<EnumA> getEnumType() {
return EnumA.class;
}
}
class AbstractionB implements Abstraction<AbstractionB.EnumB> {
enum EnumB {
FOO,
BAR
}
#Override
public Class<EnumB> getEnumType() {
return EnumB.class;
}
}
Note that unfortunately we can supply a default implementation of getEnumType() due to type erasure.
Usage Example
class Main {
public static void main(String[] args) {
Abstraction myAbstractionA = new AbstractionA();
Abstraction<AbstractionB.EnumB> myAbstractionB = new AbstractionB();
Class enumAType = myAbstractionA.getEnumType();
Class<AbstractionB.EnumB> enumBType = myAbstractionB.getEnumType();
Object[] enumsA = enumAType.getEnumConstants();
AbstractionB.EnumB[] enumsB = enumBType.getEnumConstants();
System.out.printf("Enums of the same order are still non-identical: %s", enumsA[0].equals(enumsB[0]));
System.out.println();
Enum enumA = ((Enum)enumsA[0]);
Enum enumB = ((Enum)enumsB[1]);
System.out.printf("We can get enum constants in order, and get the orderinal of the enum: A=%s, B=%s", enumA.ordinal(), enumB.ordinal());
System.out.println();
enumA = Enum.valueOf(enumAType, "FOO");
enumB = Enum.valueOf(enumBType, "BAR");
System.out.printf("We can get enum constants by name and get the name out of the enum: A=%s, B=%s", enumA.name(), enumB.name());
System.out.println();
}
}
Alternatives
If you can use an abstract class instead of an interface, you may prefer a solution similar to this related answer.
Edit: If you have a common set of constants you want to share across your actions, you should probably use a global/shared enum for those constants and define only the extensions themselves in the custom Abstractions. If you cast them all to Enum and use .equals() as needed, this should work in most cases.
Background
As you have stated you know, it is not possible to place member objects (variable or classes) of an interface.
However, the good news is that java actually supports the behaviour you want pretty well.
There are 3 key features that relate to my recommendation:
Enums are Objects
Firstly, enums in java are fully-fledged Objects, which all extend java.lang.Enum, and all implement .equals().
So, you can store different any enum class' values in a variable of type java.lang.Enum and compare them with .equals().
And, if you want to pretend that values of different enum classes are the same because they share the same name (or are the nth constant in their respective class), you can do that too.
Note that this also means that custom enums can contain complex data and behaviour like any other class, beyond it's use as a unique identifier.
See the Enum API documentation for details.
Java Reflection
Secondly, Java has extensive reflection support. For our purposes, java.lang.Class has a method called getEnumConstants() for getting the enum constants (or null if the class is not an enum).
See the Class API documentation for details.
Cyclic Dependancies
Thirdly, at least when it comes to generics, Java is permissive when it comes to cyclic dependancies, so you can define a generic interface depends on a specialisation of that generic. Java won't mind.
Interface is a contract that you want anyone to provide an implementation of that contract. In your example code you do not have a method but a definition of a enum called Action.
Generally enum is a set of constants hence we do not expect multiple classes to come up with different implementations of the same constant.
So you might want to rethink about your approach and figure out a better way. Hope this will help moving you in correct direction.

Java: Edit objects without type the name

in some programming languages you can say something like this:
do with button1 {
setName("Button");
setVisible(true);
...
}
I mean you said that the next (between {}) is for an component and so you don't need to type the name befor, like this
button1.setName("Button");
button1.setVisible(true);
...
My question is now can I do something like that in Java?
Moritz
PS: I know that the examples don't work. They are only for demonstration.
There is not exactly that in Java, but there is something similar.
Builder Pattern
It looks like this:
Button button1 = new ButtonBuilder()
.setName("Button")
.setVisible(true)
...
.build();
Obviously this can only be used when you initialise objects.
For an example of a Builder Pattern implementation, just search on Google! I found this: https://sourcemaking.com/design_patterns/builder/java/2
Something that looks like the thing you want is method chaining:
new Button()
.setName("myButton")
.setVisible(true)
.setPreferredSize(200, 100);
The condition to achieve something like that is that the method returns the instance it is performing on:
class Button {
public Button setName(String name) {
this.name = name;
return this;
}
}
This is often used in combination with the builder pattern.
It looks like you want to do that with Swing elements like JButton, but unfortunately, those components do not use method chaining.
There is no such syntax in Java.
You have to specify the object you want to operate on for each method call.
When you create your own objects, you can have all your set methods return themselves and then call the next method...
You cannot do that in Java, however, for objects you create you can use chaining to get a similar look and feel to some extent.
public class MyClass
{
private String name;
private int value;
private MyClass parent;
private MyOtherClass thing;
public MyClass setName(String _name)
{
name = _name;
return this;
}
public MyClass setValue(int _value)
{
value = _value;
return this;
}
public MyClass setParent(MyClass _parent)
{
parent = _parent;
return this;
}
public MyOtherClass setThing(MyOtherClass _thing)
{
thing = _thing;
return this;
}
// and some getters would likely be defined too, but I'll not list them here
}
Then, to use it, you could do something like...
class A
{
public void f(MyClass o)
{
o
.setName("Me")
.setValue(1)
.setParent(new MyClass())
.setThing(new MyOtherClass())
;
}
}
I actually like this style and use it in some of my own code. It makes the code easier to read, and I think it is cleaner looking.
This doesn't do quite the same thing as your example, but it fulfills a lot of the underlying desire to reduce redundancy.
What you show is a fluent API.
It may be used for builders but also to simply chain function/method invocations on a object.
This is not a feature that works only for specific languages.
It may indeed work for any language that relies on the Object paradigm.
But to use it, the specific API that you are using has to provide this feature, that is, providing methods that return the object itself.
In the case of Java Button, Swing as JavaFx don't provide a fluent API for this class.
So you cannot use a fluent builder or methods out of the box.
Indeed, you have to implement it yourself.
None of the other answers so far addressed the ambiguity that this syntax creates.
If you write a method without prefixing the instance like in setName("Button");, this means to implicitly call this.setName("Button"); (or MyClass.setName("Button"); if my class had a static method of that name).
Your proposed syntax extension would add to the ambiguity of setName("Button"); meaning this.setName("Button"); or MyClass.setName("Button"); or now also button1.setName("Button");.
Of course, such an ambiguity could be resolved by defining a priority rule, e.g. to first look for button1.setName("Button"); and then for this.setName("Button");. But all such implicit rules make reading and understanding such a piece of code more difficult. The more explicitly some piece of code tells me what it does, the better.
Personally, even if Java allowed this syntax, I'd never use it nor encourage my co-workers to use it.
By the way, I typically create JButtons based on Actions already carrying the name and the icon, so I hardly ever set a button's name.

Abstract vs Empty method

I need to add one optional method in existing abstract class that is extended by more than 50 classes:
public abstract class Animal{...}
This method is not used by all those classes, but in the future it probably will.
The structure of one of my classes is:
public class Dog extends Animal {...}
The cleanest way is using abstract method but it obliges me to change all existing classes.
The workaround is to create "empty" method in abstract class:
public String getString(Map<String, Object> params){
return "";
}
and then override it when I need in classes that extend abstract class.
Is there any better solution?
Having an "empty" method is fine. But in order to be sure, that it will be implemented where it is really needed, consider throwing an exception by default from this method:
throw new UnsupportedOperationException();
A similar approach is used in java.util.AbstractList class:
public E set(int index, E element) {
throw new UnsupportedOperationException();
}
I can't help feeling like you have some architectural/design issues here, but without knowing more, I can't say for sure. If 50 classes are going to inherit from Animal, but not all of them are going to use this method, then I'm wondering if they should really inherit from one common class. Perhaps you need further levels of sub-classing... think Kingdom->Phylum->Sub-Phylum. But my gut says that's still not the right answer for you.
Step back - what are you trying to accomplish? If you're going to implement this function on these classes in the future, then you must also be changing your code to know to use/expect this. The point of inheritance is to allow code to refer to an object's expected common behavior without knowing what type of object it's referencing. In your getString() example, you might have a function as such:
public string SendMessage(Animal someAnimal) {
string message = someAnimal.getString();
// Send the message
}
You can pass it a dog, a cat, a platypus - whatever. The function doesn't care, because it can query the message from its base class.
So when you say you'll have animals that don't implement this message... that implies you'll have logic that ensures only cats and dogs will call this function, and that a platypus is handled differently (or not at all). That kind of defeats the point of inheritance.
A more modern approach would be to use interfaces to establish a "has a" relationship instead of an "is a" relationship. A plane might have an IEngine member, but the specific type of engine can be set at run-time, either by the plane class itself, or by the app if the member is writeable.
public interface IEngine {
string getStatus();
string getMileage();
}
public class Cessna {
public IEngine _engine;
public Cessna() {
_engine = new PropellerEngine();
}
}
You could also inherit directly from that interface... Animals that don't implement IAnimalMessage wouldn't implement that function. Animals that do would be required to. The downside is that each animal will have to have its own implementation, but since your base class currently has an abstract function with no body, I'm assuming that's a non-issue. With this approach, you can determine if the object implements the interface as such:
IAnimalMessage animalMessage = myPlatypus as IAnimalMessage;
// If your playtpus doesn't implement IAnimalMessage,
// animalMessage will be null.
if (null != animalMessage) {
string message = animalMessage.getString();
}
public interface IAnimalMessage {
string getMessage();
}
public class Platypus : IAnimalMessage {
// Add this implementation when Platypus implements IAnimalMessage...
// Not needed before then
public string getMessage() {
return "I'm a cowboy, howdy, howdy, howdy!";
}
}
That's probably the closest to what you're asking for I can suggest... classes that don't need the message won't implement that interface until they do, but the code can easily check if the interface is implemented and act accordingly.
I can offer more helpful/specific thoughts, but I'd need to understand the problem you're trying to solve better.

composition-and-forwarding approach for a class with two Lists

I have read Item 16 from Effective Java and
Prefer composition over inheritance? and now try to apply it to the code written 1 year ago, when I have started getting to know Java.
I am trying to model an animal, which can have traits, i.e. Swimming, Carnivorous, etc. and get different type of food.
public class Animal {
private final List<Trait> traits = new ArrayList<Trait>();
private final List<Food> eatenFood = new ArrayList<Food>();
}
In Item 16 composition-and-forwarding reuseable approach is suggested:
public class ForwardingSet<E> implements Set<E> {
private final Set<E> s;
public ForwardingSet(Set<E> s) {this.s = s;}
//implement all interface methods
public void clear() {s.clear();}
//and so on
}
public class InstrumentedSet<E> extends ForwardingSet<E> {
//counter for how many elements have been added since set was created
}
I can implement ForwardingList<E> but I am not sure on how I would apply it twice for Animal class. Now in Animal I have many methods like below for traits and also for eatenFood. This seems akward to me.
public boolean addTrait (Trait trait) {
return traits.add(trait);
}
public boolean removeTrait (Trait trait) {
return traits.remove(trait);
}
How would you redesign the Animal class?
Should I keep it as it is or try to apply ForwardingList?
There is no reason you'd want to specialize a List for this problem. You are already using Composition here, and it's pretty much what I would expect from the class.
Composition is basically creating a class which has one (or usually more) members. Forwarding is effectively having your methods simply make a call to one of the objects it holds, to handle it. This is exactly what you're already doing.
Anyhow, the methods you mention are exactly the sort of methods I would expect for a class that has-a Trait. I would expect similar addFood / removeFood sorts of methods for the food. If they're wrong, they're the exact sort of wrong that pretty much everyone does.
IIRC (my copy of Effective Java is at work): ForwardingSet's existence was simply because you cannot safely extend a class that wasn't explicitly designed to be extended. If self-usage patterns etc. aren't documented, you can't reasonably delegate calls to super methods because you don't know that addAll may or may not call add repeatedly for the default implemntation. You can, however, safely delegate calls because the object you are delegating to will never make a call the wrapper object. This absolutely doesn't apply here; you're already delegating calls to the list.

Good practice to instantiate classes from an enum value

I've been searching to many places but I didn't find a good answer for my problem:
I have an enum, for example:
public enum Window { CLASSIC, MODERN }
and I need to separate the behavior of my application according to the enum value, like that:
switch (myWindow.getType()) {
case CLASSIC: new ClassicWindow(...);
case MODERN: new ModernWindow(...);
}
I know what you think: simply put that in the enum and basta, however this is not the only class depending on my enum! And I can't write as many object creation methods as I have objects!
Simply put, what can I do in this situation? A friend of mine said to me to get rid of the enum and to use derived classes everytime, but in the end I'd have to create as many instances as subclasses for all my tests!
In short, I'm stuck.
Do you know a best practice for that? Thanks
You seem to be looking for a design pattern, rather than good practices for using enums. The code you're intending to write will be full of switch statements, with one condition for each possible value of the enum - making it hard to maintain and extend in the long run. A better idea would be to refactor each possible case's behavior in a separate class, maybe using the Abstract Factory pattern.
This is the factory pattern. This example actually shows exactly what you're doing.
You could either implement an interface in your enum and have them act as a factory:
interface WindowBuilder {
Window makeWindow();
}
enum WindowType implements WindowBuilder {
SIMPLE {
public Window makeWindow() { return new SimpleWindow() }
},
[... other enums]
}
or you could use reflection and bind a class to the enum type to have them (again) work as a factory:
enum WindowType {
SIMPLE(SimpleWindow.class),
[... other enums]
private final Class<? extends Window> wndType;
private WindowType(Class<? extends Window> wndType) {
this.wndType = wndType;
}
public Window makeWindow() {
// in fact you will need to either catch the exceptions newInstance can throw, or declare the method can throw them
return this.wndType.newInstance();
}
}
Either way you will be able to call them like that afterward:
Window window = myWindow.getType().makeWindow();

Categories