I have a question regarding the best design pattern for code reuse when dealing with Java enums. Basically, what I'm trying to achieve is being able to define several enums that model static business collections (sets of constants), but I'd also like to share behavior between them, with minimal coding.
This is trivial to achieve with class inheritance from abstract classes but, since Java enums cannot be extended (they can only implement interfaces), this type of work is tedious and involves a lot of error prone copy/paste work (copying the code from enum to enum). Examples of "business logic" that should be shared among all enums includes converting from/to Strings, instance and logical comparison, etc.
My best shot right now is using helper classes in conjunction with business interfaces, but this only goes so far in reducing code complexity (as all enums still have to declare and invoke the helper classes). See example (just to clarify):
public enum MyEnum {
A, B, C;
// Just about any method fits the description - equals() is a mere example
public boolean equals(MyEnum that) {
ObjectUtils.equals(this, that);
}
}
How do StackOverflowers deal with this "language feature"?
You can move the reusable logic to dedicated (non-enum) classes and then have the enums delegate to those classes. Here's an example:
[Side note: the inheritance of PlusTwo extends PlusOne is not recommended (b/c PlusTwo is not PlusOne). It here just to illustrate the point of being able to extend an existing logic.]
public interface Logic {
public int calc(int n);
}
public static class PlusOne implements Logic {
public int calc(int n) { return n + 1; }
}
public static class PlusTwo extends PlusOne {
#Override
public int calc(int n) { return super.calc(n) + 1; }
}
public static enum X {
X1, X2;
public Logic logic;
public int doSomething() {
return logic.calc(10);
}
}
public static enum Y {
Y1, Y2;
public Logic logic;
public String doSomethingElse() {
return "Your result is '" + logic.calc(10) + "'";
}
}
public static void main(String[] args) {
// One time setup of your logic:
X.X1.logic = new PlusOne();
X.X2.logic = new PlusTwo();
Y.Y1.logic = new PlusOne();
Y.Y2.logic = new PlusTwo();
System.out.println(X.X1.doSomething());
System.out.println(X.X2.doSomething());
System.out.println(Y.Y1.doSomethingElse());
System.out.println(Y.Y2.doSomethingElse());
}
I would do the same, or combine the Enums into a super-enum.
With Java 8 this will be easier. You will be able to define a default implementation for interface methods and have the enum extend the interface.
I rarely find enums useful, except for representing finite states in which case they do not need behavior.
I would suggest refactoring enums that need behavior into classes with a Factory.
This might look a bit ugly, but generally can offer you the required functionality.
You can have interface
public interface MyEnumInterface<T extends Enum<T>> {
String getBusinessName();
T getEnum();
}
Implementation
public enum OneOfMyEnums implements MyEnumInterface<OneOfMyEnums>{
X, Y, Z;
#Override
public String getBusinessName() {
return "[OneOfMyEnums]" + name();
}
#Override
public OneOfMyEnums getEnum() {
return this;
}
}
And utility class instead of your parent class
public class MyEnumUtils {
public static <T extends Enum<T>> String doSomething(MyEnumInterface<T> e){
e.getBusinessName(); // can use MyEnumInterface methods
e.getEnum().name(); // can use Enum methods as well
return null;
}
}
Related
Suppose I have this:
public class A {
public String foo() { return "A"; }
}
public class B extends A {
public String foo() { return "B"; }
public String superFoo() { return super.foo(); }
}
public class C extends B {
public String foo() { return "C"; }
}
Here, new C().superFoo() returns "A".
Is there a way I can polymorphically make new C().superFoo() invoke B.foo() (and hence return "B") without the need to override superFoo() in C?
I tried with reflection (redefining B.superFoo() like this: return getClass().getSuperclass().getDeclaredMethod("foo").invoke(this)), hoping that with getDeclaredMethod I could reference the exact method implementation in superclass, but I get "C" in that case (hence, polymorphism is applied).
I was searching for a solution that doesn't require me to redeclare superFoo() whenever I add a new subclass to the hierarchy.
TL;DR
Going through the question and comments, it seems like the ask here is to incrementally build up on a behavior. Taking a different perspective, I would prefer Composition over Inheritance in this scenario.
You can use Decorator pattern and compose the instances together; which in turn gives you a reference to the parent's foo() implementation. One of the other benefits is that you can extend/change the behavior at runtime, which is not possible with a static inheritance design.
About Decorator Pattern
Decorator pattern can be used to attach additional responsibilities to an object either statically or dynamically.
Component - Interface for objects that can have responsibilities added to them dynamically.
ConcreteComponent - Defines an object to which additional responsibilities can be added.
Decorator - Maintains a reference to a Component object and defines an interface that conforms to Component's interface.
Concrete Decorators - Concrete Decorators extend the functionality of the component by adding state or adding behavior.
Sample Code
Let's take a Pizza baking process as an example.
Component interface - Defines the contract that a Pizza must be baked.
public interface Pizza {
void bake();
}
ConcreteComponent class - This is your implementation of the interface which can stand alone by itself. It should not extend the Decorator and it appears at the innermost position when the objects are composed together (see client code at the end)
public class VeggiePizza implements Pizza {
#Override
public void bake() {
System.out.println("I'm a Veggie Pizza in the making :)");
}
}
Decorator - Specifies a contract for extending the functionality of the ConcreteComponent.
public abstract class Topping implements Pizza {
private Pizza pizza;
public Topping(Pizza pizza) {
this.pizza = pizza;
}
#Override
public void bake() {
pizza.bake();
}
}
Concrete Decorator - These implementations add to the functionality of the ConcreteComponent by nesting their constructors together (one of the ways to compose!). The concrete decorator can appear anywhere while composing, except for the innermost position (see client code below).
Here we are defining two toppings - Mushroom and Jalapeno.
public class Mushroom extends Topping {
public Mushroom(Pizza pizza) {
super(pizza);
}
#Override
public void bake() {
addMushroom();
super.bake();
}
private void addMushroom() {
System.out.println("Adding mushrooms...");
}
}
public class Jalapeno extends Topping {
public Jalapeno(Pizza pizza) {
super(pizza);
}
#Override
public void bake() {
addJalapenos();
super.bake();
}
private void addJalapenos() {
System.out.println("Adding jalapenos...");
}
}
Client code - How do you compose the ConcreteDecorator and ConcreteComponenttogether?
public void bakePizza() {
Pizza pizza = new Mushroom(new Jalapeno(new VeggiePizza()));
pizza.bake();
}
Notice that we build upon the VeggiePizza by wrapping the objects around with additional behavior from Mushroom and Jalapeno. Here, the ConcreteComponent is the innermost VeggiePizza, while our ConcreteDecorators are Jalapeno and Mushroom.
Note: Constructor composition is only one of the ways to compose. You can compose object together via setters or use a Dependency Injection framework.
Output
Adding mushrooms...
Adding jalapenos...
I'm a Veggie Pizza in the making :)
Following will return B though I've omitted various safety features for the sake of brevity and used commons-lang because you don't want to have to do this stuff yourself! At a minimum, this code assumes every class defines foo() and the you never directly call a.superFoo()! :)
public String superFoo() {
return superXXX("foo");
}
private <T> T superXXX(String name, Object... args) {
Method overriddenMethod = MethodUtils.getAccessibleMethod(getClass(), name);
Iterator<Method> methods = MethodUtils.getOverrideHierarchy(overriddenMethod, EXCLUDE).iterator();
methods.next(); // this is C
Method parentMethod = methods.next(); // This is B;
try {
return (T)parentMethod.invoke(this, args);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
FYI. There may well be an AspectJ/Javassist/Bytebuddy style solution possible as well whereby you can reimplement the superFoo method on all children of A to be super.foo()
I am having an interface that holds three different methods. And there are two class Car and Plane which will implement the Vehicle interface to get access to those methods. There are two questions that I have in my mind.
1. What type of design pattern satisfies the following implementation?
2. Is there any other design pattern to satisfy similar kinds of functionalities?
Though I have tried some blogs and questions I have found one answer regarding the second question which is using Anonymous Class but which leads to more garbage code. So is there any solution or answer to my questions?
public interface Vehicle {
int set_num_of_wheels();
int set_num_of_passengers();
boolean has_gas();
}
public class Car implements Vehicle{
#Override
public int set_num_of_wheels() {
return 0;
}
#Override
public int set_num_of_passengers() {
return 0;
}
#Override
public boolean has_gas() {
return true;
}
}
public class Plane implements Vehicle{
#Override
public int set_num_of_wheels() {
return 0;
}
#Override
public int set_num_of_passengers() {
return 0;
}
#Override
public boolean has_gas() {
return true;
}
}
Polymorphism is just a fancy way to put different function pointers (chosen inconditionally by the concrete class) under a given function name.
So instead if you had a single class with a hashmap of methodenum-to-somefunctioninterface (method enum would just list the finite set of methods to hookup), then you could call the polymorphic functions by looking them up by the enum in the map, then casting to somefunctioninterface and calling it.
It entirely defeats the purpose of this OOP language, but that would be a distinct implementation.
It would fall into behavioral patterns for sure, but I guess it would be close to a Strategy or Plugin, given it's about delegating to classes incarnating the function.
BTW, that's pretty much what DynamicProxy is trying to do; proxy the interface without any impl class and delegate to a handler which figures a way to respon to the requested method.
I am attempting to create a generic/parameterized code to call from multiple classes I have. I will code it so I have several classes that have methods of the same name, so I'm hoping to create a generic way to call them.
Say I have 3 different classes that will all have methods that are called getAmount() that return ints and toString() methods that return Strings
Then I want a generic class that could possibly reference any of those three.
public class Stuff<Project> {
private Project p;
public Stuff(Project aProject) {
this.p = aProject;
}
public int getValue() {
return p.getAmount();
}
public String toString() {
return p.toString();
}
Is there anything in java that would get this functionality for me, or am i thinking in C?
I've tried using Object.getClass() in various ways to attempt to cast things, and several of the other Generic programming related questions on this site and the docs.oracle site don't seem to have what I'm looking for. Is this not possible because of the way type erasure works?
Don't use generics here, use interfaces. In Java, you use interfaces to tell the compiler that a class implements certain methods, without telling it how these methods are implemented.
public interface Project {
int getAmount();
}
public class Stuff {
private Project p;
public Stuff(Project aProject) {
this.p = aProject;
}
public int getValue() {
return p.getAmount();
}
}
You can pass an instance of any class to Stuff's constructor, as long as it implements the Project interface:
public class Construction implements Project {
public int getAmount() {
// implementation
}
}
...
Stuff s = new Stuff(new Construction());
You can use an interface, an abstract class or reflection. I would avoid using reflection unless you really need it. This looks like the perfect job for an interface.
public interface Ammount {
public int getAmmount();
}
public class BankAccount implements Ammount {
#Override
public int getAmmount() {
return -10; // broke
}
}
public class PiggyBank implements Ammount {
#Override
public int getAmmount() {
return 12; // rich
}
}
You can then use some code like
BankAccount myBankAccount = new BankAccount();
Ammount ammount = myBankAccount;
ammount.getAmmount();
PiggyBank myPiggyBank = new PiggyBank();
Ammount ammount = myPiggyBank;
ammount.getAmmount();
I am working with a Java API which requires me to implement a number of fairly large interfaces. However generally there is only one or two details that actually vary between implementations, so I made some abstract base classes to provide most of the implementation.
However now Ive come across cases where I need to extend from some other class and/or implement multiple such interfaces, and so I am unable to extend my abstract base classes.
In C++ I was able to use multiple inheritance, and also use some other tricks like below. However Java doesn't allow multiple inheritance, or generics to be used in this way.
class MyClass : public HelperForInterfaceA, public HelperForInterfaceB {...};
class template<class BASE> MyHelper : public BASE {...};
The best idea I have right now is to have the concrete implementation of my abstract helper class as a field, and then make all the interface methods forward to that field instance, with the field having a reference to the main object to implement the last details if needed.
class MyClass extends A implements IB, IC {
private static class B extends BAbstractHelper {
private A a;
public B(A a, int size) {
super(size);
this.a = a;
}
#Override
public boolean foo(int x, int y) {
return a.foo(x, y);
}
}
private static class C extends CAbstractHelper {
...
}
private B b;
private C c;
private int range;
#Override
public boolean foo(int x, int y) {
return x*x + y*y <= range*range;
}
#Override
public float bar(float x, int y, String s) {
return b.bar(x,y,s);
}
...
}
However this seems a bit of a pain, with a lot of wrapper methods required. Is there a better way of dealing with this?
A Java best practice is to prefer composition over inheritance. Keeps things simpler but creates more boilerplate code. You have the right idea to create delegate methods. A good Java IDE can generate all the boilerplate delegate methods code for you. Other languages on the JVM like Scala (with traits) make this easier.
As you may know, some people are declaring singletons with an Enum of 1 instance, because the JVM guarantees that there will always be a single instance with no concurrency problems to handle...
Thus what about an Enum with multiple instances?
Can we say something like an Enum is a kind of ordered set of singletons sharing a common interface?
Why?
public enum EnumPriceType {
WITH_TAXES {
#Override
public float getPrice(float input) {
return input*1.20f;
}
public String getFormattedPrice(float input) {
return input*1.20f + " €";
}
},
WITHOUT_TAXES {
#Override
public float getPrice(float input) {
return input;
}
},
;
public abstract float getPrice(float input);
public static void main(String[] args) {
WITH_TAXES.getFormattedPrice(33f);
}
}
In this code why this doesn't work:
WITH_TAXES.getFormattedPrice(33f);
What is the interest of declaring a public method if it can't be called without passing through the common interface?
I guess this is why i don't see any syntax to be able to declare an interface just for one of the instances of an Enum.
Edit:
It seems that enum instances are a special kind of anonymous classes.
Thus i understand why you can't call that method.
My question is kinda related to: why can't an anonymous class implement an interface (in addition to the interface it may already implement!)
I totally understand why we CANT do that:
Vehicle veh = new Vehicle() {
public String getName() {
return "toto";
}
};
veh.getName();
(getName here is not an override)
Why i don't understand is why we can't do that with anonymous classes:
Runnable veh = new Vehicle() implements Runnable {
#Override
public void run() {
System.out.println("i run!");
}
};
veh.run();
Or something that would result in the same thing.
Think about it: if you do not use anonymous classes you can absolutely extend the Vehicle class and then make that subclass implement any other interfaces you want...
I'm pretty sure that if it was possible we would be able to call WITH_TAXES.getFormattedPrice(33f) in a typesafe way, since WITH_TAXES would not be a real EnumPriceType but it would but a subclass of EnumPriceType, with its own interface, and by calling WITH_TAXES.getFormattedPrice(33f) with a hardcoded WITH_TAXES, you know at compile that which EnumPriceType child you are calling.
So my question is: are there any reasons why this is not possible? Or it just haven't be done yet?
Your enum is equivalent to the following normal class (in fact, that's pretty much what the compiler turns it into):
public abstract class EnumPriceType {
public static final EnumPriceType WITH_TAXES = new EnumPriceType() {
//getPrice() {...}
//getFormattedPrice() {...}
};
public static final EnumPriceType WITHOUT_TAXES = new EnumPriceType() {
//getPrice() {...}
};
public abstract float getPrice(float input);
public static void main(String[] args) {
WITH_TAXES.getFormattedPrice(33f);
}
}
The getFormattedPrice() method is unavailable on the abstract type, and therefore can't be called from the main method. Consider what would happen if the main method is rewritten to use a local variable:
public static void main(String[] args) {
EnumPriceType foo = EnumPriceType.WITH_TAXES;
foo.getFormattedPrice(33f);
}
This doesn't compile because getFormattedPrice() is not available on the base class. Since the WITH_TAXES instance is an anonymous subclass of EnumPriceType, there's no way you can define the local variable to a type where the getFormattedPrice() method is visible.
As a meta observation, this is a key difference between strongly typed languages such as Java and "duck typed" languages such as Ruby. Ruby will happily invoke the getFormattedPrice() method if happens to be there, regardless of what type of object is held in the foo variable.
As another meta observation, it doesn't make much sense for different constants of the same enum to have different sets methods. If you can't put everything you need as abstract (or concrete) methods on the base enum type, you're probably using the wrong tool to solve the problem.
Add
public String getFormattedPrice(float input) {
return input + " €";
}
outside the overrides as the default implementation. (Next to the declaration of getPrice.) And you are good to go.
You can also have enums implement interfaces, to define what everybody needs to implement.
Thus what about an Enum with multiple instances?
There is no such thing, and your example doesn't demonstrate it. You have an Enum with multiple values. They are all singletons.