5

I am implementing factory design pattern in java where I want to keep one overloaded method in abstract class. Will it violate the factory pattern concept? Or please suggest whether this is right way to implement Factory design pattern ?

abstract class A{
    void meth(int a);
    void meth(int a,int b);
}

class Factory{
    public static A factoryMethod(int a){
         if(a==1){
            return new Ob1();
        }else{
            return new Ob2();
        }
    }
}

class Ob1 extends A{

void meth(int a){}
void meth(int a,int b){}
}
Sermilion
  • 1,920
  • 3
  • 35
  • 54
SOP
  • 773
  • 3
  • 9
  • 26
  • Ok ,but can I keep overloaded methods in it ? – SOP Jul 11 '17 at 18:24
  • This might help https://www.tutorialspoint.com/design_pattern/factory_pattern.htm – Daedric Jul 11 '17 at 18:24
  • Okay, you don't have to have static methods for the factory, but I just think it makes more sense to do so. See here: https://stackoverflow.com/a/929273/5244131 – Rabbit Guy Jul 11 '17 at 18:25
  • It does not matter. You can keep as many methods in your factory as you want. I assume that overloaded method is a different way for creating your A subclassed object. So there is nothing wrong with that. Also, your factory methods should be static. – Sermilion Jul 11 '17 at 18:26
  • @ Sermilion : Ty for suggestion , actually I am bit confused as I am unable to find any stuff related to multiple methods inside Factory. – SOP Jul 11 '17 at 18:28
  • 3
    You cannot find any stuff about it, because there is no restriction on number of methods in your factory class. Just understand the philosophy of the pattern: instantiating a subclass depending on input. The number of methods does not matter. That's the whole point of it. You abstract away the creation of objects and your static factory methods have meaningful names that help in creating objects to the programmer. – Sermilion Jul 11 '17 at 18:35
  • 1
    I am not sure that I understand exactly which overloaded method you are referring to, but... you can have a factory that always produces one concrete type, or a factory that produces one of the concrete types from an inheritance hierarchy of sixty classes. The key is that the *client* of your factory *doesn't see how the concrete types are being constructed*, so you can always change the way you produce objects without the client *ever having to care* – crizzis Jul 11 '17 at 18:45
  • This is a simple factory with a static method. There are many variants of the factory pattern, and they all have names (although not everyone uses them precisely). See https://www.codeproject.com/Articles/1131770/Factory-Patterns-Simple-Factory-Pattern – Fuhrmanator Jul 13 '17 at 13:47

3 Answers3

4

To implement the Factory Pattern first you need to consider what the Factory will produce. Let's produce Vehicles.

public VehicleFactory {
   public Vehicle newVehicle(String type) {
      ...
   }
}

which will produce Vehicles according to the class hierarchy below.

public interface Vehicle {
   public List<Door> getDoors();
}

public class Motorcycle implements Vehicle {
   public List<Door> getDoors() {
       return Collections.<Door>emptyList();
   }
}

public class SportsCar implements Vehicle {
   public List<Door> getDoors() {
       return Collections.<Door>unmodifiableList(Arrays.asList(new Door("driver"), new Door("passenger"));
   }
}

public class Hatchback implements Vehicle {
       public List<Door> getDoors() {
       return Collections.<Door>unmodifiableList(Arrays.asList(new Door("driver"), new Door("passenger"), new Door("back"));
   }
}

Then your VehicleFactory method newVehicle(...) might look like

public Vehicle newVehicle(String type) {
    if ("motorcycle".equals(type)) { return new Motorcycle(); }
    if ("sports car".equals(type)) { return new SportsCar(); }
    if ("hatchback".equals(type)) { return new Hatchback(); }
    return null;
}

Now the main question is "Why would you want to do this?"

Sometimes you want a nice clean interface for building a lot of related items. You give the related items an Interface and a Factory to build them. This allows someone using this part of the software to simply pull in the Interface class and the ItemFactory. They don't see the individual details, which simplifies their code.

Since you hid the implementation details of all of the Vehicles in the above code, if you had a programming error (or wanted to add something), you can fix one of the Vehicles (or add a new Vehicle) to the factory and re-release the library (JAR file) containing the VehicleFactory.

You know that other people have been using the VehicleFactory methods, so you don't have to worry about their code breaking at compile time, and unless you were careless, you can also assure that it will work at runtime.

This is not the same as saying that the behavior won't change. The new implementations of Vehicle will be returned back, hopefully with fewer embedded bugs. Also, since they didn't ask for the "new vehicles" you might have added they won't see them, until they call newVehicle("station wagon") or something like that.

Also, you can change how the Vehicles are built up. For example, if you later decide that you don't want a simple "just construct it in one pass" implementation style, you could alter 'newVehicle(...)' like so

 public Vehicle newVehicle(String type) {
    Chassis chassis;
    if ("motorcycle".equals(type)) {
       chassis = new TwoWheelChassis();
    } else {
       chassis = new FourWheelChassis();
    }
    return new ComponentVehicle(chassis, getDoorCount(type));
 }

where ComponentVehicle implements Vehicle and for some reason requires an explicit Chassis object.

--- update seeing the "number of methods" question in the comments ---

A Factory pattern is not really about the number of methods, but about one method having the ability to build an abstract thing out of one or more concrete things.

So in the example above, I could have

public VehicleFactory {
    public Vehicle newVehicle(String type) { ... }
    public Vehicle newRedVehicle(String type) { ... }
    public Vehicle newBlackVehicle(String type) { ... } 
}

And they would all be acceptible factory methods with respect to the type of the Vehicle, but they would not be factory oriented methods with respect to the color of the Vehicle.

To get a factory method that could handle Type and Color at the same time, the factory method

    public Vehicle newVehicle(String type, String color) { ... } 

might be added. Note that sometimes some combinations just don't make any sense, so it might not be worthwhile packing all factory methods down into a single factory method.

Any method in your factory object is not really a factory method unless it has the potential to return back more than one base type of the interface. Likewise it is not a factory method if you have to specify how to build the object outside of the method.

If you need to pass control of how to build a Vehicle to the client of your "it would have been a factory" method while providing some security they used it in a sane manner, you want the Builder pattern. An example of how a Builder Pattern differs can be seen in the client code below

 VehicleBuilder builder = new VehicleBuilder();
 builder.addDoor("driver");
 builder.addDoor("passenger");
 builder.paintVehicle("red");
 Vehicle vehicle = builder.getVehicle();
Edwin Buck
  • 69,361
  • 7
  • 100
  • 138
  • The factory pattern idea can be used with or without Java's `static` keyword. If you don't use `static` you can have multiple factories in your program (they'll all do the same thing) which can help at a later time with scalability (if that is a concern you encounter). For example, you could very quickly change to a single factory per thread if the `VehicleFactory` is not using `static` methods, but a single instance created in the scope of where it was needed. I recommend avoiding `static` style factories, but the style is independent of the idea behind a factory. – Edwin Buck Jul 11 '17 at 19:07
  • If you don't need multithreading with factories, I don't see why would not I use factory as static or as singleton. It leads to increased number of created objects. Also it becomes another Dependency for my class that I have to create or inject. Correct me if I'm wrong. That's my understanding. – Sermilion Jul 11 '17 at 20:23
  • 1
    You create the object either way. Either it is an instance of the Class, or an instance of Object, and either way it's going to take up the same footprint. However, as an instance of Object, it can get garbage collected when it is out-of-scope, and you can keep your memory footprint from becoming permanently bigger. Classes tend not to be garbage collected (unless you throw away their class loader), and the increases in RAM can eventually fill up your L1 / L2 caches making your program a lot slower. Good OO in Java typically leads to better performance. – Edwin Buck Jul 11 '17 at 20:33
  • 1
    @Sermilion In Java, methods are members of an Object (non-static methods) or members of the Object representing the Class (static methods). Dependencies are between classes. Therefore if you moved the method (static or otherwise) into a Dependent class, then the class you moved it from is no longer the Factory, and the class you moved it to is now the Factory. That's because Factory is a Software Pattern, and anything that matches the pattern is an implementation of the Pattern. Your description of movement effectively renames the Factory, dependencies notwithstanding. – Edwin Buck Jul 12 '17 at 15:19
1

Factory pattern is a vague term, no? There are Simple factories, Factory methods, and Abstract factories. I think you're talking about a Simple Factory here. https://www.codeproject.com/Articles/1131770/Factory-Patterns-Simple-Factory-Pattern

Fuhrmanator
  • 11,459
  • 6
  • 62
  • 111
0

Here is an example of Java factory implementation.

Let's say we have a requirement to create multiple currencies support and code should be extensible to accommodate new Currency as well. Here we have made Currency as interface and all currency would be a concrete implementation of Currency interface.

Factory Class will create Currency based upon country and return concrete implementation which will be stored in interface type. This makes code dynamic and extensible.

Here is complete code example of Factory pattern in Java.

The Currency classes:

interface Currency {
       String getSymbol();
}
// Concrete Rupee Class code
class Rupee implements Currency {
       @Override
       public String getSymbol() {
              return "Rs";
       }
}

// Concrete SGD class Code
class SGDDollar implements Currency {
       @Override
       public String getSymbol() {
              return "SGD";
       }
}

// Concrete US Dollar code
class USDollar implements Currency {
       @Override
       public String getSymbol() {
              return "USD";
       }
}

The Factory:

// Factory Class code
class CurrencyFactory {

       public static Currency createCurrency (String country) {
       if (country. equalsIgnoreCase ("India")){
              return new Rupee();
       }else if(country. equalsIgnoreCase ("Singapore")){
              return new SGDDollar();
       }else if(country. equalsIgnoreCase ("US")){
              return new USDollar();
        }
       throw new IllegalArgumentException("No such currency");
       }
}

// Factory client code
public class Factory {
       public static void main(String args[]) {
              String country = args[0];
              Currency rupee = CurrencyFactory.createCurrency(country);
              System.out.println(rupee.getSymbol());
       }
}

Check out for more Java Factory pattern examples.

Johnny
  • 14,397
  • 15
  • 77
  • 118