Making a code using enum generic - java

I have a code which was initially designed for just a single team where they were passing an enum [which stores list of tasks] to an api. This api then progates the use of this enum to many other classes.
Now i have a task where this code needs to be used by multiple teams and they can pass there own set of tasks in form of enums.
Given the current implementation i dont think it is feasible to support multiple teams which completely overhauling the code because enum's cannot extend other enums.
Is there any way to implement this without massive changes?

But... enums can implement interfaces, for example:
public interface Task {
int getPriority(); // just for example
// plus whatever methods define a task
}
public enum Team1Task implements Task {
Task1(1),
Task2(3);
private final int priority;
private Team1Task(int priority) {
this.priority = priority;
}
public int getPriority() {
return priority;
}
}
Now we can employ java generic kung fu to specify a generic parameter bounded to a suitable enum:
public class TaskProcessor<T extends Enum<T> & Task> {
public void process(T task) {
// do something with task
}
}
To use it:
TaskProcessor<Team1Task> p = new TaskProcessor<Team1Task>();
p.process(Team1Task.Open); // will only accept a Team1Task instance
FYI, as a curiosity of generics, you can alternatively use this bound to achieve the same thing:
public class TaskProcessor<T extends Enum<? extends Task>> {
Although I can find no practical difference in effect, I find it lacks the clarity and familiar pattern of the intersection bound above. For more on this see this question.

It is comparatively easy to make much of the work around enums generic.
Here's a severely cut-down example. It defines a generic database Table class that takes an enum Column as its defining type. The enum defines what columns are in the table. The defining type is an enum that also implements an interface which is a really useful trick.
public class Table<Column extends Enum<Column> & Table.Columns> {
// Name of the table.
protected final String tableName;
// All of the columns in the table. This is actually an EnumSet so very efficient.
protected final Set<Column> columns;
/**
* The base interface for all Column enums.
*/
public interface Columns {
// What type does it have in the database?
public Type getType();
}
// Small list of database types.
public enum Type {
String, Number, Date;
}
public Table(String tableName,
Set<Column> columns) {
this.tableName = tableName;
this.columns = columns;
}
}
You can now create your real table with something like:
public class VersionTable extends Table<VersionTable.Column> {
public enum Column implements Table.Columns {
Version(Table.Type.String),
ReleaseDate(Table.Type.Date);
final Table.Type type;
Column(Table.Type type) {
this.type = type;
}
#Override
public Type getType() {
return type;
}
}
public VersionTable() {
super("Versions", EnumSet.allOf(Column.class));
}
}
Note that this is a truly trivial example but with a little work it is easy to move a lot of your enum work into the parent class.
This technique does retain the type-safety checks you get when using generics.

Enums can implement interfaces. I would recommend coming up with a reasonable interface for the task. make your enum implement the interface and your code will continue to work just fine. other teams can use whatever interface implementation they desire (their own enum or something else). (note, without code it's hard to make very explicit recommendations).

You probably should not use enums for this, but if you want, you can implement logic in helper class, or set of classes that extend each other, and make enums a thin wrappers saround it:
public enum MyTaskEnum {
A, B, C;
private final TaskEnumHelper helper = new TaskEnumHelper();
public void foo (int x, int y)
{
helper.foo (x, y);
}
}

Related

How can I 'group' custom classes together?

I have some custom classes, which contain information about different viewtypes in a RecyclerView, like title, description, etc (there are different variables for each class though). I want to add these classes to an ArrayList, but I don't want it to be a generic (Object?) ArrayList, I want to make sure only my custom classes can be put in. Now I could do this by making another class for it with a setter and getter, and do some checks, but I'd rather have something like ArrayList<CustomGroup>, where CustomGroup could be any of CustomClass1, CustomClass2, etc... Is this possible, and if so, how would I do this?
Example:
public class CustomClass1 {
String title, description;
int amount;
// Getter & Setter
}
public class CustomClass2 {
String errorMessage;
int errorCode;
// Getter & Setter
}
public class CustomClass3 {
String warningName;
double amount;
// Getter & Setter
}
ArrayList<CustomGroup> arrayList = new ArrayList<>();
CustomClass3 customClass3 = new CustomClass3();
// Set values for customClass3
arrayList.add(customClass3);
CustomClass1 customClass1 = new CustomClass1();
// Set values for customClass1
arrayList.add(customClass1);
I would recommend using an interface for this. You can use interfaces as "tags", where the interface basically defines nothing but the classes you want to allow in the list implement it. In your case, however, you could have the interface define the String and int properties.
Interface "tag" with nothing specified
public interface ICustomClassInterface {
}
public class CustomClass1 implements ICustomClassInterface {
String title, description;
int amount;
}
ArrayList<ICustomClassInterface> arrayList = new ArrayList<ICustomClassInterface>();
Only classes that implement the interface can be added to the list. However, your issue here is you will be getting to them through this interface which defines nothing, i.e. you will need to figure out what type it is.
Ideally you would refactor your classes to have the common functionality either defined in an abstract class or specified in an interface, then you don't need to care what the actual type is.
Interface with needed properties defined
public interface ICustomClassInterface {
String FieldA;
int FieldB;
}
public CustomClass1 implements ICustomClassInterface {
String FieldA;
int FieldB;
}
ArrayList<ICustomClassInterface> arrayList = new ArrayList<ICustomClassInterface>();
I would agree with the other answer which suggests using an interface. I would add that, since the examples that you show do not have the same types, you'll find yourself doing checks; perhaps like:
if (someClass instanceof CustomClass1) {
...
} else if (someClass instanceof CustomClass2) {
...
} else if (someClass instanceof CustomClassN) {
...
} else { ... }
That's not very extensible or easily maintained.
You could use the interface, whether empty or with common attributes of the same type, but it might get ugly though doing said checks. Maybe what you could do to avoid that is add a CustomClassProcessor class which will have overloaded methods for the various types you have to handle; this is called the visitor pattern.
public class CustomClassProcessor {
public void process(CustomClass1 cc) {
// Do stuff for CustomClass1
}
public void process(CustomClass2 cc) {
// Do stuff for CustomClass2
}
public void process(CustomClass cc) {
// Do stuff for CustomClass3
}
...
}
Your interface would be like so:
public interface CustomClass {
public void getProcessed(CustomClassProcessor cp);
}
One example of a concrete custom class would be:
public class CustomClass1 implements CustomClass {
#Override
public void getProcessed(CustomClassProcessor cp) {
cp.process(this);
}
}
And you'd use it like:
for (CustomClass cc : list)
cc.getProcessed(customClassProcessor);
or with Java 8 features...
list.forEach(cc -> cc.getProcessed(customClassProcessor);
You have several absolutely different objects and requirement to join it with array list to show it in recyclerView by position. So you have to use ArrayList of Object's(or another collection of objects) and you can't avoid it and pospone checking types.
You have to create such list and make connection of concrete class of stored object with item type (in getItemType) via using instanceof. After that you can create viewHolders according to these types and then in onBindViewHolder cast current item to connected viewHolder or encapsulate casting in concrete view holders

Varying enums in Java being accessed by common method

Essentially what I'm trying to do is create a generic method that can take many different kinds of enums. I'm looking for a way to do it how I'm going to describe, or any other way a person might think of.
I've got a base class, and many other classes extend off that. In each of those classes, I want to have an enum called Includes like this:
public enum Includes {
VENDOR ("Vendor"),
OFFERS_CODES ("OffersCodes"),
REMAINING_REDEMPTIONS ("RemainingRedemptions");
private String urlParam;
Includes(String urlParam) {
this.urlParam = urlParam;
}
public String getUrlParam() {
return urlParam;
}
}
I've got a method that takes in a generic class that extends from BaseClass, and I want to be able to also pass any of the includes on that class to the method, and be able to access the methods on the enum, like this:
ApiHelper.Response<Offer> offer = apiHelper.post(new Offer(), Offer.Includes.VENDOR);
public <T extends BaseClass> Response<T> post(T inputObject, Includes... includes) {
ArrayList<String> urlParams = new ArrayList<String>();
for (Include include : includes){
urlParams.add(include.getUrlParam());
}
return null;
}
Is there a way to be able to pass in all the different kinds of enums, or is there a better way to do this?
---EDIT---
I've added an interface to my enum, but how can I generify my method? I've got this:
public <T extends BaseClass> Response<T> post(Offer inputObject, BaseClass.Includes includes) {
for (Enum include : includes){
if (include instanceof Offer.Includes){
((Offer.Includes) include).getUrlParam();
}
}
return null;
}
But I get an error on apiHelper.post(new Offer(), Offer.Includes.VENDOR); saying the second param must be BaseClass.Includes.
Enums can implement interfaces, so you can create an interface with these methods that you'd like to be able to call:
interface SomeBaseClass {
String getUrlParam();
void setUrlParam(String urlParam);
}
and then your enum can implement this interface:
public enum Includes implements SomeBaseClass {
VENDOR ("Vendor"),
OFFERS_CODES ("OffersCodes"),
REMAINING_REDEMPTIONS ("RemainingRedemptions");
private String urlParam;
Includes(String urlParam) {
this.urlParam = urlParam;
}
#Override
public String getUrlParam() {
return urlParam;
}
#Override
public void setUrlParam(String urlParam) {
this.urlParam = urlParam;
}
}
If you want to get really fancy, it's possible to restrict subtypes of the interface to enums, but the generic type declaration will be pretty ugly (thus hard to understand and maintain) and probably won't provide any "real" benefits.
Unrelated note regarding this design: it's a pretty strong code smell that the enum instances are mutable. Reconsider why you need that setUrlParam() method in the first place.

Java: How to create an immutable value object with a field that follows the (generic) extensible enum type pattern

In Effective Java, 2nd Ed., Joshua Bloch develops the "extensible enum pattern" (item 34). Since enums cannot be subclassed, he proposes unifying groups of related enums by having each enum implement a common type, i.e. interface. This allows enums to be referred to by their unifying type name. The obvious problem with this solution is that type safety is somewhat compromised because it is at least theoretically possible to substitute any non-enum object for an enum by simply creating a class that implements the unifying interface.
To address this problem, a solution is proposed. Here is the method declaration used from the book that takes an enum. The sample application has two enums (BasicOperation and ExtendedOperation), both of which implement a unifying type interface called Operation. The method is designed to accepted any enum of the proper type:
private static <T extends Enum<T> & Operation> void test(
Class<T> opset, double x, double y) {
:
:
}
The reason this works is because the generic method type parameter assures that the class literal supplied as the first argument to the function is both an enum type and an Operation type.
Here is some code from an enum that I am using. This enum is one of a group of enums that I use to describe the metadata for a database column from any of several database tables I am using in my application. Each table has it's own enum that describes these data and they are all unified by implementing the ColumnMetaData<T> interface (where T corresponds to the class for the database table).
class Client extends DB { // Class for the Clients table
// MetaData for all the columns in Client
static enum Column implements ColumnMetaData<Client> {
CLIENT_ID (...
:
:
);
}
}
I would like to use a value class in my application called Datum. It is intended to keep together a database column's value with its column enum.
Here is my problem:
I cannot use a generic method parameter in the constructor for Datum. How can I tell the compiler that one of the fields in Datum must implement both ColumnMetaData<table> and Enum<table.Column>? Currently, I am using the following:
static class Datum {
private final Object val;
private final ColumnMetaData<? extends DB > col;
private Datum(Object val, ColumnMetaData<? extends DB> col) {
this.val = val;
this.col = col;
}
// assorted static factories here...
:
:
}
This works, but the value is not recognized as an enum type and I want to use the associated enum constants with EnumSet and EnumMap.
Is there an elegant solution I am not seeing?
Here's one way - I've used it and it works nicely.
Use a base class with a generic parameter:
public class Table<Column extends Enum<Column> & Table.Columns> {
// Name of the table.
protected final String tableName;
// All of the columns in the table. This is actually an EnumSet so very efficient.
protected final Set<Column> columns;
/**
* The base interface for all Column enums.
*/
public interface Columns {
// What type does it have in the database?
public Type getType();
}
// Small list of database types.
public enum Type {
String, Number, Date;
}
public Table(String tableName,
Set<Column> columns) {
this.tableName = tableName;
this.columns = columns;
}
}
Then subclass that and provide a concrete enum implementing the interface for each table you want.
public class VersionTable extends Table<VersionTable.Column> {
public enum Column implements Table.Columns {
Version(Table.Type.String),
ReleaseDate(Table.Type.Date);
final Table.Type type;
Column(Table.Type type) {
this.type = type;
}
#Override
public Type getType() {
return type;
}
}
public VersionTable() {
super("Versions", EnumSet.allOf(Column.class));
}
}
I've use seriously minimal code here with loads of detail trimmed out but I hope you can see how it all fits.
Note that I have used an EnumSet instead of your Class because there's more detail in an EnumSet.
Note also that maximum type safety is preserved.
It is interesting how many useful features fall out of this pattern. For example you can define sets of columns using EnumSet so you instantly have union and intersection tricks as a freebie.

Extending class in Java and constructing using an instance of the extended class

I would like to extend a class and then copy the value from an instance of the class which has been extended, so I get all its parameters in my new class. In case this doesn't make sense, a simple example of what I'm trying to do:
public class MyTableModel extends DefaultTableModel {
public MyTableModel(DefaultTableModel model){
this = (MyTableModel) model; /* I realise this is invalid */
}
public newMethod(){
// Some additional code
}
}
Is this possible to achieve?
It looks like you want composition instead of inheritance. In particular, it looks like you're trying to use the decorator pattern. That is, you want to take an existing instance of DefaultTableModel, and create another DefaultTableModel that forwards most of the methods to the underlying delegate, but perhaps adding/modifying/decorating some functionalities.
You can never set this = somethingElse;, but you can have a DefaultTableModel delegate, and forward most/all requests to delegate, perhaps adding/decorating some methods as necessary.
See also
Effective Java 2nd Edition, Item 16: Favor composition over inheritance
Guava Example: ForwardingCollection
An example of this pattern is ForwardingCollection from Guava:
A java.util.Collection which forwards all its method calls to another collection. Subclasses should override one or more methods to modify the behavior of the backing collection as desired per the decorator pattern.
You can see the source code to see how this pattern is typically implemented:
#Override protected abstract Collection<E> delegate();
public int size() {
return delegate().size();
}
public boolean isEmpty() {
return delegate().isEmpty();
}
public boolean removeAll(Collection<?> collection) {
return delegate().removeAll(collection);
}
// many more interface Collection methods implemented like above...
As you can see, all the ForwardingCollection does is it implements Collection simply by forwarding all methods to its delegate(), another Collection. Understandably this is rather repetitive and mundane code to write, but now subclasses can simply extends ForwardingCollection and only decorate what they want to decorate.
You can't not set this in Java to anything, it is just used for expressions like (this == someObject) or accessing some property of the object being currently used like (this.someProperty) or inside a constructor to initialize the current object. See here for more info about the this keyword
This code will likely throw a java.lang.ClassCastException
That is MyTableModel is a DefaultTableModel but DefaultTableModel is not a MyTableModel. See http://java.sun.com/docs/books/jls/third_edition/html/conversions.html for more details about type conversion in java
If there is some state and/or behavior that you want to reuse from your parent class in your subclass you should consider marking those members as protected, or consider other form of composition.
A better way to do this would be to make the fields of the superclass protected instead of private - this will give you access to them in your subclass.
Note that when you defined the subclass constructor, you will need to call a constructor from the superclass as well, so in that respect you'll still be able to pass in all the required variables.
And don't forget that all public methods in the superclass can be called as-is by any code that has an instance of your subclass.
EDIT: A little example might help:
public class DefaultTableModel
{
protected String modelName;
protected int numberOfTables;
private numTimesReinited = 0;
public DefaultTableModel(String name, int numTabs)
{
modelName = name;
numberOfTables = numTabs;
}
public void reinit()
{
numTimesReinited++;
// Other stuff
}
protected int getNumberOfReinits()
{
return numTimesReinited;
}
public String getName()
{
return name;
}
}
public class MyTableModel extends DefaultTableModel
{
private String modelType;
public MyTableModel(String name, int numTables, String modelType)
{
super(name, numTables); // sets up the fields in the superclass
this.modelType = modelType;
}
// purely "local" code
public void getModelType()
{
return modelType;
}
// Accesses several protected data to provide new (public) functionality
public void addTable()
{
if (getNumberOfReinits() < 10)
{
numberOfTables++;
reinit();
}
}
}
Let me know if I've misunderstood your requirements, but it sounds like you want to access fields and behaviour of the superclass - which you'll have automatic access to in your subclass so long as they're not private.

Why would an Enum implement an Interface?

I just found out that Java allows enums to implement an interface. What would be a good use case for that?
Here's one example (a similar/better one is found in Effective Java 2nd Edition):
public interface Operator {
int apply (int a, int b);
}
public enum SimpleOperators implements Operator {
PLUS {
int apply(int a, int b) { return a + b; }
},
MINUS {
int apply(int a, int b) { return a - b; }
};
}
public enum ComplexOperators implements Operator {
// can't think of an example right now :-/
}
Now to get a list of both the Simple + Complex Operators:
List<Operator> operators = new ArrayList<Operator>();
operators.addAll(Arrays.asList(SimpleOperators.values()));
operators.addAll(Arrays.asList(ComplexOperators.values()));
So here you use an interface to simulate extensible enums (which wouldn't be possible without using an interface).
Enums don't just have to represent passive sets (e.g. colours). They can represent more complex objects with functionality, and so you're then likely to want to add further functionality to these - e.g. you may have interfaces such as Printable, Reportable etc. and components that support these.
The Comparable example given by several people here is wrong, since Enum already implements that. You can't even override it.
A better example is having an interface that defines, let's say, a data type. You can have an enum to implement the simple types, and have normal classes to implement complicated types:
interface DataType {
// methods here
}
enum SimpleDataType implements DataType {
INTEGER, STRING;
// implement methods
}
class IdentifierDataType implements DataType {
// implement interface and maybe add more specific methods
}
There is a case I often use. I have a IdUtil class with static methods to work with objects implementing a very simple Identifiable interface:
public interface Identifiable<K> {
K getId();
}
public abstract class IdUtil {
public static <T extends Enum<T> & Identifiable<S>, S> T get(Class<T> type, S id) {
for (T t : type.getEnumConstants()) {
if (Util.equals(t.getId(), id)) {
return t;
}
}
return null;
}
public static <T extends Enum<T> & Identifiable<S>, S extends Comparable<? super S>> List<T> getLower(T en) {
List<T> list = new ArrayList<>();
for (T t : en.getDeclaringClass().getEnumConstants()) {
if (t.getId().compareTo(en.getId()) < 0) {
list.add(t);
}
}
return list;
}
}
If I create an Identifiable enum:
public enum MyEnum implements Identifiable<Integer> {
FIRST(1), SECOND(2);
private int id;
private MyEnum(int id) {
this.id = id;
}
public Integer getId() {
return id;
}
}
Then I can get it by its id this way:
MyEnum e = IdUtil.get(MyEnum.class, 1);
Since Enums can implement interfaces they can be used for strict enforcing of the singleton pattern. Trying to make a standard class a singleton allows...
for the possibility of using reflection techniques to expose private methods as public
for inheriting from your singleton and overriding your singleton's methods with something else
Enums as singletons help to prevent these security issues. This might have been one of the contributing reasons to let Enums act as classes and implement interfaces. Just a guess.
See https://stackoverflow.com/questions/427902/java-enum-singleton and Singleton class in java for more discussion.
It's required for extensibility -- if someone uses an API you've developed, the enums you define are static; they can't be added to or modified. However, if you let it implement an interface, the person using the API can develop their own enum using the same interface. You can then register this enum with an enum manager which conglomerates the enums together with the standard interface.
Edit: #Helper Method has the perfect example of this. Think about having other libraries defining new operators and then telling a manager class that 'hey, this enum exists -- register it'. Otherwise, you'd only be able to define Operators in your own code - there'd be no extensibility.
The post above that mentioned strategies didn't stress enough what a nice lightweight implementation of the strategy pattern using enums gets you:
public enum Strategy {
A {
#Override
void execute() {
System.out.print("Executing strategy A");
}
},
B {
#Override
void execute() {
System.out.print("Executing strategy B");
}
};
abstract void execute();
}
You can have all your strategies in one place without needing a separate compilation unit for each. You get a nice dynamic dispatch with just:
Strategy.valueOf("A").execute();
Makes java read almost like a tasty loosely typed language!
Enums are just classes in disguise, so for the most part, anything you can do with a class you can do with an enum.
I cannot think of a reason that an enum should not be able to implement an interface, at the same time I cannot think of a good reason for them to either.
I would say once you start adding thing like interfaces, or method to an enum you should really consider making it a class instead. Of course I am sure there are valid cases for doing non-traditional enum things, and since the limit would be an artificial one, I am in favour of letting people do what they want there.
Most common usage for this would be to merge the values of two enums into one group and treat them similarly. For example, see how to join Fruits and Vegatables.
For example if you have a Logger enum. Then you should have the logger methods such as debug, info, warning and error in the interface. It makes your code loosely coupled.
One of the best use case for me to use enum's with interface is Predicate filters. It's very elegant way to remedy lack of typness of apache collections (If other libraries mayn't be used).
import java.util.ArrayList;
import java.util.Collection;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;
public class Test {
public final static String DEFAULT_COMPONENT = "Default";
enum FilterTest implements Predicate {
Active(false) {
#Override
boolean eval(Test test) {
return test.active;
}
},
DefaultComponent(true) {
#Override
boolean eval(Test test) {
return DEFAULT_COMPONENT.equals(test.component);
}
}
;
private boolean defaultValue;
private FilterTest(boolean defautValue) {
this.defaultValue = defautValue;
}
abstract boolean eval(Test test);
public boolean evaluate(Object o) {
if (o instanceof Test) {
return eval((Test)o);
}
return defaultValue;
}
}
private boolean active = true;
private String component = DEFAULT_COMPONENT;
public static void main(String[] args) {
Collection<Test> tests = new ArrayList<Test>();
tests.add(new Test());
CollectionUtils.filter(tests, FilterTest.Active);
}
}
When creating constants in a jar file, it is often helpful to let users extend enum values. We used enums for PropertyFile keys and got stuck because nobody could add any new ones! Below would have worked much better.
Given:
public interface Color {
String fetchName();
}
and:
public class MarkTest {
public static void main(String[] args) {
MarkTest.showColor(Colors.BLUE);
MarkTest.showColor(MyColors.BROWN);
}
private static void showColor(Color c) {
System.out.println(c.fetchName());
}
}
one could have one enum in the jar:
public enum Colors implements Color {
BLUE, RED, GREEN;
#Override
public String fetchName() {
return this.name();
}
}
and a user could extend it to add his own colors:
public enum MyColors implements Color {
BROWN, GREEN, YELLOW;
#Override
public String fetchName() {
return this.name();
}
}
Another posibility:
public enum ConditionsToBeSatisfied implements Predicate<Number> {
IS_NOT_NULL(Objects::nonNull, "Item is null"),
IS_NOT_AN_INTEGER(item -> item instanceof Integer, "Item is not an integer"),
IS_POSITIVE(item -> item instanceof Integer && (Integer) item > 0, "Item is negative");
private final Predicate<Number> predicate;
private final String notSatisfiedLogMessage;
ConditionsToBeSatisfied(final Predicate<Number> predicate, final String notSatisfiedLogMessage) {
this.predicate = predicate;
this.notSatisfiedLogMessage = notSatisfiedLogMessage;
}
#Override
public boolean test(final Number item) {
final boolean isNotValid = predicate.negate().test(item);
if (isNotValid) {
log.warn("Invalid {}. Cause: {}", item, notSatisfiedLogMessage);
}
return predicate.test(item);
}
}
and using:
Predicate<Number> p = IS_NOT_NULL.and(IS_NOT_AN_INTEGER).and(IS_POSITIVE);
Enums are like Java Classes, they can have Constructors, Methods, etc. The only thing that you can't do with them is new EnumName(). The instances are predefined in your enum declaration.
Here's my reason why ...
I have populated a JavaFX ComboBox with the values of an Enum. I have an interface, Identifiable (specifying one method: identify), that allows me to specify how any object identifies itself to my application for searching purposes. This interface enables me to scan lists of any type of objects (whichever field the object may use for identity) for an identity match.
I'd like to find a match for an identity value in my ComboBox list. In order to use this capability on my ComboBox containing the Enum values, I must be able to implement the Identifiable interface in my Enum (which, as it happens, is trivial to implement in the case of an Enum).
I used an inner enum in an interface describing a strategy to keep instance control (each strategy is a Singleton) from there.
public interface VectorizeStrategy {
/**
* Keep instance control from here.
*
* Concrete classes constructors should be package private.
*/
enum ConcreteStrategy implements VectorizeStrategy {
DEFAULT (new VectorizeImpl());
private final VectorizeStrategy INSTANCE;
ConcreteStrategy(VectorizeStrategy concreteStrategy) {
INSTANCE = concreteStrategy;
}
#Override
public VectorImageGridIntersections processImage(MarvinImage img) {
return INSTANCE.processImage(img);
}
}
/**
* Should perform edge Detection in order to have lines, that can be vectorized.
*
* #param img An Image suitable for edge detection.
*
* #return the VectorImageGridIntersections representing img's vectors
* intersections with the grids.
*/
VectorImageGridIntersections processImage(MarvinImage img);
}
The fact that the enum implements the strategy is convenient to allow the enum class to act as proxy for its enclosed Instance. which also implements the interface.
it's a sort of strategyEnumProxy :P the clent code looks like this:
VectorizeStrategy.ConcreteStrategy.DEFAULT.processImage(img);
If it didn't implement the interface it'd had been:
VectorizeStrategy.ConcreteStrategy.DEFAULT.getInstance().processImage(img);

Categories