Skip to content

Instantly share code, notes, and snippets.

@webdevilopers
Last active February 20, 2019 11:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save webdevilopers/cb4352a591437e57785bec3f8dc3bcea to your computer and use it in GitHub Desktop.
Save webdevilopers/cb4352a591437e57785bec3f8dc3bcea to your computer and use it in GitHub Desktop.
DDD Domain Service vs Domain Factory vs. Double Dispatch
<?php
class DormerOffer
{
/**
* DormerOffer constructor.
* @param OfferId $anId
* @param OfferTitle $aTitle
* @param DormerCalculation $aDormerCalculation
* @param $chargeRates
* @param PricesCalculator $pricesCalculator
*/
public function __construct(
OfferId $anId, OfferTitle $aTitle, DormerCalculation $aDormerCalculation,
$chargeRates, PricesCalculator $pricesCalculator
)
{
$this->id = $anId;
$this->dormerCalculationId = $aDormerCalculation->calculationId();
$this->title = $aTitle;
$this->chargeRates = $chargeRates;
// Calculate prices
$prices = $pricesCalculator->calculate($aDormerCalculation, $chargeRates);
$this->setPrices($prices);
}
}
<?php
class DormerOffer
{
/**
* DormerOffer constructor.
* @param OfferId $anId
* @param OfferTitle $aTitle
* @param DormerCalculation $aDormerCalculation
* @param $chargeRates
* @param $prices
* @param PricesCalculator $pricesCalculator
*/
public function __construct(
OfferId $anId, OfferTitle $aTitle, DormerCalculation $aDormerCalculation,
$chargeRates, $prices
)
{
$this->id = $anId;
$this->dormerCalculationId = $aDormerCalculation->calculationId();
$this->title = $aTitle;
$this->chargeRates = $chargeRates;
$this->setPrices($prices);
}
}
<?php
final class OfferFactory
{
/** @var ChargeRatesFactory $chargeRatesFactory */
private $chargeRatesFactory;
/** @var PricesCalculator $pricesCalculator */
private $pricesCalculator;
/**
* OfferPriceCalculator constructor.
* @param ChargeRatesFactory $chargeRatesFactory
* @param PricesCalculator $pricesCalculator
*/
public function __construct(ChargeRatesFactory $chargeRatesFactory, PricesCalculator $pricesCalculator)
{
$this->chargeRatesFactory = $chargeRatesFactory;
$this->pricesCalculator = $pricesCalculator;
}
/**
* @param OfferId $offerId
* @param DormerCalculation $calculation
* @return DormerOffer
*/
public function withDormerCalculation(OfferId $offerId, DormerCalculation $calculation): DormerOffer
{
$chargeRates = $this->chargeRatesFactory->init($calculation);
return new DormerOffer(
$offerId,
OfferTitle::fromDormerCalculation($calculation),
$calculation, $chargeRates, $this->pricesCalculator
);
}
}
<?php
final class OfferFactory
{
/** @var ChargeRatesFactory $chargeRatesFactory */
private $chargeRatesFactory;
/** @var PricesCalculator $pricesCalculator */
private $pricesCalculator;
/**
* OfferPriceCalculator constructor.
* @param ChargeRatesFactory $chargeRatesFactory
* @param PricesCalculator $pricesCalculator
*/
public function __construct(ChargeRatesFactory $chargeRatesFactory, PricesCalculator $pricesCalculator)
{
$this->chargeRatesFactory = $chargeRatesFactory;
$this->pricesCalculator = $pricesCalculator;
}
/**
* @param OfferId $offerId
* @param DormerCalculation $calculation
* @return DormerOffer
*/
public function withDormerCalculation(OfferId $offerId, DormerCalculation $calculation): DormerOffer
{
$chargeRates = $this->chargeRatesFactory->init($calculation);
$prices = $this->pricesCalculator->calculate($calculation, $chargeRates);
return new DormerOffer(
$offerId,
OfferTitle::fromDormerCalculation($calculation),
$calculation, $chargeRates, $prices
);
}
}
@webdevilopers
Copy link
Author

The constructor reveives a domain service pricesCalculator which needs to make some complex calculations. But no calls to the external world e.g. a repository. But it requires the DormerCalculation Entity.
This entity itself is only required for the calculation and is NOT added to the aggregate root DormerOffer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment