I wouldn’t have a problem with the IF
s for a system-specific routine with a very limited scope. It would be the cleanest and most efficient.
But if the idea is to spice up your system with a little bit of the magic frameworks in general use so much, I would take a different approach. Actually it’s not so much different, because in the end it’s based on a map, as some answers have already done.
However, the fundamental difference is in the treatment of the generic value you want to put in and take out of an HTML field. It is not enough to recover and know the type of data, it is necessary to act upon it. If we just put the guy on a map and recover, we’ll end up with several IF
s.
An even worse situation is when the various developers start adding different and customized types to the Beans. Will every time a new need arises you need to fiddle with that code? Don’t want that headache!
One approach would be to use the concept of converters (converters), like JSF, JPA and other Apis that already have this type of resource.
Are we reinventing the wheel? Yes! But it’s worth it, even if it’s for learning!
Defining a Convert
Let’s define a converter that is able to put and recover HTML field values. All we need to do is convert a value from a qualuqer type to String and from String to type again, that is, to go back and forth to an HTML field.
public interface Converter<T> {
String toString(Object value);
T fromString(String str);
}
Implementing Converters basic
String
public class StringConverter implements Converter<String> {
@Override
public String toString(Object value) {
return value.toString();
}
@Override
public String fromString(String str) {
return str;
}
}
Integer
public class IntegerConverter implements Converter<Integer> {
@Override
public String toString(Object value) {
return value.toString();
}
@Override
public Integer fromString(String str) {
return Integer.parseInt(str);
}
}
java.util.Date
public class DateConverter implements Converter<Date> {
@Override
public String toString(Object value) {
return new SimpleDateFormat("dd/MM/yyyy").format(value);
}
@Override
public Date fromString(String str) {
try {
return new SimpleDateFormat("dd/MM/yyyy").parse(str);
} catch (ParseException e) {
throw new IllegalArgumentException("Data inválida: '" + str + "'!");
}
}
}
Managing the Converters
Now that we have some converters, let’s create a class to manage all this.
public class ConverterManager {
private static Map<Class<?>, Converter<?>> converterMap = new HashMap<Class<?>, Converter<?>>();
static {
//default converters
converterMap.put(String.class, new StringConverter());
converterMap.put(Integer.class, new IntegerConverter());
converterMap.put(Date.class, new DateConverter());
}
/**
* Recupera um conversor de um tipo específico
* @param classe Tipo do conversor
* @return Instância do conversor
*/
@SuppressWarnings("unchecked")
public static <T> Converter<T> getConverter(Class<T> classe) {
return (Converter<T>) converterMap.get(classe);
}
/**
* Permite o registro de um novo conversor
* @param classe Tipo do conversor
* @param converter Instância do conversor
*/
public static <T> void registerNewConverter(Class<T> classe, Converter<T> converter) {
converterMap.put(classe, converter);
}
}
The class ConverterManager
initializes some standard converters and allows the developer to register new converters for the types you want.
Example of use
A simple example of what a round-trip code looks like:
//um valor qualquer
Object val1 = 1;
//recupera o converter
Converter<?> converter = ConverterManager.getConverter(val1.getClass());
//converter para String
String str1 = converter.toString(val1);
//converte novamente para inteiro
Integer int1 = (Integer) converter.fromString(str1);
The difference of this basic example is that in your case you will need to use reflection to execute the methods getter and Setter or directly access the Field in question.
I believe that using attributes instead of methods is better, because the code is more efficient and clean. However, this can cause problems if there is any logic in the methods that is important.
Do you have any specific example or context where you are using it? Class architecture might not be the best for this situation. This comparison does not look ideal (as referred to)
– Joao Raposo
You can’t just solve it with
a.getValue().getClass().getName()
? Then just create a map and associate the class name to a return.– Rodrigo Rigotti
Well, the goal of my project is to turn a bean into an HTML form using annotations.
– user5020
Not because where I commented //commands would be different commands for each comparison.
– user5020
What Classea represents in its project?
– Joao Raposo
to create the html form, the main classes are Beaninfo(which amazerna a bean, and values in annotations),Fieldinfo(Amazernar a field and values in annotations), Beanconverter(Convert a bean into html tags ),Fieldconverter(converts the field into html tags), Tag(represents an html tag), Attribute(represents an html attribute),the problem is in Fieldconverter, its main function and create html inputs, and for each type of Attribute a different input is generated ex : for a bool or Boolean and generated 2 Radiobuttons, for a Date and generated input of type datetime-local and etç..
– user5020