1 2 Previous Next 15 Replies Latest reply on May 22, 2009 8:41 AM by Tolls

    Calling a different function based on an enum value

    843789
      Hi,

      I have just started OOP programming and was wondering how to achieve this:

      Lets say I have Class Parent which has three children Child 1, Child 2, Child 3. I want to be able to make a call like below:

      manager = new Parent(configurationList, CHILD1)

      where CHILD1 is an enum value. Depending on the input, the Parent should be able to assign a proper class to the object 'manager'. I was thinking of making the Child1, Child2, and Child3 extend the Parent class but I'm somehow lost in its implementation. Could I have some help please?
        • 1. Re: Calling a different function based on an enum value
          Herko_ter_Horst
          It's not clear what you are trying to achieve. Perhaps this is because you are using terminology in a non-standard way. In addition, you don't show what enums have to do with your problem or what the 'manager' object is. Please try to explain more clearly what you are trying to do.
          • 2. Re: Calling a different function based on an enum value
            Tolls
            The Parent class shouldn't really know about the existence of any classes that extend it (ie the children).

            What you're talking about is some sort of Factory method (it's a design pattern) that returns a Parent, but inside it builds the specific subclass based on the data passed into the method (probably the data you're passing into your Parent construcotr in the example you give).
            • 3. Re: Calling a different function based on an enum value
              843789
              Ah... sorry about that... I'm still getting a hang of all the terminologies. I apologize for the mess ups. I'll try to explain my problem in detail below by considering a hypothetical situation:

              Lets say I am designing a simulation program. The program has some pluggable components out of which the underlying algorithm is designed as a separate component. So I would run the entire simulation but I would just change the underlying algorithm for each run for a different dataset. So, at one place I have a line that says:

              AlgorithmName anObject= new AlgorithmName();

              I can get away with my whole problem by going into the code and changing this line everytime for a new algorithm but what I want to do is to have one class that takes a parameter as input which determines which object to return. For instance, if I have Bubble Sort, Insertion Sort and Quick Sort, instead of doing like this:

              QuickSort qs = new QuickSort(data)

              and for Insertion Sort: InsertionSort isa = new InsertionSort(data) etc., I am trying to achieve something like this:

              Algorithm al = new Algorithm(data, "QuickSort");

              Everything else in the program is the same but depending on the parameter (second one in this case), I want an object of a different class returned. Any small example on how to go about designing this will be great.

              Thanks

              @Tolls:

              Thanks for your reply. After you specified that, I went ahead and read about the Factory design pattern and I think I am looking for something like that but I'm getting confused while implementing it. I will keep trying and get back. Thanks...
              • 4. Re: Calling a different function based on an enum value
                Tolls
                Give the factory a go and come back if you hit a snag.
                So long as you grasp OO you should get most of it in place without too much trouble.
                • 5. Re: Calling a different function based on an enum value
                  843789
                  Thanks. I think I got it. Here's what I've done:

                  ==================Parent===================
                  public class parent {
                       
                       public String typed;
                       
                       public String getType() {
                            return typed;          
                       }
                       
                       public void setType(String e) {
                            this.typed = e;
                       }
                  }

                  ==================Child1==================
                  public class child1 extends parent {
                       
                       public String msg = "Child1";
                       
                       public child1() {
                            System.out.println(msg);
                       }
                  }

                  ==================Child2==================
                  public class child2 extends parent {
                       public String msg = "Child2";
                       
                       public child2() {
                            System.out.println(msg);
                       }
                  }

                  ==================Factory==================
                  public class factory {
                       

                       public static void main(String args[]) {
                            factory f = new factory();
                            f.getAlg("CHILD1");
                       }

                       public parent getAlg(String e) {
                            if (e.equals("CHILD1"))
                                 return new child1();
                            else if(e.equals("CHILD2"))
                                 return new child2();
                            else
                            return null;
                       }
                  }

                  I think that is what I want to achieve but if there's a better way to do the same, please suggest one. Thanks again.
                  • 6. Re: Calling a different function based on an enum value
                    843789
                    Hi,

                    I am not sure that I got what you wanted but I do think it would be easier to do something along those lines :

                    public class MyClass{

                    public enum ALGORITHM
                    {
                    ALG1("the Name 1"),
                    ALG2("the Name 2");

                    private static final Map<String, ALGORITHM> NAME_VALUE;

                    static
                    {
                    final Map<String, ALGORITHM> theMap = new HashMap<String, ALGORITHM>();
                    for (final ALGORITHM anAlgorithm : ALGORITHM.values())
                    {
                    theMap.put(anAlgorithm.getName(),
                    anAlgorithm);
                    }
                    NAME_VALUE = Collections.unmodifiableMap(theMap);
                    }

                    public static ALGORITHM findByName(String inName){
                    return NAME_VALUE.get(inName);
                    }

                    private final String name;


                    private ALGORITHM(String inName)
                    {
                    this.name = inName;
                    }


                    public String getName()
                    {
                    return this.name;
                    }

                    }

                    }

                    Let me know if your question has been answered.

                    Regards
                    • 7. Re: Calling a different function based on an enum value
                      Tolls
                      EliteLegend wrote:
                      Thanks. I think I got it. Here's what I've done:

                      I think that is what I want to achieve but if there's a better way to do the same, please suggest one. Thanks again.
                      Yep, that's pretty much what a factory method does.

                      Just a note, Java standards mean a class name should start with a capital (so Parent, Child and Factory).

                      If there's no common processing involved, that is no functionality that sits up with the Parent, then Parent should probably be an interface rather than a class. Not that this is overly important for your current situation.
                      • 8. Re: Calling a different function based on an enum value
                        Tolls
                        public class MyClass {
                        
                             public enum ALGORITHM {
                                  ALG1("the Name 1"), ALG2("the Name 2");
                        
                                  private static final Map<String, ALGORITHM> NAME_VALUE;
                        
                                  static {
                                       final Map<String, ALGORITHM> theMap = new HashMap<String, ALGORITHM>();
                                       for (final ALGORITHM anAlgorithm : ALGORITHM.values()) {
                                            theMap.put(anAlgorithm.getName(), anAlgorithm);
                                       }
                                       NAME_VALUE = Collections.unmodifiableMap(theMap);
                                  }
                        
                                  public static ALGORITHM findByName(String inName) {
                                       return NAME_VALUE.get(inName);
                                  }
                        
                                  private final String name;
                        
                                  private ALGORITHM(String inName) {
                                       this.name = inName;
                                  }
                        
                                  public String getName() {
                                       return this.name;
                                  }
                        
                             }
                        
                        }
                        How would this code go about returning an instantiation of the correct class?
                        Out of curiosity.
                        • 9. Re: Calling a different function based on an enum value
                          843789
                          With this code he could retrieve the right algorithm from its name given that it is an element of the enum. Also if the object needed is not an element of the enum he can easily add a field to the enum objects to get the instance. I only displayed a simple example of how to go with his initial idea of an enum thinking that he wanted to use a feature linked with enum, like if he wanted a unique instance, not carrying the String in multiple areas of the code...

                          Also instead of carrying Child1, Child2 ... he could use directly the element of the enum. Essentially Parent would be ALGORITHM and each Child would be ALGs.

                          Only a different implementation not a different concept.

                          Edited by: Slorg1 on May 21, 2009 8:56 AM
                          • 10. Re: Calling a different function based on an enum value
                            Tolls
                            Slorg1 wrote:
                            With this code he could retrieve the right algorithm from its name given that it is an element of the enum. Also if the object needed is not an element of the enum he can easily add a field to the enum objects to get the instance. I only displayed a simple example of how to go with his initial idea of an enum thinking that he wanted to use a feature linked with enum, like if he wanted a unique instance, not carrying the String in multiple areas of the code...

                            Also instead of carrying Child1, Child2 ... he could use directly the element of the enum. Essentially Parent would be ALGORITHM and each Child would be ALGs.

                            Only a different implementation not a different concept.

                            Edited by: Slorg1 on May 21, 2009 8:56 AM
                            So you'd have an object attached to each element, which would presumably be a subclass of something like Parent, which would then be run?

                            eg. ALG1("First algorithm",new FirstAlgorithm())
                            FirstAlgorithm being a subclass of ParentAlgorithm? That sort of thing?

                            That'd work, but I'm not too comfortable with the idea of these fixed objects. I can (sort of) see it working here, but it's not really a replacement for a factory. It also doesn't seem terribly thread friendly.
                            • 11. Re: Calling a different function based on an enum value
                              843789
                              Tolls wrote:

                              eg. ALG1("First algorithm",new FirstAlgorithm())
                              FirstAlgorithm being a subclass of ParentAlgorithm? That sort of thing?
                              Yes like that or having ALG1 actually being FirsAlgorithm to avoid multiple classes, I mean you can implement methods in an enum it is not just to have a set of values.
                              Tolls wrote:
                              That'd work, but I'm not too comfortable with the idea of these fixed objects. I can (sort of) see it working here, but it's not really a replacement for a factory. It also doesn't seem terribly >thread friendly.
                              It is very thread friendly as attached to the class loading process (the safest in Java). These fixed objects are very useful when you need something fixed like that. It is more like using a very powerful immutable set of unique objects.
                              • 12. Re: Calling a different function based on an enum value
                                Tolls
                                Slorg1 wrote:
                                Tolls wrote:

                                eg. ALG1("First algorithm",new FirstAlgorithm())
                                FirstAlgorithm being a subclass of ParentAlgorithm? That sort of thing?
                                Yes like that or having ALG1 actually being FirsAlgorithm to avoid multiple classes, I mean you can implement methods in an enum it is not just to have a set of values.
                                Yes, you can have methods...except that every enum would have the same methods. Which wouldn't be much use for varying algorithms...because each call would do the same thing. Or am I missing something blindingly obvious here (it is hometime after all)?

                                >
                                Tolls wrote:
                                That'd work, but I'm not too comfortable with the idea of these fixed objects. I can (sort of) see it working here, but it's not really a replacement for a factory. It also doesn't seem terribly >thread friendly.
                                It is very thread friendly as attached to the class loading process (the safest in Java). These fixed objects are very useful when you need something fixed like that. It is more like using a very powerful immutable set of unique objects.
                                Not really. Enums don't change, so in themsleves are very thread safe. However if you store objects in them (ie a FirstAlgorithm object) that may hold some sort of state, then it ceases to be thread safe. For example, if you have a
                                public void processData(Data stuff) {...}
                                method, and a
                                public void Result getResult() {...}
                                method you probably won't work too well in a multi-threaded environment.
                                • 13. Re: Calling a different function based on an enum value
                                  843789
                                  Tolls wrote:
                                  Yes, you can have methods...except that every enum would have the same methods. Which wouldn't be much use for varying algorithms...because each call would do the same thing. Or am I missing something blindingly obvious here (it is hometime after all)?
                                  Well just like regular objects enum fields can override methods and enum can declare abstract methods.

                                  Tolls wrote:
                                  That'd work, but I'm not too comfortable with the idea of these fixed objects. I can (sort of) see it working here, but it's not really a replacement for a factory. It also doesn't seem terribly >thread friendly.
                                  It is very thread friendly as attached to the class loading process (the safest in Java). These fixed objects are very useful when you need something fixed like that. It is more like using a very powerful immutable set of unique objects.
                                  Not really. Enums don't change, so in themsleves are very thread safe. However if you store objects in them (ie a FirstAlgorithm object) that may hold some sort of state, then it ceases to be thread safe. For example, if you have a
                                  public void processData(Data stuff) {...}
                                  method, and a
                                  public void Result getResult() {...}
                                  method you probably won't work too well in a multi-threaded environment.
                                  Well, it is the same a regular objects for that matter it is at the developer's discretion. The whole initialization including the call of the constructors is Thread safe, the methods are just as safe as you write them just like anything.

                                  Edited by: Slorg1 on May 21, 2009 9:38 AM
                                  • 14. Re: Calling a different function based on an enum value
                                    EJP
                                    except that every enum would have the same methods. Which wouldn't be much use for varying algorithms...because each call would do the same thing. Or am I missing something blindingly obvious here (it is hometime after all)?
                                    You are.
                                    enum Colour
                                    {
                                      Red { public String toString() { return "red";}},
                                      Blue { public String toString() { return "blue"; }};
                                    
                                      public abstract String toString();
                                    }
                                    1 2 Previous Next