0

I have code similar to following:

void processObjectRecursively(Object obj)
{
    Field[] fields = obj.getClass().getDeclaredFields();

    for(Field field : fields)
    {
        FieldType type = FieldUtils.getType(field); // FieldType is enum
        Object value = field.get(obj);

        switch(type)
        {
            case A:
            processObjectRecursively(value);
            continue;

            case LIST:
            processList((List<?>)value);
            continue;

            case B:
            processB(value);
            continue;

            case C:
            processC(value);
            continue;
        }
    }
}

void processList(List<?> list)
{
    for(Object obj : list)
    {
        processObjectRecursively(obj);
    }
}

void processB(Object obj)
{
    // do something
}

void processC(Object obj)
{
    // do something
}

Now. I don't like this long switch case. So I'm thinking of creating commands and populating a Map with them where the type is the key and the value is its corresponding command object. With this, the method would look something like:

void processObjectRecursively(Object obj)
{
    Field[] fields = obj.getClass().getDeclaredFields();

    for(Field field : fields)
    {
        FieldType type = FieldUtils.getType(field); // FieldType is enum
        Object value = field.get(obj);
        Command command = commandMap.get(type);
        command.execute(value, this); // 'this' needed for calling processObjectRecursively()
    }
}

But for this I will need to create one interface and four more classes. So is this approach okay or is it over-engineered? Can you suggest any other simpler approach to achieve the same effect?

Adeel Ansari
  • 39,541
  • 12
  • 93
  • 133
shrini1000
  • 7,038
  • 12
  • 59
  • 99
  • 3
    You want **break;** not **continue;** statements in that switch block. – Jivings May 25 '12 at 07:05
  • @Jivings won't continue take me to the starting loop again? or will it behave differently than break? – shrini1000 May 25 '12 at 07:25
  • @ Jivings http://stackoverflow.com/questions/2521721/why-cant-i-use-continue-inside-a-switch-statement-in-java – ejb_guy May 25 '12 at 07:32
  • It will jump to the end of the `switch`, which will then jump back to the start of the loop. `Continue` is redundant and confusing. @ejb_guy No clue why you linked me to that question. – Jivings May 25 '12 at 07:36
  • My Bad. I thought you mean that continue will fall to next case. – ejb_guy May 25 '12 at 07:46

4 Answers4

2

Command pattern sounds fine here. But I would rather look for possibility of solving this with various value types, instead of using Object. So, I can simply write one-liner like below,

value.process()
Adeel Ansari
  • 39,541
  • 12
  • 93
  • 133
1

What will happen if there is new type for processing. In first approach you will add case. In case in switch. If you use command pattern, you need to inject the new command and its type and its up and running. I will use Second approach any day

Also why you need to pass this? recurciveProcessing can be command which uses map to get the command to handle request?

ejb_guy
  • 1,125
  • 6
  • 6
  • 'this' points to the object which has 'recursiveProcessing' method, so it's the 'outer' object. I need to pass it to command so command can call 'recursiveProcessing' on outer object. – shrini1000 May 25 '12 at 07:20
  • 1
    There can be AbstrctCommand storing the map. so that all commands have access to Command map and recursive command can use that MAP. I will say this is not command only. This is mix of command and factory. But I can be wrong here. – ejb_guy May 25 '12 at 07:28
1

I agree its always better to avoid switch case statement. So creating a command map would do. Another easier approach could be to add the process method inside your enum so that every enum type knows how to process the data.

coder
  • 4,458
  • 2
  • 17
  • 23
0

There's nothing wrong with that switch block. The JVM has nice ways of dealing with it which don't impact on performance.

Jivings
  • 22,834
  • 6
  • 60
  • 101