Search code examples
oopdesign-patternsabstract-factory

Abstract factory: ways of realization


I'm learning design patterns now and reading different resources for every pattern. I have a question about pattern Abstract Factory. I read about two ways of realization this. I'll write using this factories, without realization. For example, I took making different doors.

First way. We have common class for Door Factory, which consists different methods for making different types of doors (which returns appropriate class of door):

$doorFactory = new DoorFactory();
$door1 = $doorFactory->createWoodDoor();

$doorFactory = new DoorFactory();
$door2 = $doorFactory->createSteelDoor();

Second way. We have parent class DoorFactory and extends classes for WoodDoorFactory and SteelDoorFactory. This classes realises same method createDoor (and return appropriate class of Door)

$woodDoorFactory = new WoodDoorFactory();
$door1 = $woodDoorFactory->createDoor();

$steelDoorFactory = new SteelDoorFactory();
$door2 = $steelDoorFactory->createDoor();

How you think, which way more optimal and canonical?


Solution

  • Please imagine the situation when your factory is passed around, and what client code need to ask the factory is just creating a door (not care about wood and steel), you will see why the 2nd way is better. Let's say we have a class Client with method foo which uses the factory (I'm using Java but it should be easy to understand):

    class Client {
        private DoorFactory factory;
        public Client(DoorFactory factory) { this.factory = factory; }
        public void foo() {
            Door door = factory.createDoor();
        }
    }
    

    Now you can pass a WoodDoorFactory or a SteelDoorFactory or WhateverDoorFactory to the constructor of Client.

    Moreover, not to mention that your 1st way may be a violation of The Single Responsibility Principles since the DoorFactory class knows many things which are probably unrelated. Indeed, it knows how to create a wood door which requires Wood APIs (just example), it knows how to create a steel door which requires Steel APIs. This clearly reduces the opportunity of reusing the DoorFactory class in another environment which does not want to depend on Wood APIs or Steel APIs. This problem does not happen with your 2nd way.