Skip to content

Commit d35471d

Browse files
LeroidLeroid
Leroid
authored and
Leroid
committed
Factories usage example remake
1 parent e0fd4ef commit d35471d

File tree

1 file changed

+47
-35
lines changed

1 file changed

+47
-35
lines changed

service_container/factories.rst

+47-35
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,7 @@ Services (subclasses) definition::
315315
316316
interface DeliveryInterface
317317
{
318+
public function getPrice(): float;
318319
}
319320

320321
// src/Deliveries/DHL.php
@@ -324,9 +325,10 @@ Services (subclasses) definition::
324325

325326
class DHL implements DeliveryInterface
326327
{
327-
public $costLabel;
328+
public string $priceLabel;
328329
329-
public function cost() {
330+
public function getPrice(): float
331+
{
330332
return 100;
331333
}
332334
}
@@ -338,35 +340,48 @@ Services (subclasses) definition::
338340

339341
class UPS implements DeliveryInterface
340342
{
341-
public $costLabel;
343+
public string $priceLabel;
342344
343-
public function cost() {
345+
public function getPrice(): float
346+
{
344347
return 200;
345348
}
346349
}
347350

348-
Factory definition::
351+
Static factory definition::
349352

350353
// src/Factories/DeliveryFactory.php
351354
namespace App\Factories;
352-
355+
353356
use App\Deliveries\DeliveryInterface;
354-
355-
abstract class DeliveryFactory
357+
use App\Deliveries\DHL;
358+
use App\Deliveries\UPS;
359+
360+
class DeliveryFactory
356361
{
357362
public static function create(string $deliveryMethod): DeliveryInterface
358363
{
359-
$delivery = new $deliveryMethod;
360-
$delivery->costLabel = 'Delivery cost is: ';
361-
364+
switch ($deliveryMethod) {
365+
case 'dhl':
366+
$delivery = new DHL;
367+
break;
368+
case 'ups':
369+
$delivery = new UPS;
370+
break;
371+
default:
372+
throw new \InvalidArgumentException('Unknown delivery method given');
373+
}
374+
375+
// Since DeliveryFactory is a factory of DHL and UPS instances,
376+
// priceLabel property with exactly this value ('Delivery price is: ')
377+
// is accessible for them - you will see it soon.
378+
$delivery->priceLabel = 'Delivery price is: ';
379+
362380
return $delivery;
363381
}
364-
365-
abstract public function price();
382+
366383
}
367384
368-
As you can see, ``DeliveryFactory`` doesn't specify the exact class of the object that will be created.
369-
370385
Next, use settings similar to those in the sections above. These settings allow you to define a factory method for subclasses without explicitly extending the abstract class (i.e., without ``class DHL extends DeliveryFactory``)!
371386

372387
.. configuration-block::
@@ -378,11 +393,11 @@ Next, use settings similar to those in the sections above. These settings allow
378393
# ...
379394
380395
App\Deliveries\DHL:
381-
factory: ['@App\Factories\DeliveryFactory', create]
382-
arguments: ['App\Deliveries\DHL']
396+
factory: ['App\Factories\DeliveryFactory', 'create']
397+
arguments: ['dhl']
383398
App\Deliveries\UPS:
384-
factory: ['@App\Factories\DeliveryFactory', create]
385-
arguments: ['App\Deliveries\UPS']
399+
factory: ['App\Factories\DeliveryFactory', 'create']
400+
arguments: ['ups']
386401
387402
388403
.. code-block:: xml
@@ -398,12 +413,12 @@ Next, use settings similar to those in the sections above. These settings allow
398413
<!-- ... -->
399414
400415
<service id="App\Deliveries\DHL">
401-
<factory service="App\Factories\DeliveryFactory" method="create"/>
402-
<argument>App\Deliveries\DHL</argument>
416+
<factory class="App\Factories\DeliveryFactory" method="create"/>
417+
<argument>dhl</argument>
403418
</service>
404419
<service id="App\Deliveries\UPS">
405-
<factory service="App\Factories\DeliveryFactory" method="create"/>
406-
<argument>App\Deliveries\UPS</argument>
420+
<factory class="App\Factories\DeliveryFactory" method="create"/>
421+
<argument>ups</argument>
407422
</service>
408423
</services>
409424
</container>
@@ -413,35 +428,32 @@ Next, use settings similar to those in the sections above. These settings allow
413428
// config/services.php
414429
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
415430
431+
use App\Factories\DeliveryFactory;
416432
use App\Deliveries\DHL;
417433
use App\Deliveries\UPS;
418-
use App\Factories\DeliveryFactory;
419434
420435
return function(ContainerConfigurator $configurator) {
421436
$services = $configurator->services();
422437
423438
$services->set(DHL::class)
424-
->factory([ref(DeliveryFactory::class), 'create'])
425-
->args(['App\Deliveries\DHL'])
439+
->factory([DeliveryFactory::class, 'create'])
440+
->args(['dhl'])
426441
;
427442
$services->set(UPS::class)
428-
->factory([ref(DeliveryFactory::class), 'create'])
429-
->args(['App\Deliveries\UPS'])
443+
->factory([DeliveryFactory::class, 'create'])
444+
->args(['ups'])
430445
;
431446
};
432447
433-
Now we can use our services as usual (via dependency injection). The only difference is that subclasses instances of services are created in the factory. Let's get those services in controller::
448+
Now we can use our delivery services as usual (via dependency injection). The only difference is that subclasses instances of services are created in the factory. Let's get those services in controller::
434449

435-
/**
436-
* @Route("/get-deliveries-cost", methods={"GET"})
437-
*/
438450
public function getDeliveriesCost(DHL $dhl, UPS $ups)
439451
{
440452
// ...
441453
442-
// $dhl->costLabel and $ups->costLabel are fulfilled in factory method.
443-
$dhlCost = $dhl->costLabel . $dhl->cost();
444-
$upsCost = $ups->costLabel . $ups->cost();
454+
// $dpd->priceLabel and $ups->priceLabel are fulfilled in factory method.
455+
$dhlPriceMessage = $dhl->priceLabel . $dhl->getPrice();
456+
$upsPriceMessage = $ups->priceLabel . $ups->getPrice();
445457
446458
// ...
447459
}

0 commit comments

Comments
 (0)