Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I am implementing factory design pattern in java

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){}
}
like image 313
SOP Avatar asked Jul 11 '17 18:07

SOP


Video Answer


2 Answers

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();
like image 150
Edwin Buck Avatar answered Sep 29 '22 23:09

Edwin Buck


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

like image 35
Fuhrmanator Avatar answered Sep 30 '22 01:09

Fuhrmanator