I would like to have a limited fixed catalogue of instances of a certain complex interface. The standard multiton pattern has some nice features such as lazy instantiation. However it relies on a key such as a String which seems quite error prone and fragile.
I'd like a pattern that uses enum. They have lots of great features and are robust. I've tried to find a standard design pattern for this but have drawn a blank. So I've come up with my own but I'm not terribly happy with it.
The pattern I'm using is as follows (the interface is highly simplified here to make it readable):
interface Complex {
void method();
}
enum ComplexItem implements Complex {
ITEM1 {
protected Complex makeInstance() { return new Complex() { ... }
},
ITEM2 {
protected Complex makeInstance() { return new Complex() { ... }
};
private Complex instance = null;
private Complex getInstance() {
if (instance == null) {
instance = makeInstance();
}
return instance;
}
protected void makeInstance() {
}
void method {
getInstance().method();
}
}
This pattern has some very nice features to it:
the enum implements the interface which makes its usage pretty natural: ComplexItem.ITEM1.method();
Lazy instantiation: if the construction is costly (my use case involves reading files), it only occurs if it's required.
Having said that it seems horribly complex and 'hacky' for such a simple requirement and overrides enum methods in a way which I'm not sure the language designers intended.
It also has another significant disadvantage. In my use case I'd like the interface to extend Comparable. Unfortunately this then clashes with the enum implementation of Comparable and makes the code uncompilable.
One alternative I considered was having a standard enum and then a separate class that maps the enum to an implementation of the interface (using the standard multiton pattern). That works but the enum no longer implements the interface which seems to me to not be a natural reflection of the intention. It also separates the implementation of the interface from the enum items which seems to be poor encapsulation.
Another alternative is to have the enum constructor implement the interface (i.e. in the pattern above remove the need for the 'makeInstance' method). While this works it removes the advantage of only running the constructors if required). It also doesn't resolve the issue with extending Comparable.
So my question is: can anyone think of a more elegant way to do this?
In response to comments I'll tried to specify the specific problem I'm trying to solve first generically and then through an example.
There are a fixed set of objects that implement a given interface
The objects are stateless: they are used to encapsulate behaviour only
Only a subset of the objects will be used each time the code is executed (depending on user input)
Creating these objects is expensive: it should only be done once and only if required
The objects share a lot behaviour
This could be implemented with separate singleton classes for each object using separate classes or superclasses for shared behaviour. This seems unnecessarily complex.
Now an example. A system calculates several different taxes in a set of regions each of which has their own algorithm for calculting the taxes. The set of regions is expected to never change but the regional algorithms will change regularly. The specific regional rates must be loaded at run time via remote service which is slow and expensive. Each time the system is invoked it will be given a different set of regions to calculate so it should only load the rates of the regions requested.
So:
interface TaxCalculation {
float calculateSalesTax(SaleData data);
float calculateLandTax(LandData data);
....
}
enum TaxRegion implements TaxCalculation {
NORTH, NORTH_EAST, SOUTH, EAST, WEST, CENTRAL .... ;
private loadRegionalDataFromRemoteServer() { .... }
}
Recommended background reading: Mixing-in an Enum
Seems fine. I would make initialization threadsafe like this:
enum ComplexItem implements Complex {
ITEM1 {
protected Complex makeInstance() {
return new Complex() { public void method() { }};
}
},
ITEM2 {
protected Complex makeInstance() {
return new Complex() { public void method() { }}
};
private volatile Complex instance;
private Complex getInstance() {
if (instance == null) {
createInstance();
}
return instance;
}
protected abstract Complex makeInstance();
protected synchronized void createInstance() {
if (instance == null) {
instance = makeInstance();
}
}
public void method() {
getInstance().method();
}
}
The modifier synchronized only appears on the createInstance() method, but wraps the call to makeInstance() - conveying threadsafety without putting a bottleneck on calls to getInstance() and without the programmer having to remember to add synchronized to each to makeInstance() implementation.
This works for me - it's thread-safe and generic. The enum must implement the Creator interface but that is easy - as demonstrated by the sample usage at the end.
This solution breaks the binding you have imposed where it is the enum that is the stored object. Here I only use the enum as a factory to create the object - in this way I can store any type of object and even have each enum create a different type of object (which was my aim).
This uses a common mechanism for thread-safety and lazy instantiation using ConcurrentMap of FutureTask.
There is a small overhead of holding on to the FutureTask for the lifetime of the program but that could be improved with a little tweaking.
/**
* A Multiton where the keys are an enum and each key can create its own value.
*
* The create method of the key enum is guaranteed to only be called once.
*
* Probably worth making your Multiton static to avoid duplication.
*
* #param <K> - The enum that is the key in the map and also does the creation.
*/
public class Multiton<K extends Enum<K> & Multiton.Creator> {
// The map to the future.
private final ConcurrentMap<K, Future<Object>> multitons = new ConcurrentHashMap<K, Future<Object>>();
// The enums must create
public interface Creator {
public abstract Object create();
}
// The getter.
public <V> V get(final K key, Class<V> type) {
// Has it run yet?
Future<Object> f = multitons.get(key);
if (f == null) {
// No! Make the task that runs it.
FutureTask<Object> ft = new FutureTask<Object>(
new Callable() {
public Object call() throws Exception {
// Only do the create when called to do so.
return key.create();
}
});
// Only put if not there.
f = multitons.putIfAbsent(key, ft);
if (f == null) {
// We replaced null so we successfully put. We were first!
f = ft;
// Initiate the task.
ft.run();
}
}
try {
/**
* If code gets here and hangs due to f.status = 0 (FutureTask.NEW)
* then you are trying to get from your Multiton in your creator.
*
* Cannot check for that without unnecessarily complex code.
*
* Perhaps could use get with timeout.
*/
// Cast here to force the right type.
return type.cast(f.get());
} catch (Exception ex) {
// Hide exceptions without discarding them.
throw new RuntimeException(ex);
}
}
enum E implements Creator {
A {
public String create() {
return "Face";
}
},
B {
public Integer create() {
return 0xFace;
}
},
C {
public Void create() {
return null;
}
};
}
public static void main(String args[]) {
try {
Multiton<E> m = new Multiton<E>();
String face1 = m.get(E.A, String.class);
Integer face2 = m.get(E.B, Integer.class);
System.out.println("Face1: " + face1 + " Face2: " + Integer.toHexString(face2));
} catch (Throwable t) {
t.printStackTrace(System.err);
}
}
}
In Java 8 it is even easier:
public class Multiton<K extends Enum<K> & Multiton.Creator> {
private final ConcurrentMap<K, Object> multitons = new ConcurrentHashMap<>();
// The enums must create
public interface Creator {
public abstract Object create();
}
// The getter.
public <V> V get(final K key, Class<V> type) {
return type.cast(multitons.computeIfAbsent(key, k -> k.create()));
}
}
One thought about this pattern: the lazy instantiation isn't thread safe. This may or may not be okay, it depends on how you want to use it, but it's worth knowing. (Considering that enum initialisation in itself is thread-safe.)
Other than that, I can't see a simpler solution that guarantees full instance control, is intuitive and uses lazy instantiation.
I don't think it's an abuse of enum methods either, it doesn't differ by much from what Josh Bloch's Effective Java recommends for coding different strategies into enums.
Related
I'm looking for a recommendation on a design pattern which could be used to interpret an array of different Object instances. Ideally, these pattern definitions would be statically defined.
So, as an example, I'm looking for something along the lines of this:
Ingredient [] lIngredients = new Ingredient []{ new Lime (), new Soda (), new Sugar (), new Mint (), new Rum () };
Patterns.WHITE_RUSSIAN.isRecipe(lIngredients);//returns false
Patterns.MOJITO.isRecipe(lIngredients);//returns true
I managed to develop a working solution using Object class references, however it's clear that later on in my development some of my patterns will rely upon instance data members, whilst others will not. I'd like the patterns to be flexible, so they may not have to depend on a specific ordering in the array, or ignore superfluous elements, or detect duplicates.
Are there any widely-used approaches that suit these requirements?
Probably, you can do it using one of those two
interface Ingredient {
boolean belongsTo(Cocktail cocktail)
}
interface Cocktail {
boolean hasIngredient(Ingredient ingredient)
}
A Cocktail itself can be an array or other aggregation of Ingredients
The preferred design pattern for when you have a hierarchy of classes to be processed is the Visitor pattern.
public class Lime {
public void accept(IngredientVisitor visitor) {
visitor.visit(this);
}
}
public class Soda {
public void accept(IngredientVisitor visitor) {
visitor.visit(this);
}
}
public class MojitoVisitor extends IngredientVisitor {
public void visit(Lime lime) {
System.out.println("Visiting lime");
}
public void visit(Soda soda) {
System.out.println("Visiting soda");
}
}
EDIT: I agree solution above creates too much overhead. I'd then go with a Matcher like Hamcrest where you can do something like:
private Matcher mojitoMatcher = arrayContainingInAnyOrder(
instanceOf(Rum.class),
instanceOf(Mint.class),
instanceOf(SodaWater.class),
instanceOf(Lime.class),
instanceOf(Sugar.class)
);
public boolean isMojito(Ingredient[] ingredients) {
return mojitoMatcher.matches(ingredients);
}
After a little contemplation and encouragement from the wonderful answers offered by other StackOverflow users, I think I've stumbled upon a reasonable solution.
Scenario
We'd like to take an array of Ingredients and systematically interpret the range of delicious cocktail recipes that can be reproduced from them. The relationships must be flexible and capable of accessing data members from our generic array specifications.
Technical
In this application, we'll be processing a collection of instances. In this regard we'd like to develop pattern-matching code that acts as a function of aggregate set of data members, rather than have the data members themselves define the logic of a recipe. The reason for this is two-fold; firstly, an Ingredient is not just only ever used in just a Cocktail (which will pertube the more party-prone amongst you); it could be in a Cake, a Salad or even an Colonoscopy; therefore we're obliged to abstract the analysis logic from the base class specifications to improve separation of responsibilities. This approach inspires us to develop a set of generic tools that are applicable for a whole range of different applications, not just my imaginary bar. Secondly, it enables us to process autoboxed Java Primitives or Java Beans without having to construct any interfaces. Another happy biproduct of this approach is that it enables much clearer visualization of the Cocktails pattern as a whole; there's no 'hidden' interactions between class calls.
So, rather than handling the relationships between different Ingredients, I decided to formalise the entire approach as finite interactions between two generic entities; Alice and Bob. I've decided to refer to these interactions as a Liason, not only because I'm just sad, but also lonely.
Design
First, I've constructed an Interface called ILiason. I use an interface because this enables existing classes in a design to integrate with the pattern matching architecture without causing multiple-inheritance conflicts.
/* Defines the basis of a ILiason. */
public interface ILiason<A, B> {
/* Defines whether a ILiason exists between Alice and Bob. */
public abstract boolean isLiason(final A pAlice);
/* Returns the source of comparison. */
public abstract B getBob();
}
In ILiason, we define two simple methods that are dependent on two generic types, A (Alice) and B (Bob). A will be the runtime collection or Object we wish to compare against, and B will be the source of Comparison returned by getBob(). In the method isLiason(final A pAlice), we will define the specific logic in how to properly compare Alice and Bob.
In the Cocktails application, I've decided to represent each specific Ingredient as an implementor of the IIngredient interface. You'll see below that we define things like Rum, Vodka and eugh... Gin. I've also defined an additional extension to IIngredient, ISpoonfuls; this enumerates the number of spoonfuls of a certain ingredient the caller has selected. A concrete implementation of ISpoonfuls is defined within the IIngredient.Sugar class specification.
`/* The base ingredient interface. */
public interface IIngredient {
/* Amount Interface. */
public static interface ISpoonfuls extends IIngredient {
/* Returns the Number of Teaspoons required for the concrete Ingredient. */
public abstract int getNumberOfTeaSpoons();
}
/* Define some example implementations. */
public static final class Rum implements IIngredient { };
public static final class Liquor implements IIngredient { };
public static final class Vodka implements IIngredient { };
public static final class Cream implements IIngredient { };
public static final class Gin implements IIngredient { };
public static final class Vermouth implements IIngredient { };
public static final class Orange implements IIngredient { };
public static final class Lime implements IIngredient { };
public static final class Soda implements IIngredient { };
public static final class Mint implements IIngredient { };
public static final class Sugar implements ISpoonfuls {
/* Member Variables. */
private final int mNumberOfTeaspoons;
/* Constructor. */
public Sugar(final int pNumberOfTeaspoons) {
/* Initialize Member Variables. */
this.mNumberOfTeaspoons = pNumberOfTeaspoons;
}
/* Getters. */
#Override public int getNumberOfTeaSpoons() { return this.mNumberOfTeaspoons; }
};
}`
It's clear from this design that in order to check for the presence of a certain IIngredient in a collection, we'll wish to test for it's Class. So, we'll define our first ILiason type, the Assignable:
/* A ILiason used to determine whether a given instance is assignable from a given class. */
public static abstract class Assignable<A> implements ILiason<A, Class<?>> {
/* Default Implementation Stub. */
public static final class Impl<A> extends Assignable<A> { private final Class<?> mBob; public Impl(final Class<?> pBob) { this.mBob = pBob; } #Override public final Class<?> getBob() { return this.mBob; } };
/* Determines whether Alice is an assignable form of Bob. */
#Override public final boolean isLiason(final A pAlice) {
/* Checks whether the source class of Alice is compatible with the concretely-defined Bob. */
return (this.getBob().isAssignableFrom(pAlice.getClass()));
}
};
In the abstract (incomplete) Assignable class, we'll see that we define a generic specification of the Alice type, however we assert that Bob must be a Class<?> reference. In our concrete definition of isLiason(final A pAlice), we use the Class<?> reference returned by getBob() in conjunction with the method isAssignableFrom(Class<?> c) to investigate if Java can detect an existing hierarchy between Alice and Bob. We use this metric as the result for whether there's an existing liason between Alice and Bob. In Cocktails, we're able to use this basic form of ILiason to detect specific Class types.
As a basic implementation, below I demonstrate how to detect if a certain instance is a specific type of IIngredient:
(new ILiason.Assignable<IIngredient>() { #Override public Class<?> getBob() { return Lime.class; } }).isLiason(Lime.class); // Returns true!
(new ILiason.Assignable<IIngredient>() { #Override public Class<?> getBob() { return Lime.class; } }).isLiason(Mint.class); // Returns false!
What we've achieved so far seems like a lot of overhead for what we could have achieved using instanceof, and it is; but the benefit will soon be apparent when we move onto more complex relationships, which fundamentally rely upon the same architecture.
Another requirement of our design is that for given instances, we'd like to query their instance members to determine the validity of an ILiason. To achieve this, we define a second implementor of ILiason, the Intuition.
What we've achieved so far seems like a lot of overhead for what we could have achieved using instanceof, and it is; but the benefit will soon be apparent when we move onto more complex relationships, which fundamentally rely upon the same architecture.
Another requirement of our design is that for given instances, we'd like to query their instance members to determine the validity of an ILiason. To achieve this, we define a second implementor of ILiason, the Intuition.
/* A ILiason which uses informed knowledge of a type to determine the state of a ILiason. */
public static abstract class Intuition<A, B> implements ILiason<A, Class<?>> { /*** TODO: to B **/
/* First, we determine if Alice is an instance of Bob. */ /** TODO: We suppress the unchecked type cast, however Assignable guarantees us the check. **/
#Override #SuppressWarnings("unchecked") public final boolean isLiason(final A pAlice) {
/* Determine if we can use intuitive processing via an Assignable. If we can't, return the default result. */
return (new ILiason.Assignable.Impl<A>(this.getBob()).isLiason(pAlice) ? this.onSupplyIntuition((B)pAlice) : false);
}
/* Defines concrete methodology towards handling alice in a class-specific manner. */
public abstract boolean onSupplyIntuition(final B pA);
};
`
In Intuition, we see that to compute the status of the Liason we first test for assignability using an ILiason.Assignable; if this is achieved, we're able to safelty type cast Alice to the assignable type and allow concrete implementors to define a more intimate analysis of the instance via onSupplyIntuition. Below, we use this to examine the NumberOfTeaspoons of IIngredient.Sugar:
new ILiason.Intuition<IIngredient, Sugar>() {
/* Define the Number of Teaspoons of Sugar expected for a Mojito. (I made this up, it's probably a lot more.) */
#Override public final boolean onSupplyIntuition(final Sugar pSugar) { return (pSugar.getNumberOfTeaSpoons() == 2); }
/* Define the Searchable class reference. */
#Override public final Class<Sugar> getBob() { return Sugar.class; }
}; } }
With these definitions, we're able to define both generic and informed analysis of Collections, and use their results to infer specific combinations of classes. For example, the presence of a given ILiason within an individual array index may be found using the ILiason.Element:
/* Determines whether a particular Liason is present within a specified Array, Alice. */
public static abstract class Element<A, B> implements ILiason<A[], ILiason<A, B>> {
/* Here we iterate through the entire specification of Alice in search of a matching Liason. */
#Override public final boolean isLiason(final A[] pAlice) {
/* Define the Search Metric. */
boolean lIsSupported = false;
/* Iterate Alice. */
for(int i = 0; i < pAlice.length && !lIsSupported; i++) {
/* Fetch Alice at this index. */
final A lAlice = pAlice[i];
/* Update the Search metric using Alice's Liason with Bob. */
lIsSupported |= this.getBob().isLiason(lAlice);
}
/* Return the Search Metric. */
return lIsSupported;
}
};
Using a similar approach, the applicability of an array of ILiasons to a given Alice may be processed using a ILiason.Cohort. The order in which ILiasons are defined in the call to getBob() also defines priority:
/* Compares an array of Alice against an array of Liasons. Determines whether all Liasons are fully met. */
public static abstract class Cohort<A, B> implements ILiason<A[], ILiason<A[], B>[]> {
/* Iterates the array of Alice and returns true if all Liasons within the cohort are supported. */
#Override public final boolean isLiason(final A[] pAlice) {
/* Define the Search Metric. */
boolean lIsValid = true;
/* Fetch the associated Liasons. */
final ILiason<A[], B>[] lLiasons = this.getBob();
/* Iterate the Liasons whilst the delegation is Valid. */
for(int i = 0; i < lLiasons.length && lIsValid; i++) {
/* Fetch the Liason. */
final ILiason<A[], B> lLiason = lLiasons[i];
/* Update the search metric. */
lIsValid &= lLiason.isLiason(pAlice);
}
/* Return the search metric. */
return lIsValid;
}
};
Using these tools, we're able to define different Cocktails as follows: :
/* Define the Martini Specification. */
private static final ILiason.Cohort<IIngredient, Class<?>> LIASON_COHORT_COCKTAIL_MARTINI = new ILiason.Cohort<IIngredient, Class<?>>() { #SuppressWarnings("unchecked") #Override public final ILiason<IIngredient[], Class<?>>[] getBob() { return ((ILiason<IIngredient[], Class<?>>[]) new ILiason<?, ?>[] {
/* Define the Dry-Gin. */
new ILiason.Element<IIngredient, Class<?>>() { #Override public final ILiason<IIngredient, Class<?>> getBob() { return new ILiason.Assignable<IIngredient>() { #Override public Class<?> getBob() { return Gin.class; } }; } },
new ILiason.Element<IIngredient, Class<?>>() { #Override public final ILiason<IIngredient, Class<?>> getBob() { return new ILiason.Assignable<IIngredient>() { #Override public Class<?> getBob() { return Vermouth.class; } }; } },
new ILiason.Element<IIngredient, Class<?>>() { #Override public final ILiason<IIngredient, Class<?>> getBob() { return new ILiason.Assignable<IIngredient>() { #Override public Class<?> getBob() { return Orange.class; } }; } },
}); } };
Then, with a simple call to an LIASON_COHORT_COCKTAIL_MARTINI's isLiason(final IIngredient[] pAlice) method, we're able to test for the existence of appropriate data members in our array of IIngredients.
And there you have it! Statically defined pattern definitions which may implement arbitrary comparison functionality.
Drawbacks
-- There's a pretty large coding overhead in creating new ILiason definitions. With all of the flexibility the pattern buys us, it doesn't quite measure up in simplicity.
-- It's quite likely slow. Most of the comparisons implemented here are 2D array searches for every single ILiason type. instanceof might be the more preferable choice in simple cases.
-- It's possible that there's an overlapping of responsibilities in ILiason definitions. Luckily, the core ILiason types are ILiasons themselves, and can often be nested in an effort improve code cohesion.
So, I here was my previous code:
public enum eDay {
eMON,
eTUE,
eWED
}
eDay day = eMON;
switch( day ) {
case eMON:
//load class 1
break;
case eTUE:
//load class 2
break;
case eWED:
//load class 3
break;
}
Reading around, the OO way to do things is to have an enum that overrides a method rather than using a switch statement, such as:
enum eDay {
eMON {
#Override
public void loadClass() {
//load class 1
}
},
eTUE {
#Override
public void loadClass() {
//load class 2
}
};
public abstract void loadClass();
}
void aMethodSomewhere(final eDay e) {
e.loadClass();
}
While the concept of using polymorphism makes sense to me, rather than using a switch statement, what happens in the situation where the enum is used in different classes to do different things? For example, different classes behave differently according to a limited set of options, defined in the enum ( so not always performing loadClass() ).
Should you define different methods according to the different classes? To my mind, that would increase object coupling greatly.
I would really like to do OO properly, so good advice is much appreciated.
Many thanks.
In general, you want to use polymorphism to avoid if() blocks and for behavior reuse, you should favor composition.
In your case, I understand that there is some dynamic behavior involved in your design and, therefore, the use of enums could not be advisable.
Enums have a lot of advantages: they're final, static and every instance is a singleton by default. Whenever I need a static singleton that is up when the JVM starts, I favor enums over classes.
In this case, if you have some dynamic behavior going on, you could write a class with some static final properties that are an instance of the same class. With proper visibility modifiers for constructors or factory methods, the external API of the class could be the same as with the enum.
In order to inject the dynamic behavior, you could use Strategy design pattern or even inject a Function (if you're using Java8) as a parameter in the class' constructor.
public static class eDays {
public static final eDay eMON = new eDay(i -> i + 1);
public static final eDay eTUE = new eDay(i -> i + 2);
public static class eDay {
private final Function<Integer, Integer> loadClassStrategy;
public eDay(Function<Integer, Integer> loadClassStrategy) {
this.loadClassStrategy = loadClassStrategy;
}
public int loadClass(int i) {
return loadClassStrategy.apply(i);
}
}
}
void aMethodSomewhere(final eDays.eDay e) {
e.loadClass(1);
}
// or even...
void aMethodSomewhere() {
eDay eMON = new eDay(i -> i + 1);
eMON.loadClass(1);
}
If your behavior is not dynamic, you could continue using enums, but you could inject the behavior in their constructor to improve readability:
public enum eDay {
eMON(i->i+1),
eTUE(i->i+2);
private final Function<Integer, Integer> loadClassStrategy;
eDay(Function<Integer, Integer> loadClassStrategy) {
this.loadClassStrategy = loadClassStrategy;
}
public int loadClass(int i) {
return loadClassStrategy.apply(i);
}
}
void aMethodSomewhere(eDay e) {
e.loadClass(1);
}
I'd advise against putting this kind of behavior in enums; that's really not what they are designed for*. Instead, it might be better to maintain a map of enums and handlers.
Map<Eday, Loader> enumHandlerMap = new EnumMap<>();
Loader should be an interface (basically the stuff you had in your enum):
public interface Loader {
void loadClass();
}
Then you can initialize your your handler map like so:
enumHanderMap.put(EDay.MON, new Loader() {
#Override
public void loadClass() {
...
}
});
And you can run a handler like so:
enumHandler.get(eDayEnum).loadClass();
*To clarify, the semantic conveyed by enums is that you are dealing with a static, predefined set of values. I think an acceptable form of logic to include within enums is the kind that provides additional information about each of the values. The Planet enum is a good example because it provides additional information related to each enum. There is no strict rule to define what is "too much" logic. But if you find yourself implementing a method on an enum that talks to a database, or makes an HTTP connection, I would argue that you're doing too much. In general, the logic you implement inside the enum shouldn't concern itself with other parts of your model or business logic; it shouldn't need access to additional entities from your model, or other services. If you can convey additional information and behavior in the context of the enum itself, then you might be alright. But if you are using the enum to implement complex behavior that involves other entities or services, then the enum is doing too much.
Enum in Java is used for the non-changeable and defined constants.
It seems to me that you would like to have differently behaived classes based on some conditions. If so the strategy patter would be more suitable for this task.
For more info click here.
I have several child classes that extend a parent class, forced to have a uniform constructor. I have a queue which keeps a list of these classes, which must extend MergeHeuristic. The code that I currently have looks like the following:
Class<? extends MergeHeuristic> heuristicRequest = _heuristicQueue.pop();
MergeHeuristic heuristic = null;
if(heuristicRequest == AdjacentMACs.class)
heuristic = new AdjacentMACs(_parent);
if(heuristicRequest == SimilarInterfaceNames.class)
heuristic = new SimilarInterfaceNames(_parent);
if(heuristicRequest == SameMAC.class)
heuristic = new SameMAC(_parent);
Is there any way to simplify that to dynamically instantiate the class, something along the lines of:
heuristic = new heuristicRequest.somethingSpecial();
That would flatten that block of if statements.
It looks like you're using the class on the queue as a sort of flag to indicate what type of request to instantiate. Another approach that doesn't use reflection is to make this flag behavior explicit by introducing an enum to indicate the request type, with a factory method:
public enum HeuristicType {
AdjacentMACsHeuristic(AdjacentMACs.class) {
#Override public MergeHeuristic newHeuristic(ParentClass parent) {
return new AdjacentMACs(parent);
}
},
SimilarInterfaceNamesHeuristic(SimilarInterfaceNames.class) {
#Override public MergeHeuristic newHeuristic(ParentClass parent) {
return new SimilarInterfaceNames(parent);
}
},
... // other types here.
;
private final Class<? extends MergeHeuristic> heuristicClass;
public Class<? extends MergeHeuristic> getHeuristicClass() {
return heuristicClass;
}
abstract public MergeHeuristic newHeuristic(ParentClass parent);
private HeuristicType(Class<? extends MergeHeuristic> klass) {
this.heuristicClass = klass;
}
}
Your client code then becomes:
Queue<HeuristicType> _heuristicQueue = ...
HeuristicType heuristicRequest = _heuristicQueue.pop();
MergeHeuristic heuristic = heuristicRequest.newHeuristic(_parent);
The main advantages of using an enum as opposed to reflection are:
You're explicitly stating the requirements for adding a new heuristic type, i.e. that there must be a heuristic class and that you must be able to instantiate it based on a parent.
You have a single point in the system where you can see all available heuristic types.
By abstracting the instantiation into a factory method, you allow the possibility of alternate constructor signatures.
You could use reflection, but it won't make the code any prettier.
try {
Constructor<? extends MergeHeuristic> heuristicConstructor =
heuristicRequest.getConstructor(_parent.getClass());
heuristic = heuristicConstructor.newInstance(_parent);
} catch (Exception ex) {
// TODO Handle this
}
Only do this if you're planning on having a lot of different classes. Don't bother if it's only going to be 3 of them, your code is fine for that.
Unfortunately you can't enforce a class to have a certain constructor or a static method - both would be very useful in your case.
As all constructors take the same argument there is one other way to simplify your code using dynamic class instantiation:
Constructor c = heuristicRequest.getConstructor(ParentClass.class).
heuristic = c.newInstance(_parent);
Note that your code did not contain the class type of _parent - in the code sample I named it ParentClass.class - you have to adapt that to your code.
Is Class.forName(heuristicRequest.getName()) an option?
Then constructor heuristicRequestClass.getDeclaredConstructor(_parent.getClass());
Last heuristic = constructor.newInstance(_parent);
I've run into a situation in which I was to extend the functionality of a given class, but I'm not sure of the best way to go about this. I started by invoking functionality "upwards" and have now switched to "downwards", but I see issues with both. Let me explain what I mean. First, the "upwards" approach:
public class ParentValidator
{
public void validate() {
// Some code
}
}
public class ChildValidator extends ParentValidator
{
#Override
public void validate() {
super.validate();
// Some code
}
}
public class GrandchildValidator extends ChildValidator
{
#Override
public void validate() {
super.validate();
// Some code
}
}
This functions perfectly well, but it requires that I always remember to place super.validate() in my method body or the logic in the parent class(es) won't be executed. In addition, extension in this manner can be considered "unsafe" due to the fact that a child class could actually replace/modify the code defined in the parent class. This is what I call invoking methods "upwards" because I'm invoking methods from higher level classes as I go.
To counter these shortfalls, I decided to make ParentValidator.validate() final and have it invoke a different method. Here's what my code was modified to:
public class ParentValidator
{
public final void validate() {
// Some code
subValidate();
}
protected void subValidate() {}
}
public class ChildValidator extends ParentValidator
{
#Override
public final void subValidate() {
// Some code
subSubValidate();
}
protected void subSubValidate() {}
}
public class GrandchildValidator extends ChildValidator
{
#Override
public void subSubBalidate() {
// Some code
subSubSubValidate();
}
protected void subSubSubValidate();
}
This is what I was referring to when I say that I'm calling downwards as each class invokes methods on classes "down" the inheritance chain.
Using this approach, I can be guaranteed that the logic in the parent class(es) will be executed, which I like. However, it doesn't scale well. The more layers of inheritance I have, the uglier it gets. At one level, I think this is very elegant. At two levels, it starts to look shoddy. At three or more, it's hideous.
In addition, just as I had to remember to invoke super.validate() as the first line of any of my children's validate methods, I now have to remember to invoke some "subValidate" method at the end of any of my parent's validate methods, so that didn't seem to get any better.
Is there a better way to do this type of extension that I haven't even touched on. Either of these approaches have some serious flaws and I'm wondering if there's a better design pattern I could be using.
In what you describe as your first approach you are using simple inheritance, your second approach is closer to what the Gang of Four [GoF] called a Template Method Pattern because your parent class is using the so-called Hollywood Principle: "don't call us, we'll call you".
However, you could benefit from declaring the subvalidate() method as abstract in the parent class, and by this, make sure all subclasses are forced to implement it. Then it would be a true template method.
public abstract class ParentValidator
{
public final void validate() {
//some code
subValidate();
}
protected abstract void subValidate() {}
}
Depending on what you are doing there are other patterns that could help you do this in a different manner. For instance, you could use a Strategy Pattern to peform the validations, and by this favoring composition over inheritance, as suggested before, but a consequence is that you will need more validation classes.
public abstract class ParentValidator
{
private final ValidatorStrategy validator;
protected ParentValidator(ValidatorStrategy validator){
this.validator = validator;
}
public final void validate() {
//some code
this.validator.validate();
}
}
Then you can provide specific validation strategies for every type of Validator that you have.
If you want to get the best of both worlds you might considering implementing the solution as a Decorator Pattern where subclasses can extend the functionality of a parent class and still stick to a common interface.
public abstract class ValidatorDecorator implements Validator
{
private final Validator validator;
protected ParentValidator(Validator validator){
this.validator = validator;
}
public final void validate() {
//some code
super.validate(); //still forced to invoke super
this.validator.validate();
}
}
All patterns have consequences and advantages and disadvantages that you must consider carefully.
I'd prefer to 1) program against interfaces, and 2) opt for composition over inheritance. This is how I have done. Some people like it, some do not. It works.
// java pseudocode below, you'll need to work the wrinkles out
/**
* Defines a rule or set of rules under which a instance of T
* is deemed valid or invalid
**/
public interface ValidationRule<T>
{
/**
* #return String describing invalidation condition, or null
* (indicating then that parameter t is valid */
**/
String apply(final T t);
}
/**
* Utility class for enforcing a logical conjunction
* of zero or more validatoin rules on an object.
**/
public final class ValidatorEvaluator
{
/**
* evaluates zero or more validation rules (as a logical
* 'AND') on an instance of type T.
**/
static <T> String apply(final T t, ValidationRule<T> ... rules)
{
for(final ValidationRules<T> v : rules)
{
String msg = v.apply(t);
if( msg != null )
{
return msg; // t is not valid
}
}
return null;
}
}
// arbitrary dummy class that we will test for
// i being a positive number greater than zero
public class MyFoo
{
int i;
public MyFoo(int n){ i = n; }
///
}
public class NonZeroValidatorRule implements ValidatorRule<MyFoo>
{
public String apply(final MyFoo foo)
{
return foo.i == 0 ? "foo.i is zero!" : null;
}
}
// test for being positive using NonZeroValidatorRule and an anonymous
// validator that tests for negatives
String msg = ValidatorEvaluator.apply( new MyFoo(1),
new NonZeroValidatorRule(),
new ValidatorRule<MyFoo>()
{
public String apply(final MyFoo foo)
{
return foo.i < 0 ? "foo.i is negative!" : null;
}
}
);
if( msg == null )
{
\\ yay!
...
}
else
{
\\ nay...
someLogThingie.log("error: myFoo now workie. reason=" + msg );
}
More complex, non-trivial evaluation rules can be implemented this way.
The key here is that you should not use inheritance unless there exists a is-a relationship. Do not use it just to recycle or encapsulate logic. If you still feel you need to use inheritance, then don't go overkill trying to make sure that every subclass executes the validation logic inherited from the superclass. Have implementations of each subclass do an explicit execution on super:
public class ParentValidator
{
public void validate() { // notice that I removed the final you originally had
// Some code
}
}
pubic class ChildValidator extends ParentValidator
{
#Override
public void validate() {
// Some code
super.validate(); // explicit call to inherited validate
// more validation code
}
}
Keep things simple, and don't try to make it impossible or fool-proof. There is a difference between coding defensively (a good practice) and coding against stupid (a futile effort.) Simply lay out coding rules on how to subclass your validators. That is, put the onus on the implementors. If they cannot follow the guidelines, no amount of defensive coding will protect your system against their stupidity. Ergo, keep things clear and simple.
I prefer to using composition over inheritance if your subSubSubValidate is related general functionality. You can extract new class and move it there than you can use it without inheritance in the other classes.
There is also
"Favor 'object composition' over
'class inheritance'." (Gang of Four
1995:20)
maybe a look at the visitor pattern may help you to develop your pattern.
Here are some information on it : http://en.wikipedia.org/wiki/Visitor_pattern
I am trying to write a Factory Pattern to create either a MainMode or a TestMode in my program. The code I was previously using to create these objects was:
play = (isMode) ? new MainMode(numberRanges, numberOfGuesses) :
new TestMode(numberRanges, numberOfGuesses, randNo());
My Game (play) would either create a MainMode object or a TestMode object depending on a boolean value (isMode). As you can see I am adding an extra value into my TestMode object (randNo()). This value is used within TestMode to allow the user to input their own "Random Number", whereas within the MainMode constructor this was randomly generated. In this program both MainMode and TestMode are sub-classes of the abstract class Game.
Now I want to replace this line with a Factory Pattern, although I am unsure as my TestMode constructor requires an extra object and I am unsure where I would need to pass this value. If I were going to create a Factory it'd need to be in a new class, probably named GameFactory or ModeFactory or something along those lines.
How would I go about this?
EDIT: The problem here is that the code above is in my GUI, where the values for numberRanges, numberOfGuesses and the randNo() method are. I want to create a Factory class but I am unable to pass these values through because randNo() activates itself. Here is my randNo() method.
private int randNo() {
boolean isValidNumber = true;
int testRandomNum = 0;
while(isValidNumber) {
try {
testRandomNum = Integer.parseInt(JOptionPane.showInputDialog("Enter Random Number"));
isValidNumber = false;
} catch (NumberFormatException e) {
JOptionPane.showMessageDialog(null, "Sorry, but the number you entered was invalid");
}
}
return testRandomNum;
}
The problem is that whenever I pass randNo() it displays the JOptionPane. As I've said already the GUI and Logic is separate. The GUI is in a GUI package whilst the rest of the code is in the logic package.
Note that some of the other answers may arguably describe factories, but don't describe the GOF Factory Pattern.
Now I want to replace this line with a
Factory Pattern, although I am unsure
as my TestMode constructor requires an
extra object and I am unsure where I
would need to pass this value.
Well, you could think of it this way: MainMode, not TestMode, is the one that does a special thing. The special thing it does, is to ignore the given number, in order to ensure it's really random. In this way of thinking about it, it's MainMode that does something extra.
Or, if other than the randomness, MainMode and TestMode are not different, then you'd be thinking perhaps that you can factor out that similarity into one class, which is provided one of two Strategies for calculating random numbers. One Strategy would actually be random, and one would be perverse, with a random range of only 1 value.
But let's assume that there are other differences between MainMode and TestMode -- presumably TestMode outputs extra debugging to System.out or something.
We can still factor out "how do we supply randomness" from are we testing or playing the game for real". These are orthogonal concerns.
So now we know that in addition to whatever else a 'Mode does, it should accept a Randomness Strategy. Then we could, for example, when you're told that the standard platform random isn't really random enough, you can replace it with a better random.
Or you can do testing where the range of randoms is constrained to only two choices, or always alternates from one to zero, or returns on each call the next value in some Vecrtor or Iterator.
So we use the GOF Strategy Pattern to build the randomness strategies:
interface RandomStrategy {
public double random();
}
public class NotSoRandom implements RandomStrategy {
private double r;
public NotSoRandom( final double r ) { this.r = r; }
public double random() { return r; }
}
public class PlatformRandom implements RandomStrategy {
public double random() { return Math.random(); }
}
Now, if your whole app only ever creates one 'Mode, there's no need for a factory; you use a factory when you need to create the same class type over and over; the Factory is in fact just a Strategy for creating the right kind of (sub) class.
In production code, I've used factories where I have some generic class that creates stuff, and I need to tell how to create the right subclass to create; I pass in a factory to do that.
Now we create a Factory pattern for the 'Mode; this will be surprisingly similar to the Strategy pattern:
abstract class Mode() {
private RandomStrategy r;
public Mode( final RandomStrategy r ) { this.r = r; }
// ... all the methods a Mode has
}
public class MainMode implements Mode {
public MainMode( final RandomStrategy r ) { super(r); }
}
public class TestMode implements Mode {
public TestMode( final RandomStrategy r ) { super(r); }
}
interface ModeFactory{
public Mode createMode( final RandomStrategy r );
}
public class MainFactory() {
public Mode createMode( final RandomStrategy r ) {
return new MainMode(r);
}
}
public class TestFactory() {
public Mode createMode( final RandomStrategy r ) {
return new TestMode(r);
}
}
So now you know about the Factory Pattern and Strategy Pattern, and how they're similar in "shape", but different in how they're used: Factory Pattern is Object Creational and returns an object to be used; Strategy is Object Behavioral, and an instance is usually created explicitly and a reference is held to the instance, to encapsulate an algorithm. But in terms of the structure, they're quite similar.
Edit: the OP asks, in a comment, "How would I integrate this into my GUI?"
Well, none of this belongs in the GUI of your program, except possibly the 'Mode. You'd create the ConcreteStrategy and pass it to the preferred Factory in some setup routine, possibly determining which to use based on command line arguments or config files. basically, you'd select the correct factory very much as you selecting the correct class in your original post. Again, if you're only ever creating one of something, you don't need a Factory; factories are for mass production (or creating families of related concrete types -- though that's beyond the scope of this question).
(Assume we have a game where the user can select on the command line whether to fight robots or dragons; then we'd want to instantiate an OpponentFactory that produce Opponents (an interface), with derived classes RobotOpponent and DragonOpponent, and pass that factory to the part of the game that spawnsNewOpponent(). Similarly, a user might select brave or cowardly opponents, which we'd set up as a Strategy. We don't need to make more Strategy instances, as a Strategy is usually idempotent (stateless and singleton).)
static int main( String[] args ) {
// setup game world
final RandomStrategy r = "random".equals(args[0])
? new PlatformRandom() : new NotSoRandom( Integer.intValue(args[0]) ) ;
// notice the simlarity to the code you originally posted;
// we factored out how to achieve "randomness" as a Strategy.
// now we will use our Strategy to setup our Factory;
final ModeFactory f = "test".equals(args[1])
? new TestFactory(r) : new MainFactory(r);
// also similar to your code
// we've just added an extra level of indirection:
// instead of creating a Mode, we've created an object that can create Modes
// of the right derived type, on demand.
// call something that uses our factory
functionThatRunsameAndNeedstoProduceModesWhenevertNeedsTo( f );
}
The whole point of a Factory is that it should have the needed state to create your Game appropriately.
So I would build a factory like this:
public class GameFactory {
private boolean testMode;
public GameFactory(boolean testMode) {
this.testMode = testMode;
}
public Game getGame(int numberRanges, int numberOfGuesses) {
return (testMode) ? new MainMode(numberRanges, numberOfGuesses) :
new TestMode(numberRanges, numberOfGuesses, getRandom());
}
private int getRandom() {
. . . // GUI code here
}
}
Now you can initialize this factory somwhere in your app, and pass it in to whatever code needs to create a Game. This code now doesn't need to worry about what mode it is, and passing extra random params - it uses a well known interface to create Games. All the needed state is internalized by the GameFactory object.
Try somthing like,
abstract class ModeFactory {
public static Mode getMode(isMode, numberRanges, numberofGuesses) {
return isMode ? new MainMode(numberRanges, numberofGuesses) : new TestMode(numberRanges, numberOfGuesses, randNo());
}
public static Mode getMode(isMode, numberRanges, numberofGuesses, someNumber) {
return isMode ? new MainMode(numberRanges, numberofGuesses) : new TestMode(numberRanges, numberOfGuesses, someNumber);
}
}
The class is abstract just to stop intialization. You could modify it to use final and then create a private constructor.
Your code could probably be changed into a factory pattern.
Something like:
public static Mode createMode(boolean isMainMode)
{
if(isMainMode) return new MainMode(...);
return new TestMode(...);
}
Place this method somewhere sensible (this one is tricky, maybe a static ModeFactory)
This assumes that MainMode and TestMode are subtypes of the same type (subclasses or implement Mode interface)
Now all play has to do is call ModeFactory.createMode(...) and pass the appropriate boolean.
Edit (in response to OP update):
Your rand() gets evaluated before the actual constructor is called, and it presents the GUI. Is that what you mean by activating itself?
You have to make the design decision where you want to make the decision about the mode. If you have a GUI and you have a model, it might be preferable to design the GUI to know whether or not the call to random generation (and popup) is necessary before you call the factory method, and then pass the random number to the factory method and let it just pick the correct constructor.
Having it the other way around (model calls your GUI) is trickier and probably a bad idea.
interface ModeFactory {
Mode createMode(int numberRanges, int numberOfGuesses);
}
class MainModeFactory implements ModeFactory {
Mode createMode(int numberRanges, int numberOfGuesses) {
return new MainMode(numberRanges, numberOfGuesses);
}
}
class TestModeFactory implements ModeFactory {
Mode createMode(int numberRanges, int numberOfGuesses) {
return new TestMode(numberRanges, numberOfGuesses, randNo());
}
}
...
play = modeFactory.createMode(numberRanges, numberOfGuesses);
So at startup you create the appropriate mode factory, passing it in to wherever the play needs to be created.
Very simply, ALWAYS USE A PARAMETER, in case the parameter is not used, send null, if you have several parameters for other "Modes", encapsulate them, into a single parameter.
If you are just after factory method, that will create for you a class of a given name try this:
public static MyInterface createClass(String name) throws IllegalAccessException,
InstantiationException, ClassNotFoundException {
try {
Class myClass = Class.forName(name);
MyInterface myObj = (MyInterface) myObj.newInstance();
return myObj;
} catch (ClassNotFoundException ex) {
logger.error("Could not find a class {}", name);
throw ex;
} catch (InstantiationException e) {
logger.error("Class must be concrete {}", name);
throw e;
} catch (IllegalAccessException e) {
logger.error("Class must have a no-arg constructor {}", name);
throw e;
}
}
What you realy want to do, is make a factory, which returns you an object of abstract class or interface (theyr implementors of course). In the factory method you then deside, which implementor to choose. You if you choose an abstract class, you can implement some common logic in it and let other methods unimplemented (declaring them abstract). You would let the concrete descenders implement them depending on theyr need. This is factory design pattern:
public class GridManagerFactory {
public static AbstractGridManager getGridManager(LifecicleAlgorithmIntrface lifecicleAlgorithm, String... args){
AbstractGridManager manager = null;
// input from the command line
if(args.length == 2){
CommandLineGridManager clManager = new CommandLineGridManager();
clManager.setWidth(Integer.parseInt(args[0]));
clManager.setHeight(Integer.parseInt(args[1]));
// possibly more configuration logic
...
manager = clManager;
}
// input from the file
else if(args.length == 1){
FileInputGridManager fiManager = new FileInputGridManager();
fiManager.setFilePath(args[0]);
// possibly more method calls from abstract class
...
manager = fiManager ;
}
//... more possible concrete implementors
else{
manager = new CommandLineGridManager();
}
manager.setLifecicleAlgorithm(lifecicleAlgorithm);
return manager;
}
}
The commoun logic in the abstract class is available to its descenders:
public abstract class AbstractGridManager {
private LifecicleAlgorithmIntrface lifecicleAlgorithm;
// ... more private fields
//Method implemented in concrete Manager implementors
abstract public Grid initGrid();
//Methods common to all implementors
public Grid calculateNextLifecicle(Grid grid){
return this.getLifecicleAlgorithm().calculateNextLifecicle(grid);
}
public LifecicleAlgorithmIntrface getLifecicleAlgorithm() {
return lifecicleAlgorithm;
}
public void setLifecicleAlgorithm(LifecicleAlgorithmIntrface lifecicleAlgorithm) {
this.lifecicleAlgorithm = lifecicleAlgorithm;
}
// ... more common logic and geter-seter pairs
}
The concrete implementor only need implement the method which is declared abstract:
public class FileInputGridManager extends AbstractGridManager {
private String filePath;
#Override
public Grid initGrid() {
return this.initGrid(this.getFilePath());
}
public Grid initGrid(String filePath) {
List<Cell> cells = new ArrayList<>();
char[] chars;
File file = new File(filePath); // for ex foo.txt
// ... more logic
return grid;
}
}
The receiver of AbstractGridManager would call the methods on him and get the logic, implemented in the concrete descenders (and partually in the abstract class methods) without knowing what is the concrete implementation he got. This is also know like inversion of control or dependency injection