Static factory method for subclasses with variable number of constructor arguments

It's more of a style issue where I'm not sure which solution to my problem would be the "cleanest" one.

The implementation details are not important, I want to do the following:

I have an abstract class that is extended by multiple subclasses that are all very similar in nature. I want to hide these classes from the client, making them only available through a static method in the superclass that returns the superclass's reference to the subclass instance (the specific class is determined by the method parameters). So far so good, I think this is a very common thing.

Now these subclasses I'm talking about can be divided into two groups: one group whose members need two parameters to build, and another group whose members need an additional parameter.

So now my question is, how can I let the client get both of these types with a static method like the one above. Am I providing two static methods with different parameters? Am I forcing the client to pass zero on a third optional parameter that is not required by the first group? Is there a design pattern for this? (I looked at the Builder pattern from Effective Java, but as far as I understand it is usually used in a different context). Or can I change the inheritance hierarchy?

Any answers would be appreciated!

EDIT:

I find my question is a bit confusing at the moment, everybody add some code to make it clearer:

abstract class SuperClass{

    public static SuperClass getSuperClass(String type, int i1, int i2, int optional) {

        /*
         *'type' alone determines which concrete subclass is instanciated
         *'optional' is only needed for the construction for some of those 'types'
         *so the implementation of this method might look like this:
         */

        switch(type) {
            case "1":
                return new Subclass1(i1, i2);
                break;
            case "2":
                return new Subclass2(i1, i2, optional);
                break;

        /*
         *So the problem is this: always passing 'optional' is weird if it 
         *is then simply discarded in some cases.
         *Overloading is weird as well because I don't want to split up 
         *the switch statement or check for exceptions in every case 
         *(when optional is/is not declared for types where it 
         *shouldn't/should be)
         */
    }

}

      

+3


source to share


3 answers


You have two options:

Option 1

Yours static factory method

in superclass can be implemented with var-args:

public static SuperClass newInstace(int...parameters) {
     SuperClass superClass = null;
     if(parameters.length == 2) {
          if(parameters[1]>=5) {//instantiate a subclass based on a value
             super = new SubClass1(parameters[0],parameters[1]);
          } else {
             super = new SubClass2(parameters[0],parameters[1]);
          }

     } else if(parameters.length == 3) {
           if(parameters[2]>=5) {
             super = new SubClass3(parameters[0],parameters[1],parameters[2]);
          } else {
             super = new SubClass4(parameters[0],parameters[1],parameters[2]);
          }
     } else {
          throw new IllegalArgumentException("Invalid number of parameters passed to newInstance. Expected number of parameters [min = 2, max = 3]")
     }

     return superClass;
}

      



Option 2

Alternatively, you can overload the method newInstance

and have one that takes 2 parameters and the other takes 3 parameters.

There are pros and cons to both approaches, as described below:

  • When the frequency at which you expect new fields to be introduced into existing subclasses, or the frequency at which you expect new subclasses to be introduced with more fields than existing ones, is extremely low, Approach 1 is the best option.
  • When the frequency with which new fields are expected to appear in existing subclasses, or the frequency with which you expect new subclasses to be represented with more fields than existing ones, is relatively higher, Approach 2 is the best option, as Approach 1 will create very large body.
+1


source


You can pass in config strings or config objects (like Properties) that have as many details as the implementation requires. It can be 1 or 100 arguments. However, there is one and only carry argument for the caller.



0


source


It depends. It looks like your static superclass method is returning an instance SuperClass

. If so, you can return different instances of the subclass according to the optional parameter.

Consider an abstract class Vehicle

. Now two abstract classes SingleDeckVehicle

and MultiDeckVehicle

extend Vehicle

, and the first two parameters are the number of wheels and the number of seats, and the additional parameter will be the number of vehicle decks. Then the number of decks will be important and your client will pass it 1

as the third argument if it needs an instance SingleDeckVehicle

.

However, you can also create another static method. Let's say you have defined a static method Vehicle.getVehicle(int wheelNo, int seatNo, int deckNo)

. You can also define another:, Vehicle.getSingleDeckVehicle(int wheelNo, int seatNo)

which returns Vehicle.getVehicle(wheelNo, seatNo, 1);

.

A similar example is BorderFactory: http://docs.oracle.com/javase/7/docs/api/javax/swing/BorderFactory.html . I hope I understood your question correctly ...

0


source







All Articles