Reputation: 801
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){}
}
Upvotes: 5
Views: 3610
Reputation: 15413
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.
Upvotes: 0
Reputation: 70909
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();
Upvotes: 4
Reputation: 12882
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
Upvotes: 1