Wzorzec fabryka i jego odmiany

Jak przychodzi do poznania wzorca fabryki to sprawa nie jest prosta – w przypadku innych wzorców wpisujemy frazę „wzorzec xxx” i mamy konkretne artykuły i UMLe. Jeśli chodzi o fabrykę to jest to bardziej skomplikowane – istnieje wiele odmian tego wzorca. Nie będę w tym wpisie podejmował wyjaśniania do czego służy wzorzec fabryka – ponieważ istnieje już wiele materiałów dostępnych w sieci.

I tak, przeglądając literaturę/Internet można natrafić na:
1. Prostą fabrykę (Simple Factory)
2. Fabrykę (Factory)
3. Metodę fabrykującą (Factory Method)
4. Abstrakcyjną fabrykę (Abstract Factory)

Prosta fabryka

Według niektórych źródeł nie jest to wzorzec projektowy. Jest to coś co przypomina fabrykę – podajemy jako argument metody parametr, a w środku następuje decyzja jaka implementacja zostanie wybrana:

public class CarFactory {
    public Car create(String type){
        if(type == "BMW"){
            return new BMW();
        }
        else if(type == "Mercedes"){
            return new Mercedes();
        }
        //...
    }
}

Fabryka

W tym przypadku mowa jest o klasie, która ma konkretne opcje tworzenia obiektów (nie ma parametrów):

public class CarFactory {
    public BMW createBMW(){
        return new BMW();
    }
    public Mercedes createMercedes(){
        return new Mercedes();
    }
    //...
}

Metoda fabrykująca

Używana gdy chcemy „wyciągnąć” z naszej klasy i potraktować jako możliwość wyboru tworzenie obiektu/obiektów:

abstract class RentalCar {

    protected abstract Car chooseCar();

    public void rentCar(){
        Car car = this.chooseCar();
        car.fuelUp();
        car.clean();
        car.rent();
    }

}

class BMWRentalCar extends RentalCar {

    protected Car chooseCar(){
        return new BMW();
    }

}

Abstrakcyjna fabryka

Głównym celem jest zgromadzenie w jednym interfejsie powiązanych ze sobą obiektów, które to powinny być tworzone w jednym miejscu (na przykład części do samochodu powinny być tworzone w jednej fabryce aby uzyskać spójność):

interface CarElementsFactory{
    Wheel createWheel();
    FrontBumper createFrontBumper();
    //...
}

class BMWElementsFactory implements CarElementsFactory{

    public Wheel createWheel(){
        return new BMWWheel();
    }

    public FrontBumper createFrontBumper(){
        return new BMWFrontBumper();
    }

}