I have thought about making enums for all my fields, but that doesn't look to cool either (i have many classes that implements similar methods). Is there a better way?
public void writeAttribute(String attribute, Object value) {
if (attribute.equals("title")) {
title = (String) value;
} else if (attribute.equals("description")) {
description = (String) value开发者_JAVA技巧;
} else if (attribute.equals("room")) {
room = (Room) value;
} else if (attribute.equals("type")) {
type = AppointmentType.valueOf((String) value);
} else if (attribute.equals("guestCount")) {
guestCount = (Integer) value;
}
}
Depending on the attribute
parameter, i want to map the input value
to the appropriate field. Is there a way to clean up/optimize my code? Writing .equals
for every field isn't too elegant.
Rather than have an individual named member variable for each attribute, have you considered using a HashMap to store attributes? Your class would have an attribute map
Map<String,Object> attributes = new HashMap<String,Object>();
and your method above reduces to
public void writeAttribute(String attribute, Object value) {
this.attributes.put(attribute,value);
}
Since you're casting anyway, you would then have methods that cast the value appropriately when you access it, or cast it yourself at the point of access.
You could put your attribute/value pairs in a map:
public void writeAttribute(String attribute, Object value) {
attributeMap.put(attribute, value);
}
And then mapping them to fields is a little cleaner:
title = (String)map.get(value);
description = (String)map.get(value);
room = (Room)map.get(value);
type = AppointmentType.valueOf((String)map.get(value));
guestCount = (Integer)map.get(value);
you could do this: (feel free to use interface other than Runnable)
interface AttributeEvaluator {
Object getValue(String s);
}
enum Attribute {
TITLE(new AttributeEvaluator() { public Object getValue(String str) { return (String)value; }),
ROOM(new AttributeEvaluator() { public Object getValue(String str) { return (Room)value; });
private Attribute(AttributeEvaluator r) {
this.evaluator = evaluator;
}
public <T> T getValueOf(String str) {
return (T)evaluator.getValue(str);
}
}
I don't think if your method is OK to avoid such if-conditions, try do something like that:
public void writeAttributes(Map<String, Object> attributesMap) {
title = (String) attributesMap.get(TITLE);
description = (String) attributesMap.get(DESCRIPTION);
...
}
where TITLE and DESCRIPTION is your final variables. If you won't have value in your Map for example in description then you'll have there null.
One way is using reflection, check out this post which explains how to get a field and then set the value for it.
You can try
public void writeAttribute(String attribute, Object value) {
Field field = value.getClass().getDeclaredField(attribute);
field.setAccesible(true);
field.set(value);
}
We write preprocessed Java, for which you can find the processing code here.
It gives us string switches. However it adds an additional step to compilation. Files that require processing are named Foo.jpp
and are processed to Foo.java
, but the pervasiveness of String
-based switches in our code more than makes up for this inconvenience.
Example:
/** set flags on added traps */
public void addTrap(JS key, JS function) throws JSExn {
super.addTrap(key, function);
// differentiate between read and write traps
if (function.getFormalArgs().length != 1) {
//#switch (JSU.toString(key))
case "surface": set(SURFACE_READ_TRAP);
case "visible": set(VISIBLE_READ_TRAP);
case "Children": set(CHILDREN_READ_TRAP);
//#end
return;
}
//#switch (JSU.toString(key))
case "x": set(X_TRAP);
case "y": set(Y_TRAP);
case "width": set(WIDTH_TRAP);
case "height": set(HEIGHT_TRAP);
case "minwidth": set(MINWIDTH_TRAP);
case "maxwidth": set(MAXWIDTH_TRAP);
case "minheight": set(MINHEIGHT_TRAP);
case "maxheight": set(MAXHEIGHT_TRAP);
case "contentwidth": set(CONTENTWIDTH_TRAP);
case "contentheight": set(CONTENTHEIGHT_TRAP);
case "surface": set(SURFACE_TRAP);
case "visible": set(VISIBLE_TRAP);
case "Children": set(CHILDREN_TRAP);
case "Enter": set(ENTER_TRAP);
case "Leave": set(LEAVE_TRAP);
case "_Move": set(_MOVE_TRAP);
case "Move": set(MOVE_TRAP);
case "fontsize": renderprops.setTrapFontsize(this);
case "font": renderprops.setTrapFont(this);
case "shrink": set(SHRINK_TRAP);
case "hshrink": set(HSHRINK_TRAP);
case "vshrink": set(VSHRINK_TRAP);
//#end
}
Since Java SE 7 (July 28, 2011) you can switch strings.
精彩评论