PHP Factory design pattern method explanation

I want to know if this tutorial correctly implements a factory design pattern in PHP. Below is the source code.

<?php class Automobile { private $vehicle_make; private $vehicle_model; public function __construct($make, $model) { $this->vehicle_make = $make; $this->vehicle_model = $model; } public function get_make_and_model() { return $this->vehicle_make . ' ' . $this->vehicle_model; } } class AutomobileFactory { public static function create($make, $model) { return new Automobile($make, $model); } } // have the factory create the Automobile object $veyron = AutomobileFactory::create('Bugatti', 'Veyron'); print_r($veyron->get_make_and_model()); // outputs "Bugatti Veyron" 

According to Gang of Four's Design Patterns book, factory template applicability

  • a class cannot foresee a class of objects that it must create.
  • a class wants its subclasses to indicate the objects it creates.
  • the class delegates responsibility to one of several auxiliary subclasses, and you want to localize the knowledge of which auxiliary subclass is a delegate

The first point, this example actually knows which class of objects to create, that is, Automobile , doesn't it?

Second point, no subclass. Automobile class does not inherit from AutomobileFactory . I thought that AutomobileFactory should have at least one function implemented by Automobile, which is engaged in the creation of objects.

Can someone clarify this? I just started to learn design patterns, and every time I come across textbooks that are different from others, it really bothers me.

+4
source share
4 answers

I pretty much agree with what Wikipedia says

  • Creating an object eliminates its reuse without significant code duplication.
  • Creating an object requires access to information or resources that should not be contained in the layout class .
  • Management of the created lifecycle objects must be centralized to ensure consistent behavior in the application.

The main reason I create factories is the one I highlighted.

For example, imagine a real factory world with many plants throughout the country. This factory creates doors . Doors require a handle . For logistics reasons, each of the factory factories has its own pen suppliers, another completely different factory.

The software for the production manager of this factory will choose based on some criteria that the factory will produce many doors, but it does not need to know where the handles will come from. The selected plant will request from its supplier a handle for the door being manufactured.

However, it doesn’t matter for the client which factory made the door, he only cares about his door.

Put this on the code:

 class Knob { // something... } interface KnobSupplier { public function makeKnob(); } class SaoPauloKnobSupplier { public function makeKnob() { return new Knob('Knob made in São Paulo'); } } class NewYorkKnobSupplier { public function makeKnob() { return new Knob('Knob made in New York'); } } class Door { public function __construct(Knob $knob) { // something... } } interface DoorFactory { public function makeDoor(); } class SaoPauloDoorFactory { private $knobSupplier; public function __construct() { $this->knobSupplier = new SaoPauloKnobSupplier(); } public function makeDoor() { return new Door($this->knobSupplier->makeKnob(), "Door made in São Paulo"); } } class NewYorkDoorFactory { private $knobSupplier; public function __construct() { $this->knobSupplier = new NewYorkKnobSupplier(); } public function makeDoor() { return new Door($this->knobSupplier->makeKnob(), "Door made in New York"); } } class ProductionManager { private $plants = array(); // methods for adding plants, etc... public function getDoor() { // Somehow decides which plant will create the door. return $plant->makeDoor(); } } class Client { public function getMyDoor(ProductionManager $manager) { return $manager->getDoor(); } } 

With this code:

 $manager = new ProductManager(); $manager->addPlant(new SaoPauloDoorFactory()); $manager->addPlant(new NewYorkDoorFactory()); $client = new Client(); var_dump($client->getMyDoor($manager)); 

ProductManager knows nothing about buttons; Client knows nothing about a factory that has more than one plant.

+3
source

I don't like the tutorial. As you can see on the WikiPedia factories page ( https://en.wikipedia.org/wiki/Factory_pattern ) - this is usually done differently. The WikiPedia example matches the rules you specify. Check out the PHP section there.

+1
source

I’ll get along with you, I really don’t see this example as a traditional factory method template.

I would write your example like this (psuedo code)

 <?php abstract class CarAbstract { protected $_vehicleMake; protected $_vehicleModel; public function __construct($model) { $this->_vehicleModel = $model; } public function getMakeAndModel() { return $this->_vehicleMake . ' ' . $this->_vehicleModel; } } class Bugatti extends CarAbstract { public function __construct($model) { parent::__construct($model); $this->_vehicleMake = get_class($this); } } class AutomobileFactory { public static function getInstance($make, $model) { if (is_file('Model/Car/' . $make . '.php')){ require_once 'Model/Car/' . $make . '.php'; $car = new $make($model); }else{ throw new Exception('Car not found'); } } } $veyron = AutomobileFactory::getInstance('Bugatti', 'Veyron'); print_r($veyron->getMakeAndModel()); // outputs "Bugatti Veyron" 
+1
source

In fact, there is one Factory design pattern corresponding to the original group of four directories. Abstract Factory is completely different and based on various structural assumptions. Simple Factory is not a design pattern, but what Freemans call the "programming idiom." The Factory method includes the abstract Creator and Product, and Customers usually make their requests through the Creator. Concrete plants are located in ConcreteCreator (s), and concrete products are child classes of the Product class and are created by specific creators. For a complete and simple PHP example, see http://www.php5dp.com/a-simple-php-design-pattern-the-factory-method/ .

+1
source

Source: https://habr.com/ru/post/1480499/


All Articles