Skip to content

Commit bcb7557

Browse files
LeroidLeroid
Leroid
authored and
Leroid
committed
Factories usage example remake
1 parent d5f57bb commit bcb7557

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
@@ -307,6 +307,7 @@ Services (subclasses) definition::
307307
308308
interface DeliveryInterface
309309
{
310+
public function getPrice(): float;
310311
}
311312

312313
// src/Deliveries/DHL.php
@@ -316,9 +317,10 @@ Services (subclasses) definition::
316317

317318
class DHL implements DeliveryInterface
318319
{
319-
public $costLabel;
320+
public string $priceLabel;
320321
321-
public function cost() {
322+
public function getPrice(): float
323+
{
322324
return 100;
323325
}
324326
}
@@ -330,35 +332,48 @@ Services (subclasses) definition::
330332

331333
class UPS implements DeliveryInterface
332334
{
333-
public $costLabel;
335+
public string $priceLabel;
334336
335-
public function cost() {
337+
public function getPrice(): float
338+
{
336339
return 200;
337340
}
338341
}
339342

340-
Factory definition::
343+
Static factory definition::
341344

342345
// src/Factories/DeliveryFactory.php
343346
namespace App\Factories;
344-
347+
345348
use App\Deliveries\DeliveryInterface;
346-
347-
abstract class DeliveryFactory
349+
use App\Deliveries\DHL;
350+
use App\Deliveries\UPS;
351+
352+
class DeliveryFactory
348353
{
349354
public static function create(string $deliveryMethod): DeliveryInterface
350355
{
351-
$delivery = new $deliveryMethod;
352-
$delivery->costLabel = 'Delivery cost is: ';
353-
356+
switch ($deliveryMethod) {
357+
case 'dhl':
358+
$delivery = new DHL;
359+
break;
360+
case 'ups':
361+
$delivery = new UPS;
362+
break;
363+
default:
364+
throw new \InvalidArgumentException('Unknown delivery method given');
365+
}
366+
367+
// Since DeliveryFactory is a factory of DHL and UPS instances,
368+
// priceLabel property with exactly this value ('Delivery price is: ')
369+
// is accessible for them - you will see it soon.
370+
$delivery->priceLabel = 'Delivery price is: ';
371+
354372
return $delivery;
355373
}
356-
357-
abstract public function price();
374+
358375
}
359376
360-
As you can see, ``DeliveryFactory`` doesn't specify the exact class of the object that will be created.
361-
362377
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``)!
363378

364379
.. configuration-block::
@@ -370,11 +385,11 @@ Next, use settings similar to those in the sections above. These settings allow
370385
# ...
371386
372387
App\Deliveries\DHL:
373-
factory: ['@App\Factories\DeliveryFactory', create]
374-
arguments: ['App\Deliveries\DHL']
388+
factory: ['App\Factories\DeliveryFactory', 'create']
389+
arguments: ['dhl']
375390
App\Deliveries\UPS:
376-
factory: ['@App\Factories\DeliveryFactory', create]
377-
arguments: ['App\Deliveries\UPS']
391+
factory: ['App\Factories\DeliveryFactory', 'create']
392+
arguments: ['ups']
378393
379394
380395
.. code-block:: xml
@@ -390,12 +405,12 @@ Next, use settings similar to those in the sections above. These settings allow
390405
<!-- ... -->
391406
392407
<service id="App\Deliveries\DHL">
393-
<factory service="App\Factories\DeliveryFactory" method="create"/>
394-
<argument>App\Deliveries\DHL</argument>
408+
<factory class="App\Factories\DeliveryFactory" method="create"/>
409+
<argument>dhl</argument>
395410
</service>
396411
<service id="App\Deliveries\UPS">
397-
<factory service="App\Factories\DeliveryFactory" method="create"/>
398-
<argument>App\Deliveries\UPS</argument>
412+
<factory class="App\Factories\DeliveryFactory" method="create"/>
413+
<argument>ups</argument>
399414
</service>
400415
</services>
401416
</container>
@@ -405,35 +420,32 @@ Next, use settings similar to those in the sections above. These settings allow
405420
// config/services.php
406421
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
407422
423+
use App\Factories\DeliveryFactory;
408424
use App\Deliveries\DHL;
409425
use App\Deliveries\UPS;
410-
use App\Factories\DeliveryFactory;
411426
412427
return function(ContainerConfigurator $configurator) {
413428
$services = $configurator->services();
414429
415430
$services->set(DHL::class)
416-
->factory([ref(DeliveryFactory::class), 'create'])
417-
->args(['App\Deliveries\DHL'])
431+
->factory([DeliveryFactory::class, 'create'])
432+
->args(['dhl'])
418433
;
419434
$services->set(UPS::class)
420-
->factory([ref(DeliveryFactory::class), 'create'])
421-
->args(['App\Deliveries\UPS'])
435+
->factory([DeliveryFactory::class, 'create'])
436+
->args(['ups'])
422437
;
423438
};
424439
425-
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::
440+
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::
426441

427-
/**
428-
* @Route("/get-deliveries-cost", methods={"GET"})
429-
*/
430442
public function getDeliveriesCost(DHL $dhl, UPS $ups)
431443
{
432444
// ...
433445
434-
// $dhl->costLabel and $ups->costLabel are fulfilled in factory method.
435-
$dhlCost = $dhl->costLabel . $dhl->cost();
436-
$upsCost = $ups->costLabel . $ups->cost();
446+
// $dpd->priceLabel and $ups->priceLabel are fulfilled in factory method.
447+
$dhlPriceMessage = $dhl->priceLabel . $dhl->getPrice();
448+
$upsPriceMessage = $ups->priceLabel . $ups->getPrice();
437449
438450
// ...
439451
}

0 commit comments

Comments
 (0)