3

I am trying to learn creational design patterns, and i think i understand Factory Method pattern now. But on moving to Abstract Factory Pattern, I couldn't find its use. I know i miss something with this, but no idea where.

In Abstract Factory Pattern we will have a an Abstract Factory, and Concrete Factories wil return the instance. Suppose we are dealing with creation of Cars. We will have an Abstract Factory like

public interface CarFactory{
    public Car getCar();
}

And our concrete Factories will be something like

public class AudiFactory{
    public Car getCar(){
        return new Audi();
    }
}

public class VolvoFactory{
    public Car getCar(){
        return new Volvo();
    }
}

And in user class we will use it like

CarFactory factory = new AudiFactory();
Car carAudi = factory.getCar();
factory = new VolvoFactory();
Car carVolvo = factory.getCar();

I think we can build the same functionality using Factory Pattern too

public class CarFactory{

    public Car getCar(String make){
    if("Audi".equals(make))
        return new Audi();
    else if("Volvo".equals(make))
        return new Volvo();
    }
}

And in user class we can

CarFactory factory = new CarFactory();
Car carAudi = factory.getCar("Audi");
Car carVolvo = factory.getCar("Volvo");

If my understanding is correct(please correct me if its wrong), Why we need another design pattern for this?

Dave Schweisguth
  • 36,475
  • 10
  • 98
  • 121
Jomy George
  • 313
  • 3
  • 13
  • Have you read the Design Patterns book of GoF? – Adam Arold Oct 01 '15 at 14:54
  • It is meant to abstract the object creation, a client class for example expects to get a `CarFactory` to constructor and use it to create car, the client class doesnt care what kind of Car it is and it shouldn't know that. If you read GoF book maybe read it again ;p client class should never create a factory itself. – Łukasz Oct 01 '15 at 15:01
  • You may want to check [this](http://stackoverflow.com/questions/1673841/examples-of-gof-design-patterns-in-javas-core-libraries) question. It has a lot of useful examples from the JDK. – Adam Arold Oct 01 '15 at 15:06
  • thanks Lukasz, but cant we have a client class with a string value that represent the type of car ("Audi, or "Volvo") in its constructor? just like the Factory instance? – Jomy George Oct 01 '15 at 15:13

4 Answers4

5

For your example, yes you are right factory pattern can replace abstract factory pattern.

Abstract factory makes sense when you need to create different products of same family without actully knowing the family (Volvo or Audi).

interface Car {}
interface Engine {}
interface Gear {}

interface ICarFactory {
    Car createCar();
    Engine createEngine();
    Gear createGear();
}

class AudiCar implements Car {}
class AudiEngine implements Engine {}
class AudiGear implements Gear {}

class AudiFactory implements ICarFactory {
    public Car createCar() { return new AudiCar(); }
    public Engine createEngine() { return new AudiEngine(); }
    public Gear createGear() { return new AudiGear(); }
}

I believe you can image same things for the Volvo.

Now assume that we have a class that builds a Car and this does not care whether it is an Audi or Volvo.

class CarBuilder {
    public static Car buildCar(ICarFactory factory) {
        Car car = factory.createCar();

        car.setEngine(factory.createEngine());
        car.setGear(factory.createGear());

        return car;
    }
}

Now our builder class can work without knowing the actual brand which makes the builder class conforming to the Open/Closed Principle. If there is a third brand comes in the future our builder class will still be able to build that car without needing to change single line of code. It is opened to extension but closed to change thanks to the abstract factory..

Mehmet Ataş
  • 11,081
  • 6
  • 51
  • 78
2

In your example:

  • Factory Method Pattern is the pattern to create car ( hide implementation of Car creation)

  • Abstract Factory Pattern is the pattern to create Factory of car (Car Factory creation, Not car creation, Focus on factory creation)

  • So you can think: Abstract Factory pattern is a pattern to create Factory of Factory

  • These two pattern are for different purposes.

Abstract Factory Pattern (implementation using Interface/Abstract) + IoC pattern -> Help you to decide what Car factory type used at Runtime - Not at compile time ( Factory Method pattern is not good for this requirements)

LHA
  • 9,398
  • 8
  • 46
  • 85
0

Think about java.sql.Connection object To me, its an abstract factory

It produces Statement, CallableStatement etc for you

Internally it can be OracleStatement or MySQLStatement

Your client code is clean, and it doesnt care how it internally connects the socket to db server

Also see Design Patterns: Abstract Factory vs Factory Method

About your original code

Think about real world, GM cars are not made in Toyota "Factory" or some Generic car factory :)

What you are achieving is getting rid of if-else Think of learning entire design pattern list to simply get rid of if-else in you r code

If Sun had a finite set of databases to deal with, they could write some if else

Fact is

1) SQL driver is not written by sun 2) with this pattern you can "inject" whatever driver in your code, without worrying about how it works, simply relying on interfaces

asking client to pass "Audi" to each call is simply unreasonable

Community
  • 1
  • 1
Kalpesh Soni
  • 6,879
  • 2
  • 56
  • 59
  • Even if we use Factory Pattern, we can achieve the same. what if java.sql.Connection is a FactoryPattern wich accept a String which represent "OracleStatement" or "MySQLStatement". I see the case of passing some invalid values. – Jomy George Oct 01 '15 at 15:09
0

You have understood very well the use of Factory pattern: A factory allows tou to create objects whose type is unknown at compile time (just a subclass of an interface, of corse). Now, take a step beyond:

Right now you have got one CarFactory to create Car objects. But, how will you manage when you need several factories simultaneously in your program?

That is when Abstract Factory comes in: An Abstract Factory is a factory of factories that allows you to create factories whose type is unknown at compile time: So, you will have

public interface AbstractCarFactory
{
    public CarFactory getCarFactory(String area);
}

... and you will be able to implement EuropeanCarFactory, AmericanCarFactory, etc.


Another example of when it is useful an abstract factory is when you have some factory class with parameters in its constructor:

public CarFactory
{
    public CarFactory(boolean cheatingMotor) {...}
}

It is difficult to create one CarFactory object through dynamic instantiation (Class.forName("CarFactory").newInstance()), so one more level of factorization upwards is useful: An abstract factory which decides how to instantiate the CarFactory:

public interface AbstractCarFactory
{
    public CarFactory(boolean cheatingMotor);
}

public class MyAbstractCarFactory implements AbstractFactory
{
    public CarFactory(boolean cheatingMotor)
    {
        return new CarFactory(true);
    }
}

Note: In common applications, the abstract factory pattern is enough to properly parametrize all the application's behaviour. I've never known of an instance where a factory of factory of factories was needed.

Little Santi
  • 8,563
  • 2
  • 18
  • 46