Java Enum polymorphism pattern
In Java, the group of constants is usually represented in form of an enum. The enum can implement an interface that allows it to be polymorphic. In this tutorial, I will show how to implement the Enum polymorphism pattern with a real example.
The use case:
Let's say we develop an app that processes purchase transactions. The app receives the data about transactions in a form of a JSON and it contains a code of a credit card type. The relationship between the codes and the names of the cards looks like this:
We have a requirement to develop a code that receives a credit card code and then converts it to their names.
Solution:
The first solution that comes to mind is to simply create one enum and combine inside it all values and add the property to the enum which indicates a type of card VISA or MASTERCARD. This attempt will fail because there are duplicate names, for example, PLATINUM and GOLD. Both are types of VISA and MASTERCARD and the enum does not allow duplicates.
The second approach is to prefix the name of the card with the name of the type of the card, like VISA_PLATINUM, MASTERCARD_PLATINUM, etc, and keep the property to indicate a type of a card like in the previous attempt. This will solve the problem of duplication cause now all the names will be unique, but at the same time, this will make a code looks clumsy.
Because now we have a property that indicates a type of a card (VISA or MASTERCARD) and the name is prefixed with the name of a type of a card, basically duplicating the property. And if we remove the property, then we won't be able to filter cards by their type. For example, if we want to get all VISAs then the solution is to deal with the prefix, which is a very bad idea.
The ideal way is to separate cards into two different enums, one for VISA and one for MASTERCARD. Then the first question arises if we have two different enums, then how we can use it in one property for example in the variable and the second question is how the converting from a code to the name works in this case.
The solution is polymorphism using the interface. The first step is to create the enum of credit card types. The role of this enum is to distinguish the cards:
The second step is to create an interface, containing two abstract methods, and two static methods. About static methods a bit later.
Now we create the enum for VISA credit cards and this enum implements the interface created earlier. The enum has one property — a code, and implementation of the methods of the interface, one returns the code and another returns the type of a card. the type of the card is an enum created previously.
The same implementation we create for the MASTERCARD cards.
The value duplication problem is solved because now we have separated them into different enums. We don’t have to use a prefix as well. Even though now it is a different enum we still can use it as one reference type, we declare one variable of interface type and reference to both enums.
To be able to convert the code of a card to enum the static method created in the interface combines values of both enums into a stream and filters out the enum matching the code.
And the second static method of the enum allows us to get the list of the cards by their type.
The best part is that this pattern is extensible, for example, if in the future we decide to add a new type of card for example AMEX then we only will need to follow the contract defined in the interface.
You can check the code in action by running tests:
The complete code you can find below:
Conclusion
The Java enum at the first glimpse looks simple and limited. But thanks to polymorphism it can make the code extensible and easier to use. Thank you for reading! Please like and follow. If you have any questions or suggestions, please feel free to write me on my LinkedIn account.