The problem is as follows:
There are the entities Box, Boxvalue, Boxstrategy and then as example "IntegerBoxStrategy".
The concept is quite simple, I'd like to put different kind of types in this box. Sometimes there will be an Integer inside this Box, sometimes a String. I want to be able to do specific conversion between these types (so type specific behaviour -> hence my strategy approach. Every type will require a specific strategy to convert) and these types can be specified with an ENUM.
So after googling a lot (though I'm quite sure this question might be marked as duplicate and say that I haven't googled enough ;) ) i'm trying this approach:
https://www.javaspecialists.eu/archive/Issue123.html
Concise summary of this approach: they use a strategy to implement a taxstrategy for taxpayers. UML will be more easy to understand:
Though in my case, I'd only have one "Taxpayer", aka the BoxType.
fyi: this question is really similar : Conditional behaviour based on concrete type for generic class though -> i want to be able to switch between my BoxValues, and convert "true" into "1". But I think that the approach of the answer might be helpful, Run time type identification. Which in my case would be used to match strategies with their according "supported types".
The problem with the first link is that in every specific strategy implementation, I'm going to have a huge switch. (sample code later on)
My question is not something like "solve this for me please" but more like point me in the general direction. If a simple example could be given how this could be done when you don't have to update every specific strategy implementation when you support a new "boxvaluetype", I'd be really happy. If posssible, I'd like the cleanest design implementation or approach according to the GRASP principles.
public interface typeStrategy {
boolean canChangeToType(Object myvalue,ValueType type);
boolean correctType(Object myvalue);
}
class BoolTypeStrategy implements typeStrategy{
#Override
public boolean canChangeToType(Object myvalue, ValueType type) {
if (correctType(myvalue))
throw new IllegalArgumentException("your initial value should be a boolean!");
switch (type){
case INT:
return true;
case STRING:
return true;
default:
return false;
}
}
#Override
public boolean correctType(Object myvalue) {
if (!(myvalue instanceof Boolean))
return false;
return true;
}
}
In the example, this ValueType is my Enum.
public class BoxValue<T> {
private T value;
private typeStrategy mystrategy;
public BoxValue(T value, typeStrategy strategy) {
this.value = value;
this.mystrategy = strategy;
}
public T getValue() {
return value;
}
public boolean canChangeToType(ValueType type){
return mystrategy.canChangeToType(value, type);
}
}
As you can see, huge switches solve the problem.. So what design patterns, what suggestions are recommended to solve this problem? (fyi: I'd like to resolve this in Java 8, as i am aware that there are these strange "var" types in Java10+)
Related
I have a string that tells me what I want to cast my object to, Is there a way to cast to that object?
Here is some pseudo code that defines what I would like to do
public TypeToCastTo Cast(T object, String TypeToCastTo) {
switch (TypeToCastTo) {
case "foo":
return (foo)T;
case "otherType":
return (otherType)T;
...
}
}
edit
I wanted to create a game where I can click on a button to purchase something e.g. sword or armour which inherits from worldObject. I figure since I might be returning a weapon or armour class (which both inherit from worldObject) that it would make sense to return a worldObject and then downcast to the correct class (Based off it's name (String)).
edit 2:
As mentioned in the comments this is an XY problem. I was originally trying to make a function that would return the downcast type but in reality that doesn't make sense, since in the case it is used somewhere else, i will need a switch statement to determine what to do with the object anyway (at this point i can cast) so rather than having
public TypeToCastTo Cast(T object, String TypeToCastTo) {
switch (TypeToCastTo) {
case "foo":
return (foo)T;
...
}
}
And using my function to cast the WorldObject, I can have
Method DoingSomethingWithWorldObject(WorldObject T) {
switch(T.typeToCastTo) {
case "foo":
foo temp = (foo)T;
// code using temp
case "other":
other temp = (other)T;
// code using temp
...
}
}
although several people mentioned it was probably wrong the way i was thinking of doing it, Including the answer i have marked correct (Which answered my question even though i was asking the wrong question), The reason i actually understood this was because of a response that was deleted.
As mentioned in the comments, you can do this by using reflection with the Class.cast method:
public Object cast(Object object, String typeToCastTo) {
switch (typeToCastTo) {
case "foo":
return Foo.class.cast(object);
case "otherType":
return OtherType.class.cast(object);
}
}
However the return type of the method needs to be Object as you don't know the actual return type that is encoded in the typeToCastTo parameter.
That is it only makes at least some sense, if you have an instance of Class at hand:
Class<Foo> fooClass = (Class<Foo>) Thread.currentThread().getContextClassLoader().loadClass("my.foo.Foo");
Foo fooObject = foo.cast(object);
But all of this seems rather pointless...
Based on the comments. To invoke a parent class' private method, you don't need to cast:
Object object = new SubFoo();
Method privateFooMethod = Arrays.asList(ParentFoo.class.getDeclaredMethods())
.stream().filter(m -> m.getName().equals("privateFooMethod")).findAny()
.get();
privateFooMethod.setAccessible(true);
privateFooMethod.invoke(object);
But you should really think twice before using reflection to achieve something like this. This very much looks like a bad class/interface design resulting in weird solutions for rather basic needs.
Alternative approach (though I don't know if it's considered bad practice):
public TypeToCastTo Cast(T object, String TypeToCastTo) {
switch (TypeToCastTo) {
case "foo":
return new Foo(object);
case "otherType":
return new OtherType(object);
...
}
}
You'll need specific constructors with corresponding parameters (overloaded) for the different types you'd like to address though. Within those constructors you can control the exact "translations" from one type to another.
I had this case where I needed that all the objects in a collection have a specific boolean value in a field. extracting() seemed like a very good candidate for this. I was able to 'access' the field pretty easily but when I wanted to check it againt the value I was not able to find a clean way to do it in the API. The first thing I came up was the following:
SomeService someService = new SomeService();
List<ClassA> llList = someService.getList();
assertThat(llList).extracting("someBoolean")
.are(new Condition<Object>() {
#Override
public boolean matches(Object o) {
return Boolean.FALSE.equals(o);
}
});
This seems like it is such common thing to check that I am buffled that I could not find something better in the AssertJ API. To enhance readability I next did the the following:
assertThat(llList).extracting("someBoolean")
.are(createBooleanCondition(false));
public static Condition<Object> createBooleanCondition(boolean expected){
return new Condition<Object>() {
#Override
public boolean matches(Object o) {
return new Boolean(expected).equals(o);
}
};
}
Is there a cleaner way to express this kind of assertion with the AssertJ?
NOTE: I could use a java8 lambda to make this cleaner but my question is geared towards assertj and I also have the hard rule that I need this to compile in java 1.7.
To check that every extracted boolean values are false, I would simply do:
assertThat(llList).extracting("someBoolean").containsOnly(Boolean.FALSE);
A quite simple way for that is...
assertThat( llList ).filteredOn( "someBoolean", Boolean.FALSE ).isEmpty();
Of course, this will require reflection on AssertJ's side, but that's the price to pay for something like that...
I'm receiving from a webservice a list of key-value pairs, and have inherited the following code:
public String iconValue = null;
... (over 50 class variables assigned in MyObject constructor below)
public MyObject(List<Attribute> attrs) {
String attrName, attrValue;
for (Attribute a : attrs) {
try
{
attrName = a.getName();
attrValue = a.getValue();
if (attrValue == null || "".equals(attrValue.trim()))
continue;
if (ICONS.equals(attrName)) {
//Do something including assignment
this.iconValue = attrValue;
}
else if (URL.equals(attrName))
{
//Do something including assignment
}
else if (...) A giant list of over 50 different attributes hardcoded
{
//Do something including assignment
}
...
So,except for keeping a hashmap - is there a better way than the above to keep hard coded variables within the class and use this "when-if" pattern.
Also,does this pattern have a name?
One way I can think about is to use ENUMs and dynamically dispatch the works to each of the ENUM object, instead of doing a huge if else, esp. since ENUMs can be looked up by their names.
That would be like a strategy pattern.
For example:
Implement an ENUM to have a method doJob() for each of the instances;
Use the valueOf() method to dispatch the works.
Code sample:
public enum Strategies {
URL {
#Override
public void doJob(MyObject mo) {
// do the work
}
},
ICONS {
#Override
public void doJob(MyObject mo) {
// another work
}
};
public abstract void doJob(MyObject mo);
}
And when using it,
try {
Strategies.valueOf(attrName).doJob();
} catch (IllegalArgumentException e) {
// ENUM does not exist, illegal parameter
}
If you want to take a different action for each possible value of attribute, you will end up with something about that verbose, I'm afraid. Some improvements though:
If you are using Java7 or above, you can now use switch statements with Strings (link)
If you are not, you could create an Enum that has a static method that returns an Enum element you could switch on. It's no performance improvement, but it might help with readability of your code.
Does this pattern have a name?
Nope.
In Java 7 you can express that as:
switch (attrName) {
case ICONS:
//Do something including assignment
break;
case URL:
//Do something including assignment
break;
// and so on
}
... provided that ICONS, URL and the other strings are compile-time constants.
That is more concise and more robust. It is also (probably) more efficient because the switch can most likely be implemented using hashing.
I don't think it has a name, but you could call it "using polymorphism wrong" (if type safety is a concern). It depends on whether you have a well defined data contract or not. Is the data you're receiving a proper object, or just "random" data?
If it's a proper object I would create a concrete representation and use something like Dozer (or if you don't want to be tied down wit dependency, roll your own mapper using reflection) to convert between them.
If it's more or less random data, I'd just use a Map, or similar data structure.
I have written a Java enum where the values have various attributes. These attributes could be stored in any of the following ways:
Using fields:
enum Eenum {
V1(p1),
V2(p2);
private final A attr;
public A attr() { return attr; }
private Eenum(A attr) {
this.attr = attr;
}
}
Using abstract methods:
enum Eenum {
V1 {
public A attr() { return p1; }
},
V2 {
public A attr() { return p2; }
}
public abstract A attr();
}
Using class level map:
enum Eenum {
V1,
V2;
public A attr() { return attrs.get(this); }
private static final Map<Eenum, A> attrs;
static {
ImmutableMap.Builder<Eenum, A> builder = ImmutableMap.builder();
builder.put(V1, p1);
builder.put(V2, p2);
attrs = builder.build();
}
}
How should I decide when to prefer which?
Thanks!
I would do the one which you think is the simplest.
In general I don't write code which can be implemented using data. I would use the first one.
My actual use case has some attributes which are not relevant for all enum values
You can use a combination of these approaches if it makes sense on a per attribute basis.
A fourth option is to not have an abstract method.
enum Eenum {
V1 {
public A attr() { return p1; }
},
V2 {
public A attr() { return p2; }
},
V3, V4, V5, V6;
public A attr() { return defaultA; }
}
None of those. Do this:
interface HasAttr<T> {
T attr();
}
enum Eenum implements HasAttr<A> {
// use "fields" version - ideally with constructor version
public A attr() {
return field;
}
}
This pattern follows the fundamental Abstract Type design pattern, which allows for method like:
public void someMethod(HasAttr<A> hasAttr); // pass anything that is HasAttr<a>
in preference to the fixed type:
public void someMethod(Eenum eenum); // locked into passing an Eenum
Also, and importantly, it's easier to mock for testing, especially if your enum uses real connections etc.
I grant you, all this only applied if the enum is "nontrivial". If it's just a plain old enum, I agree it's just code bloat (which I also detest)
(I am answering my own question so that I can share some things I learned while trying out things.)
Here are the questions you should ask to come at a decision for your specific case:
1: Do the attribute values involve forward references?
Sometimes V1's attribute may need a reference to V2 and vice versa. This is not a rare case. If you are dealing with such an enum, approach 1 simply would not work. The compiler will (rightly) complain about illegal forward references. Any of the other two approaches can be used.
Now, if the attribute value is expensive to compute and a constant, you'd want that it's computed only once. With approach 2, you'd have to introduce local variables per enum value, and cache results there. This is verbose but will give you better performance. With approach 3, the results are anyway computed only once, and so don't have to do any extra work. This is more readable but somewhat less performant than approach 2. Design between these as per the specific trade offs warranted in your case.
2: Do I need to cache results?
Refer to the second paragraph of previous bullet.
If there are no forward references, you can use approach 1 too. But if the computation involved in calculation of attributes is complex, you are better off with one of the other two approaches.
3: Are the attributes relevant for all of the enum values?
If not, then quite logically, you should be using a Map here. That is, approach 3.
4: Are there any default values for some attributes for some enum values?
If so, you can use all three approaches, and they all offer different set of trade-offs.
With approach 1: You would define an auxiliary constructor that initializes the attribute to the default value. If there are multiple such attributes, this might not be a feasible approach.
With approach 2: This will actually be like "fourth" approach Peter Lawrey suggested above. You will have a method returning the default value in enum's main body. And some enum values will override this method to return a different value. This is, again, quite verbose.
With approach 3: Just less efficient. Good in every other way.
I'm looking at some GXT code for GWT and I ran across this use of Generics that I can't find another example of in the Java tutorials. The class name is com.extjs.gxt.ui.client.data.BaseModelData if you want to look at all of the code. Here are the important parts:
private RpcMap map;
public <X> X get(String property) {
if (allowNestedValues && NestedModelUtil.isNestedProperty(property)) {
return (X)NestedModelUtil.getNestedValue(this, property);
}
return map == null ? null : (X) map.get(property);
}
X is defined nowhere else in the class or anywhere in the hierarchy, and when I hit "go to declaration" in eclipse it just goes to the <X> in the public method signature.
I've tried to call this method with the following two examples to see what happens:
public Date getExpiredate() {
return get("expiredate");
}
public String getSubject() {
return get("subject");
}
They compile and show no errors or warnings. I would think at the very least I would have to do a cast to get this to work.
Does this mean that Generics allow a magic return value that can be anything and will just blow up at runtime? This seems counter to what generics are supposed to do. Can anyone explain this to me and possibly give me a link to some documentation that explains this a little better? I've went through Sun's 23 page pdf on generics and every example of a return value is defined either at the class level or is in one of the parameters passed in.
The method returns a type of whatever you expect it to be (<X> is defined in the method and is absolutely unbounded).
This is very, very dangerous as no provision is made that the return type actually matches the returned value.
The only advantage this has is that you don't have to cast the return value of such generic lookup methods that can return any type.
I'd say: use such constructs with care, because you lose pretty much all type-safety and gain only that you don't have to write an explicit cast at each call to get().
And yes: this pretty much is black magic that blows up at runtime and breaks the entire idea of what generics should achieve.
The type is declared on the method. That's that "<X>" means. The type is scoped then to just the method and is relevant to a particular call. The reason your test code compiles is that the compiler tries to determine the type and will complain only if it can't. There are cases where you have to be explicit.
For example, the declaration for Collections.emptySet() is
public static final <T> Set<T> emptySet()
In this case, the compiler can guess:
Set<String> s = Collections.emptySet();
But if it can't, you must type:
Collections.<String>emptySet();
I was just trying to figure out the same thing with a GXT class. Specifically I was trying to call a method with the signature of:
class Model {
public <X> X get(String property) { ... }
}
To call the above method from your code and have it cast X to a String I do the following:
public String myMethod(Data data) {
Model model = new Model(data);
return model.<String>get("status");
}
The above code will call the get method and tell it that the type being returned by X should be returned as a String.
In the case where the method is in the same class as you, I've found that I have to call it with a "this.". For example:
this.<String>get("status");
As others have said, this is rather sloppy and dangerous by the GXT team.
BaseModelData raises unchecked warnings when compiled, because it is unsafe. Used like this, your code will throw a ClassCastException at runtime, even though it doesn't have any warnings itself.
public String getExpireDate() {
return get("expiredate");
}
Interesting note, from RpcMap (GXT API 1.2)
get's header:
public java.lang.Object get(java.lang.Object key)
Having a generic parameter of <X> in there that's uninstantiated has the same effect, except you don't have to say "Object" all over the place. I agree with the other poster, this is sloppy and a bit dangerous.
Yes, this is dangerous. Normally, you'd protect this code like so:
<X> getProperty(String name, Class<X> clazz) {
X foo = (X) whatever(name);
assert clazz.isAssignableFrom(foo);
return foo;
}
String getString(String name) {
return getProperty(name, String.class);
}
int getInt(String name) {
return getProperty(name, Integer.class);
}