0

I have abstract class-factory Factory with factory-method getProduct() and his child classes.

I have abstract class-product Product and his child classes.

Classes-factories created objects of classes-products.

abstract class Factory { abstract function getProduct(); } class FirstFactory extends Factory { public function getProduct() { return new FirstProduct(); } } abstract class Product { }; class FirstProduct extends Product { } 

In result I can use this client code:

$factory = new FirstFactory(); $firstProduct = $factory->getProduct(); $factory = new SecondFactory(); $secondProduct = $factory->getProduct(); 

Question: what for this pattern is necessary? Because in client code I just can use direct classes:

$firstProduct = new FirstProduct(); $secondProduct = new SecondProduct(); 

3 Answers 3

1

It's important to note that the Factory Pattern is not always the best solution and for simple case, it is even better having simple new. For instance, your example would probably be better without Factory. Factory Pattern takes all its power when you don't need to work on the exact implementation of a class but stay at the 'abstraction layer' (ex. Interface and abstract classes). You can have a look at the "Dependency Inversion Principle DIP" (Depend upon abstraction. Do not depend upon concrete classes).

Factory use case: switching Database with one line

For instance, let's say you have a software that use Database system. For whatever reason, you know the concrete database used (MongoDB, SQL...) may change later. (Or even just need a fake hard coded database in files during the development). The factory pattern allows you to switch from one to another in just one line, by calling the right Factory, since all the implementation depends upon abstraction. (This is actually the DAO pattern that makes a great use of Factory Pattern, see the oracle documentation for more informations: http://www.oracle.com/technetwork/java/dataaccessobject-138824.html)

Concrete example: Game with 2 Factions

Here a concrete and simple example of implementation.

You have 2 Units

  • Peon
  • Warrior

You have 2 Factions

  • Orc
    • Orc Peon
    • Orc Warrior
  • Human
    • Human Peon
    • Human Warrior

2 Players

  • Orc player (Use only Orc units)
  • Human player (Use only Human units)

You want to instantiate both players but the concrete player class should be implemented in the more generic way, so that it can be reused later. This is also really important in case of adding several new faction, you don't want to spend time going back to your player class.

The code sample

To build and run it, copy in Main.java, then javac Main.java and java Main

The result should be

enter image description here

// Factories ---------------------------------------- abstract class AbsUnitFactory { public abstract Warrior creaWarrior(); public abstract Peon creaPeon(); } class OrcFactory extends AbsUnitFactory { public Warrior creaWarrior() { return new OrcWarrior(); } public Peon creaPeon() { return new OrcPeon(); } } class HumanFactory extends AbsUnitFactory { public Warrior creaWarrior() { return new HumanWarrior(); } public Peon creaPeon() { return new HumanPeon(); } } abstract class Unit { public abstract String getRole(); public abstract String getFaction(); @Override public String toString() { String str = new String(); str += "[UNIT]\n"; str += " Role: " + this.getRole() + "\n"; str += " Faction: " + this.getFaction() + "\n"; return str; } } // Warrior Units ---------------------------------------- abstract class Warrior extends Unit { @Override public String getRole() { return "I'm a badass Warrior with the biggest sword!"; } } class OrcWarrior extends Warrior { @Override public String getFaction() { return "Orc"; } } class HumanWarrior extends Warrior { @Override public String getFaction() { return "Human"; } } // Peon Units ---------------------------------------- abstract class Peon extends Unit { @Override public String getRole() { return "I'm a little simple peon... Ready to work."; } } class HumanPeon extends Peon { @Override public String getFaction() { return "Human"; } } class OrcPeon extends Peon { @Override public String getFaction() { return "Orc"; } } // Main components ---------------------------------------- class Player { private AbsUnitFactory factory; private Peon myPeon; private Warrior myWarrior; public Player(AbsUnitFactory pFactory) { this.factory = pFactory; this.myPeon = this.factory.creaPeon(); this.myWarrior = this.factory.creaWarrior(); } @Override public String toString() { return this.myPeon.toString() + this.myWarrior.toString(); } } class Main { public static void main(String[] args) { AbsUnitFactory humanFactory = new HumanFactory(); AbsUnitFactory orcFactory = new OrcFactory(); Player humanPlayer = new Player(humanFactory); Player orcPlayer = new Player(orcFactory); System.out.println("***** Human player *****"); System.out.println(humanPlayer.toString()); System.out.println("***** Orce player *****"); System.out.println(orcPlayer.toString()); } } 

See how the player class can be reused for any faction and the only line that defines witch faction to use is the Factory. (You may even add a singleton).

More resources

These are books I really appreciate (About Design Patterns)

Sign up to request clarification or add additional context in comments.

4 Comments

This is example of Abstract Factory pattern.
If we don't have Peon, and only have Warrior. Then class Player will be create object of Warrior: OrcWarrior or HumanWarrio, Depending on the argument received. And, if in the clent code I need create OrcFactory or HumanFactory, what profit from this pattern? Because I can call: new OrcWarrior; or new HumanWarrior;
I can use: humanPlaywer = new Player(); Player.myWarrior = new HumanWarrior(); I can't understand what profit from pattern Factory Method
The interesting class is the player one. Don't see the Factory Pattern as a way to replace your 'new' but more like a way to automatically switch to the right concret implementation. For simple case, it may be better without factory (So yeah Player.myWarrior = new HumanWarrior(); may be easier). But now imagine the Player has a list of Units and he can create Peon, warrior, and 50 more types. And let's say there is also Elf, Dwarfs... With factory Pattern, you have only one Player class that never change. Only the right factory is given and all Unit creation is automatically done.
1

If you know at compile time that firstProduct is always of type FirstProduct and secondProduct is always of type SecondProduct then there is no need for an factory method.

A factory method is only useful if you want to create a product that might be FirstProduct or might be SecondProduct depending on the runtime type of a factory. Perhaps, for example, the type of the factory is decided by user input.

Comments

0

a Factory can be injected instead of the actual class. Suppose you have a class that can be instantiated only at runtime based on some specific conditions, in this case you cannot do new Foo(...args) . One option is to inject FooFactory instead and have it create the Foo instance for you.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.