Wzorce projektowe ułatwiają nam programistom życie, w końcu pomagają rozwiązywać powtarzalne problemy. Nie musimy już sami wymyślać rozwiązania, bo już ktoś kiedyś wpadł na pewien pomysł i udostępnił go w postaci wzorca. W tym cyklu artykułów opiszę popularne 3 wzorce. Pierwszym będzie wzorzec Fabryka.
Wzorzec Fabryka
Jeśli nie chcesz dokładnie ujawniać klientowi sposobu w jaki tworzone są obiekty wzorzec Fabryka, jest tym czego potrzebujesz. Wzorzec Fabryka oferuje jeden z najlepszych sposobów na tworzenie nowych obiektów.
Wzorzec fabryka udostępnia interfejs (lub klasę abstrakcyjną), który pozwala na tworzenie obiektów, ale to klasy podrzędne decydują o tym, jakiej klasy obiekt zostanie utworzony. Klasa nadrzędna przekazuje odpowiednie dane, a to klasy podrzędne decydują, na podstawie zaprogramowanej przez nas logiki jakiej klasy obiekt utworzyć. Takie rozwiązanie usuwa niepotrzebne sprzężenie między kodem klienta, a kodem tworzącym obiekty. Klient nie jest zależny od implementacji klas podrzędnych, które tworzą obiekt; musi jedynie wiedzieć jakich typów abstrakcyjnych użyć. Metoda fabrykująca wykorzystuje mechanizm dziedziczenia.
Przykład użycia
Istnieje kilka możliwych implementacji wzorca Fabryka, tutaj przedstawię jedną z prostszych. Jako przykład posłuży nam salon samochodowy.

Krok 1: Utworzenie klasy abstrakcyjnej Car
Na początku utworzymy klasę abstrakcyjną Car (interfejs), po której dziedziczyć będą konkretne klasy rzeczywiste typów samochodów.
abstract public class Car {
String name;
public String getName() {
return name;
}
}
Krok 2: Utworzenie poszczególnych rzeczywistych klas samochodów
public class Sedan extends Car {
public Sedan() {
name = "Sedan";
}
}
public class Van extends Car{
public Van() {
name = "Van";
}
}
public class PickUp extends Car{
public PickUp() {
name = "pickUp";
}
}
Krok 3: Utworzenie klasy fabryki
public class CarFactory {
public Car createCar(String type) {
Car car = null;
if (type.equals("sedan")) {
car = new Sedan();
} else if(type.equals("pickUp")) {
car = new PickUp();
} else if(type.equals("Van")) {
car = new Van();
}
return car;
}
}
Krok 4: Utworzenie klasy dealera samochodowego
public class CarDealership {
CarFactory factory;
public CarDealership(CarFactory factory) {
this.factory = factory;
}
public Car orderCar(String type) {
Car car;
car = factory.createCar(type);
return car;
}
}
Krok 5: Utworzenie klasy testowej (klienta)
public class CreateCarTest {
public static void main(String[] args) {
CarFactory factory = new CarFactory();
CarDealership dealership = new CarDealership(factory);
Car car = dealership.orderCar("sedan");
System.out.println("Here is your ordered car: " + car.getName() +"\n");
car = dealership.orderCar("Van");
System.out.println("Here is your ordered car: " + car.getName() +"\n");
car = dealership.orderCar("pickUp");
System.out.println("Here is your ordered car: " + car.getName() +"\n");
}
}
Po uruchomieniu naszej fabryki powinniśmy otrzymać nasze zamówione samochody:

Jak więc działa Fabryka?
W kliencie tworzymy 2 obiekty: fabrykę (factory) oraz dilera samochodów (dealership), do której konstruktora wysyłamy utworzoną fabrykę i konstruktor tworzy w obiekcie dealership odwołanie do tej fabryki.
Następnie metodą orderCar() wywoływaną na obiekcie dealership „zamawiamy” samochody: sedan, van i pickup i przypisujemy je do obiektu klasy Car.
Metoda orderCar() w klasie CarDealership, do której w argumencie podajemy typ naszego samochodu wywołuje na obiekcie factory metodę createCar(), gdzie w argumencie również podawany jest typ samochodu.
Następnie nasza fabryka w metodzie createCar() decyduje na podstawie podanego typu samochodu jakiej klasy obiekt typu Car utworzyć (czy ma być to obiekt klasy Sedan, Van lub PickUp). Dzieje się to za pomocą instrukcji warunkowej If. To jest właśnie kluczowe funkcja naszego wzorca, gdzie delegujemy utworzenie obiektów do klas rzeczywistych.