Cześć wszystkim!
Dzisiaj chciałbym podzielić się z Wami jednym z podstawowych wzorców projektowych, który może znacząco ułatwić nasze życie jako programistów – wzorcem fabryka.
Dowiemy się, czym on jest, jak działa w praktyce oraz jakie są różnice między fabryką a fabryką abstrakcyjną.
Zaczynajmy! 🚀
Czym jest Wzorzec Fabryka?
Wzorzec fabryka to sposób na tworzenie obiektów, który pozwala na oddzielenie procesu tworzenia od użycia obiektów.
Dzięki temu możemy łatwo zmieniać klasę obiektów, które chcemy tworzyć, bez konieczności zmiany kodu klienckiego. W skrócie, fabryka umożliwia tworzenie obiektów w sposób bardziej elastyczny i zorganizowany.
Przykład z życia w PHP
Wyobraźmy sobie, że budujemy aplikację do zarządzania różnymi rodzajami pojazdów. Mamy klasy Samochod i Motocykl, a chcemy mieć możliwość łatwego tworzenia obiektów tych klas. Zamiast tworzyć obiekty bezpośrednio w kodzie, możemy stworzyć klasę fabryki, która będzie odpowiedzialna za ich tworzenie.
class Car { public function drive(): string { return "Driving a car!"; } } class Motorcycle { public function drive(): string { return "Riding a motorcycle!"; } } class VehicleFactory { // Mapa typów pojazdów do ich klas private static $vehicleTypes = [ 'car' => Car::class, 'motorcycle' => Motorcycle::class, // Można łatwo dodać nowe typy pojazdów // 'bicycle' => Bicycle::class, ]; public static function createVehicle($type) { if (array_key_exists($type, self::$vehicleTypes)) { $class = self::$vehicleTypes[$type]; return new $class(); } return null; // lub rzucić wyjątek } } $vehicle = VehicleFactory::createVehicle('car'); // bądź można też bezpośrednio wrzucać klase i dostosować konstruktor VehicleFactory echo $vehicle->drive(); // Output: Driving a car!
W powyższym przykładzie klasa VehicleFactory ma metodę createVehicle, która na podstawie podanego typu zwraca odpowiedni obiekt. Dzięki temu możemy łatwo dodawać nowe typy pojazdów w przyszłości, nie zmieniając kodu klienckiego.
Czym jest Fabryka Abstrakcyjna?
Fabryka abstrakcyjna to bardziej zaawansowany wzorzec, który pozwala na tworzenie rodzin powiązanych obiektów bez konieczności ich konkretnej implementacji. Umożliwia to wytwarzanie różnych klas obiektów, które mają ze sobą coś wspólnego.
Przykłąd użycia fabryki abstrakcyjnej w PHP
Zaczniemy od zdefiniowania interfejsów dla pojazdów i silników.
// Engine interface interface Engine { public function start(): string; } // Vehicle interface interface Vehicle { public function drive(): string; }
Następnie stworzymy konkretne klasy dla różnych typów silników i pojazdów.
// Klasy silników class PetrolEngine implements Engine { public function start(): string { return "Petrol engine started."; } } class DieselEngine implements Engine { public function start(): string { return "Diesel engine started."; } } // Klasy pojazdów class Car implements Vehicle { private Engine $engine; public function __construct(Engine $engine) { $this->engine = $engine; } public function drive() { return $this->engine->start() . " Car is driving!"; } } class Motorcycle implements Vehicle { private Engine $engine; public function __construct(Engine $engine) { $this->engine = $engine; } public function drive() { return $this->engine->start() . " Motorcycle is driving!"; } }
Teraz zdefiniujemy fabryki, które będą tworzyć różne rodzaje pojazdów z odpowiednimi silnikami.
// Interfejs fabryki pojazdów interface VehicleFactory { public function createCar(): Vehicle; public function createMotorcycle(): Vehicle; } // Konkretny producent pojazdów benzynowych class PetrolVehicleFactory implements VehicleFactory { public function createCar(): Vehicle { return new Car(new PetrolEngine()); } public function createMotorcycle(): Vehicle { return new Motorcycle(new PetrolEngine()); } } // Konkretny producent pojazdów diesel class DieselVehicleFactory implements VehicleFactory { public function createCar(): Vehicle { return new Car(new DieselEngine()); } public function createMotorcycle(): Vehicle { return new Motorcycle(new DieselEngine()); } }
Na koniec, możemy wykorzystać fabryki do tworzenia różnych pojazdów.
// Użycie fabryki $factory = new PetrolVehicleFactory(); $car = $factory->createCar(); echo $car->drive(); $motorcycle = $factory->createMotorcycle(); echo $motorcycle->drive(); // Użycie fabryki diesel $dieselFactory = new DieselVehicleFactory(); $dieselCar = $dieselFactory->createCar(); echo $dieselCar->drive(); $dieselMotorcycle = $dieselFactory->createMotorcycle(); echo $dieselMotorcycle->drive();
Wzorzec fabryki abstrakcyjnej pozwala na tworzenie rodzin powiązanych obiektów w bardziej zorganizowany sposób. W naszym przykładzie, różne fabryki produkują różne pojazdy z odpowiednimi silnikami. Dzięki temu możemy łatwo dodawać nowe typy pojazdów i silników bez modyfikacji istniejącego kodu.
Różnice między Fabryką a Fabryką Abstrakcyjną
- Fabryka: Służy do tworzenia pojedynczego obiektu, często na podstawie podanego parametru (jak w naszym przykładzie). Jest to prostszy wzorzec, bardziej zrozumiały dla mniej skomplikowanych przypadków.
- Fabryka Abstrakcyjna: Pozwala na tworzenie rodzin obiektów, często powiązanych ze sobą. Stosuje się ją w bardziej skomplikowanych scenariuszach, gdzie musimy tworzyć obiekty różnych klas w jednocześnie współpracujących rodzajach.
Zalety i Wady Korzystania z Wzorca Fabryka
Zalety:
- Oddzielenie logiki tworzenia obiektów: Wzorzec fabryka pozwala na lepsze zarządzanie kodem i łatwiejsze wprowadzanie zmian.
- Elastyczność: Możemy łatwo zmieniać typy obiektów bez zmiany kodu klienckiego.
- Łatwość w testowaniu: Możemy łatwo podmieniać konkretne implementacje w testach jednostkowych.
Wady:
- Złożoność: Może wprowadzić dodatkową złożoność, szczególnie w prostych aplikacjach, gdzie fabryka może być zbędna.
- Przeciążenie klas: W miarę dodawania nowych typów obiektów, klasa fabryki może stać się zbyt rozbudowana.
Podsumowanie wzorca fabryki
Wzorzec fabryka oraz fabryka abstrakcyjna są niezwykle użytecznymi narzędziami w arsenale programisty PHP. Pozwalają na tworzenie elastycznego i łatwego w zarządzaniu kodu, a także ułatwiają rozwój aplikacji. Wybór między fabryką a fabryką abstrakcyjną zależy od złożoności i potrzeb projektu. Mam nadzieję, że ten artykuł pomógł Wam lepiej zrozumieć te wzorce!
Nikt jeszcze nie komentował. Bądź pierwszy!