Artem's blog

March 24, 2008

Get rid of your nested if operators!

Filed under: Software — Tags: , — Artem @ 3:18 AM

Every one of you know how it is disappointing that you can not use

switch

operators with strings, doubles, your custom objects, etc. But anyway sometimes it is possible to get rid of your nested ifs if you will use static maps. Let us consider an example: here we need to set JavaBean properties of certain types:

 protected static Object fillTestBean(Object bean) throws InvocationTargetException, IllegalArgumentException, IllegalAccessException {
  Method[] methods = bean.getClass().getMethods();

  for (Method method : methods) {
   if (RTTIUtils.isSetter(method)) {
    Class type = RTTIUtils.getSetterType(method);
    if (type == String.class)
     RTTIUtils.invokeSetter(bean, method, testStr);
    else if (type == boolean.class)
     RTTIUtils.invokeSetter(bean, method, testBoolean);
    else if (type == byte.class)
     RTTIUtils.invokeSetter(bean, method, testByte);
    else if (type == char.class)
     RTTIUtils.invokeSetter(bean, method, testChar);
    else if (type == short.class)
     RTTIUtils.invokeSetter(bean, method, testShort);
    else if (type == int.class)
     RTTIUtils.invokeSetter(bean, method, testInt);
    else if (type == long.class)
     RTTIUtils.invokeSetter(bean, method, testLong);
    else if (type == float.class)
     RTTIUtils.invokeSetter(bean, method, testFloat);
    else if (type == double.class)
     RTTIUtils.invokeSetter(bean, method, testDouble);
    else if (type == Boolean.class)
     RTTIUtils.invokeSetter(bean, method, testBooleanObj);
    else if (type == Byte.class)
     RTTIUtils.invokeSetter(bean, method, testByteObj);
    else if (type == Character.class)
     RTTIUtils.invokeSetter(bean, method, testCharacterObj);
    else if (type == Short.class)
     RTTIUtils.invokeSetter(bean, method, testShortObj);
    else if (type == Integer.class)
     RTTIUtils.invokeSetter(bean, method, testIntegerObj);
    else if (type == Long.class)
     RTTIUtils.invokeSetter(bean, method, testLongObj);
    else if (type == Float.class)
     RTTIUtils.invokeSetter(bean, method, testFloatObj);
    else if (type == Double.class)
     RTTIUtils.invokeSetter(bean, method, testDoubleObj);
    else if (type == Date.class)
     RTTIUtils.invokeSetter(bean, method, testDate);
   }
  }

  return bean;
 }

(here all variables starting with test are constants)
Seems really annoying to write all this ifs and, also what if we will need to check values? Another function will also need this nested ifs!
In this case I usually do the following (factory method -like solution):

 private static final Map initObjects = new HashMap();
 private static boolean isCosideredType(Class type) {
  return initObjects.containsKey(type);
 }
 static {
  initObjects.put(String.class, testStr);
  initObjects.put(boolean.class, testBoolean);
  initObjects.put(byte.class, testByte);
  initObjects.put(char.class, testChar);
  initObjects.put(short.class, testShort);
  initObjects.put(int.class, testInt);
  initObjects.put(long.class, testLong);
  initObjects.put(float.class, testFloat);
  initObjects.put(double.class, testDouble);
  initObjects.put(Boolean.class, testBooleanObj);
  initObjects.put(Byte.class, testByteObj);
  initObjects.put(Character.class, testCharacterObj);
  initObjects.put(Short.class, testShortObj);
  initObjects.put(Integer.class, testIntegerObj);
  initObjects.put(Long.class, testLongObj);
  initObjects.put(Float.class, testFloatObj);
  initObjects.put(Double.class, testDoubleObj);
  initObjects.put(Date.class, testDate);
 }

 protected static Object fillTestBean(Object bean) throws InvocationTargetException, IllegalArgumentException, IllegalAccessException {
  Method[] methods = bean.getClass().getMethods();

  for (Method method : methods) {
   if (RTTIUtils.isSetter(method)) {
    Class type = RTTIUtils.getSetterType(method);
    if (isCosideredType(type)) {
     RTTIUtils.invokeSetter(bean, method, initObjects.get(type));
    }
   }
  }

  return bean;
 }
 

2 Comments »

  1. “initObjects.keySet().contains(type)” should be replaced with “initObjects.containsKey(type)”

    Comment by bob — February 26, 2010 @ 3:53 PM

  2. Thank you, Bob. Fixed it.

    Comment by Artem — February 27, 2010 @ 10:40 AM

RSS feed for comments on this post. TrackBack URL

Leave a comment

 

You need to log in to vote

The blog owner requires users to be logged in to be able to vote for this post.

Alternatively, if you do not have an account yet you can create one here.

Powered by Vote It Up

Powered by WordPress