webdevilopers/php-ddd

How to pass (which) data from Handler to Domain Service

Opened this issue · 0 comments

My CalculateDormerHandler needs to pass data from a CalculateDormerCommand to a DormerCalculator Domain Service.

Currently the Handler is passing the complete DTO (Command including a lot of args) and some Infrastructure concerns to the Domain Service:

class CalculateDormerHandler extends AbstractCalculateDormerHandler
{
    public function handle(CalculateDormerCommand $command)
    {
        // Pass to domain service calculator
        $dormerCalculation = $this->dormerCalculator->calculate(
            PartnerId::create($this->getTokenStorage()->getToken()->getUser()->getId()),
            $command
        );

        $this->dormerCalculationRepository->save($dormerCalculation);
    }
}

ATM the Domain Service then transforms some of the args from the DTO into Domain Models:

class DormerCalculator
{
    public function calculate(
        PartnerId $partnerId,
        $command
    ) {
        $this->partner = $this->partnerRepository->ofId($partnerId);
        $this->gutter = $this->calculateGutter($command->gutter());
    }

    private function calculateGutter($gutterData) : Gutter
    {
        if (true !== $gutterData['add']) {
            return;
        }
        return new Gutter(
            GutterMaterial::create($gutterData['materialId']),
            GutterColor::create($gutterData['colorId'])
        );
    }
}

I'm thinking about refactoring the Domain Service and move the creation of the required Domain Models to the Handler.

class CalculateDormerHandler extends AbstractCalculateDormerHandler
{
    public function handle(CalculateDormerCommand $command)
    {
        if (true !== $command->gutter()['add']) {
            $gutter = new Gutter(
                GutterMaterial::create($gutterData['materialId']),
                GutterColor::create($gutterData['colorId'])
            );
        }

        // Pass to domain service calculator
        $dormerCalculation = $this->dormerCalculator->calculate(
            PartnerId::create($this->getTokenStorage()->getToken()->getUser()->getId()),
            $gutter
            // ...
        );
    }
}

class DormerCalculator
{
    public function calculate(
        PartnerId $partnerId,
        Gutter $gutter = null,
        // ...
    ) {
        $this->partner = $this->partnerRepository->ofId($partnerId);
        $this->gutter = $this->gutter;
    }
}

This way the Domain receives Models that it understands. In addtion every other Application or even Domain Service could use the DormerCalculator Domain Service.

As I mentioned my command holds a lot(!) of arguments. Should the Handler still carry out the task as refactored?