Giter VIP home page Giter VIP logo

Comments (3)

webdevilopers avatar webdevilopers commented on July 17, 2024 2

Please do not @ people who have not explicitly consented to it. Thanks.

Sorry @udidahan for this faux-pas. Same for twitter. Just wanted to ask you for your feedback on this regarding your suggestion in your mentioned article.

from php-ddd.

udidahan avatar udidahan commented on July 17, 2024

Please do not @ people who have not explicitly consented to it. Thanks.

from php-ddd.

JulianMay avatar JulianMay commented on July 17, 2024

(Copy/Pasted from https://gist.github.com/webdevilopers/687c8b34d68e97a8f93df5db09242406 )

Disclaimer: I'm no expert or authority, I might be "wrong" on every line below ;)

Thoughts regarding terminology/structure:

  • "Policy" for me is something that is a reaction to an event ("Whenever X, then Y"), which might hold it's own aggregated state - I usually call specifications like this "Constraints", e.g.: "OverlappingEmploymentContractsConstraint" or simply name them according to the rule: "EmploymentsMayNotOverlap"
  • It feels weird for me that a ReadModel is instantiating an aggregate - I would not expect a ReadModel to be more than data and queries.
    Besides the instantiation of an EmploymentContract, the PersonReadModel seems to be 1) a factory for dependencies of the OverlappingEmploymentContractPolicy and 2) control-flow, checking the constraint

... Personally, I would probably do something like:

    public function __invoke(SignEmploymentContract $command): void
    {
        $enteredContracts = $this->contractsDetailsRepository->ofPersonId($person->personId());     

        if(!OverlappingEmploymentContractPolicy::isSatisfiedBy($command->... , $enteredContracts)) 
        {
            throw new EmploymentPeriodOverlapsException();
        }
      
        $person = $this->personDetailsRepository->ofPersonId($command->personId()->toString());
        
        $contract = EmploymentContract::sign($command->... , $person->... )
        
        $this->contractCollection->save($contract);

EDIT: you could probably clean it up by injecting the "policy" as a dependency, which encapsulates the 'contractsDetailsRepository' (as long as you don't need it to be 'pure'):

    public function __invoke(SignEmploymentContract $command): void
    {
        $constraintSatisfied =   $this->newEmploymentContractMayNotOverlap->isSatisfiedBy($command);
        if(!$constraintSatisfied) 
        {
            throw new EmploymentPeriodOverlapsException();
        }
      
        $person = $this->personDetailsRepository->ofPersonId($command->personId()->toString());
        
        $contract = EmploymentContract::sign($command->... , $person->... )
        
        $this->contractCollection->save($contract);

Thoughts regarding consistency/invariants:
Be aware that all code in this gist so far does not guarantee that 2 contracts for the same person do not overlap periods.
It "only" guarantees it as long as that person does not sign up for 2 different contracts at the same time - It's probably only a window of a few milliseconds, and more a theoretical edge case than anything worth coding around.
Besides "how probably is it", I find another heuristic for whether the code should care, is the severity of the consequence of such invariant failing.
If there is a way to identify and compensate for a theoretical edge case without much blowback, and the race-condition would probably never happen, I would suggest not complicating things with saga/process-manager/policies.

Just be aware that you have a guard, not an absolute guarantee ;)

from php-ddd.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.