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.
source share