2

I'm learning Java and I'm fairly new to this. Here is my problem with some pseudocode:

public void objectCaller(int objectNumber) {

   switch(objectnumber) {

     case 1:
     object1.setFill(color.RED);
     break:

     case 2:
     object2.setFill(color.RED);
     break;
     .
     .and so on

    }
}

Is there a way to replace it in a way with something like that?

public void objectCaller(int objectNumber) {

   (object + objectnumber).setFill(color.RED);

}

It is not a concrete problem. I was just thinking about if it is possible to assemble the object names.

Christopher Hackett
  • 6,042
  • 2
  • 31
  • 41
70g50
  • 23
  • 4

2 Answers2

4

There are three approaches you can use to solve the problem (Reflection is the last option I would recommend) :

Option 1 : Employ the Strategy pattern

If method1 and method2 are not objects of classes that are related. Employ the Strategy pattern as follows :

  public interface Filler {
     public void fill(Color color);
  }

Create two classes that fill colors differently :

 public class FloodFill implements Filler {
     public void fill(Color color) {
         //fill using flood fill algorithm
     }
 }

 public class QuickFill implements Filler {
     public void fill(Color color) {
        //fill using quick fill algorithm
     }
 }

You can then use the Map approach explained below :

Option 2 : Use a HashMap

Assuming that method1 and method2 are related either through a common parent or through a parent child relationship, create a HashMap and prepopulate it with method1 and method2 objects :

 Map<String,Filler> methods = new HashMap<>();
 FloodFill method1 = new FloodFill();
 QuickFill method2 = new QuickFill();
 map.put("FloodFill",method1);
 map.put("QuickFill",method2);

You can then change the methodCaller method to :

public void methodCaller(String method,Color color) {
     methods.get(method).fill(color); 
}

The client code can then look like this :

methodCaller("FloodFill",Color.RED);
methodCaller("QuickFill",Color.GREEN);

Using a HashMap instead of a basic array or a List allows you to associate meaningful names to your method calls. The HashMap is kind of a Factory for objects. The String constants used as the key for the Map can be defined as enum instead.

Option 3 : Use reflection :

This is not something I would recommend for this particular case but if you have to, take a look at this answer on how to achieve this trough reflection.

Community
  • 1
  • 1
Chetan Kinger
  • 15,069
  • 6
  • 45
  • 82
2

You could do that by reflection, but for this case is clearly overkill. What about this approach?: Store your objects in an array (or a List) and then use the index to access the required one. Note that I'm assuming that all the objects are of the same class or are least they have a parent-child class relationship, as @ChetanKinger pointed in the comment below.

public void methodCaller(int methodNumber) {
   myArrayOfObjects[methodNumber].setFill(color.RED);
}

PS: In fact, you are trying to compose "object" names, not methods names. In that case you would really need to use the Reflection API

Pablo Lozano
  • 10,122
  • 2
  • 38
  • 59
  • 1
    This will only work if `method1` and `method2` are siblings or in a parent-child relationship. – Chetan Kinger Jun 02 '15 at 15:11
  • 1
    Good point, updating the answer! I Assumed it automatically because they seem to share the same method, but actually that does not have to be always true – Pablo Lozano Jun 02 '15 at 15:13
  • I feel that just because one can use reflection doesn't mean they should. The specific example provided by the OP could better be implemented using the Strategy and Factory pattern. See my answer. – Chetan Kinger Jun 03 '15 at 09:34