<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Fluttershy</title>
    <description>The latest articles on Forem by Fluttershy (@coajaxial).</description>
    <link>https://forem.com/coajaxial</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F99648%2F1dec9be9-6ed2-4fb1-a91d-93c02cb987cf.jpg</url>
      <title>Forem: Fluttershy</title>
      <link>https://forem.com/coajaxial</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/coajaxial"/>
    <language>en</language>
    <item>
      <title>My first open-source project: The Messaging Mediator</title>
      <dc:creator>Fluttershy</dc:creator>
      <pubDate>Sat, 23 May 2020 19:22:52 +0000</pubDate>
      <link>https://forem.com/coajaxial/my-first-open-source-project-the-messaging-mediator-177m</link>
      <guid>https://forem.com/coajaxial/my-first-open-source-project-the-messaging-mediator-177m</guid>
      <description>&lt;p&gt;Hello fellow coders,&lt;/p&gt;

&lt;p&gt;I want to show you my first open-source project. It is a relatively small library for PHP that enables you to model a more beautiful domain model using DDD practices.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it does
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;The messaging mediator hooks into your message bus, giving you the ability to yield messages from your application and domain layer, including message handlers, aggregates, value objects, domain services, etc.&lt;/p&gt;

&lt;p&gt;Publish domain events, dispatch commands and issue queries and get their results without any dependency to your message bus.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Look at the repository's &lt;code&gt;README&lt;/code&gt; file to see how you can use it (section "Use Cases")&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vWogaON8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-28d89282e0daa1e2496205e2f218a44c755b0dd6536bbadf5ed5a44a7ca54716.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/coajaxial"&gt;
        coajaxial
      &lt;/a&gt; / &lt;a href="https://github.com/coajaxial/messaging-mediator"&gt;
        messaging-mediator
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Send messages directly from your domain model without any dependencies
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;
  &lt;a rel="noopener noreferrer" href="https://raw.githubusercontent.com/coajaxial/messaging-mediator/master/res/logo.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wsuxPmMH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/coajaxial/messaging-mediator/master/res/logo.png" alt="Messaging Mediator" title="Messaging Mediator"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/coajaxial/messaging-mediator/workflows/Psalm/badge.svg"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NKBa0bHy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/coajaxial/messaging-mediator/workflows/Psalm/badge.svg" alt="Psalm"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer" href="https://github.com/coajaxial/messaging-mediator/workflows/Unit%20tests/badge.svg"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VaPCBm_o--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/coajaxial/messaging-mediator/workflows/Unit%2520tests/badge.svg" alt="Unit tests"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer" href="https://github.com/coajaxial/messaging-mediator/workflows/Integration%20tests/badge.svg"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9zKcBL0l--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/coajaxial/messaging-mediator/workflows/Integration%2520tests/badge.svg" alt="Integration tests"&gt;&lt;/a&gt;
&lt;a href="https://packagist.org/packages/coajaxial/messaging-mediator" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/d68875f10dcbd2ab1e6d1cbf46e2e4d06eab655f/68747470733a2f2f706f7365722e707567782e6f72672f636f616a617869616c2f6d6573736167696e672d6d65646961746f722f762f737461626c65" alt="Latest Stable Version"&gt;&lt;/a&gt;
&lt;a href="https://packagist.org/packages/coajaxial/messaging-mediator" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/919f9f5b5247edb8c78c050272d4de558c85f68f/68747470733a2f2f706f7365722e707567782e6f72672f636f616a617869616c2f6d6573736167696e672d6d65646961746f722f646f776e6c6f616473" alt="Total Downloads"&gt;&lt;/a&gt;
&lt;a href="https://packagist.org/packages/coajaxial/messaging-mediator" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/e9253fce7aa1b796e0dcba5ea279e09fc684e83f/68747470733a2f2f706f7365722e707567782e6f72672f636f616a617869616c2f6d6573736167696e672d6d65646961746f722f6c6963656e7365" alt="License"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The messaging mediator hooks into your message bus, giving you the ability
to &lt;code&gt;yield&lt;/code&gt; messages from your application and domain layer, including message
handlers, aggregates, value objects, domain services, etc.&lt;/p&gt;
&lt;p&gt;Publish domain events, dispatch commands and issue queries and get their results
without any dependency to your message bus.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://raw.githubusercontent.com/coajaxial/messaging-mediator/master/docs/#installation"&gt;Installation&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/coajaxial/messaging-mediator/master/docs/#symfony-messenger-component-manually"&gt;Symfony messenger component (manually)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://raw.githubusercontent.com/coajaxial/messaging-mediator/master/docs/#use-cases"&gt;Use cases&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/coajaxial/messaging-mediator/master/docs/#publish-domain-events"&gt;Publish domain events&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/coajaxial/messaging-mediator/master/docs/#execute-commands"&gt;Execute commands&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/coajaxial/messaging-mediator/master/docs/#issue-queries-to-enforce-soft-business-rules"&gt;Issue queries to enforce &lt;em&gt;soft&lt;/em&gt; business rules&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/coajaxial/messaging-mediator/master/docs/#motivation"&gt;Motivation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/coajaxial/messaging-mediator/master/docs/#what-this-library-does"&gt;What this library does&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://raw.githubusercontent.com/coajaxial/messaging-mediator/master/docs/#contribute"&gt;Contribute&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/coajaxial/messaging-mediator/master/docs/#build-docker-image"&gt;Build docker image&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/coajaxial/messaging-mediator/master/docs/#load-shell-aliases"&gt;Load shell aliases&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;
Installation&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;This library has no stable release! It currently only provides
a middleware for &lt;a href="https://symfony.com/doc/current/components/messenger.html" rel="nofollow"&gt;Symfony's messenger component&lt;/a&gt;
and testing aids for &lt;a href="https://phpunit.de/" rel="nofollow"&gt;PHPUnit&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight highlight-source-shell"&gt;&lt;pre&gt;composer require coajaxial/messaging-mediator:@dev&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Next, you need to configure your message bus to use the mediator.&lt;/p&gt;
&lt;h2&gt;
Symfony messenger component (manually)&lt;/h2&gt;
&lt;div class="highlight highlight-text-html-php"&gt;
&lt;pre&gt;&lt;span class="pl-ent"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="pl-k"&gt;use&lt;/span&gt; &lt;span class="pl-v"&gt;Coajaxial&lt;/span&gt;\&lt;span class="pl-v"&gt;MessagingMediator&lt;/span&gt;\&lt;span class="pl-v"&gt;Adapter&lt;/span&gt;\&lt;span class="pl-v"&gt;Messenger&lt;/span&gt;\&lt;span class="pl-v"&gt;MessageBusAdapter&lt;/span&gt;
&lt;span class="pl-k"&gt;use&lt;/span&gt; &lt;span class="pl-v"&gt;Coajaxial&lt;/span&gt;\&lt;span class="pl-v"&gt;MessagingMediator&lt;/span&gt;\&lt;span class="pl-v"&gt;Adapter&lt;/span&gt;\&lt;span class="pl-v"&gt;Messenger&lt;/span&gt;\&lt;span class="pl-v"&gt;MessagingMediatorMiddleware&lt;/span&gt;;
&lt;span class="pl-k"&gt;use&lt;/span&gt; &lt;span class="pl-v"&gt;Coajaxial&lt;/span&gt;\&lt;span class="pl-v"&gt;MessagingMediator&lt;/span&gt;&lt;/pre&gt;…&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/coajaxial/messaging-mediator"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;If you have any questions about my project, please feel free to ask them here!&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>php</category>
      <category>ddd</category>
    </item>
    <item>
      <title>Domain-Driven Design - The Factory in PHP</title>
      <dc:creator>Fluttershy</dc:creator>
      <pubDate>Sun, 17 Feb 2019 20:37:16 +0000</pubDate>
      <link>https://forem.com/coajaxial/domain-driven-design---the-factory-in-php-4gea</link>
      <guid>https://forem.com/coajaxial/domain-driven-design---the-factory-in-php-4gea</guid>
      <description>&lt;p&gt;EDIT: Added usage example in the modified TimeSpanFactory.&lt;/p&gt;

&lt;p&gt;In Domain-Driven design we want our domain model to be bullet proof. Sometimes it is necessary to ensure some business rules while bringing a new object into life. If this construction is too complicated or simply cannot be ensured by the object itself, than you should move the construction of this object in a dedicated class: A factory.&lt;/p&gt;

&lt;p&gt;Let's make a quick example. Let's say we have a TimeSpan value object. Our initial implementation of a TimeSpan may look like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;

&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TimeSpan&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cd"&gt;/** @var \DateTimeImmutable **/&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nv"&gt;$from&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="cd"&gt;/** @var \DateTimeImmutable **/&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nv"&gt;$until&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;\DateTimeImmutable&lt;/span&gt; &lt;span class="nv"&gt;$from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;\DateTimeImmutable&lt;/span&gt; &lt;span class="nv"&gt;$until&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$from&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nv"&gt;$until&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;\InvalidArgumentException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Invalid time span.'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$from&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;until&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$until&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Some other useful stuff goes in here...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Let's say we don't want the TimeSpan to be unlimited, there is a maximum that can be specified by some user through a Configuration that looks like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;

&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TimeSpanConfiguration&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cd"&gt;/** @var \DateInterval **/&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nv"&gt;$maxTimeSpan&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;\DateInterval&lt;/span&gt; &lt;span class="nv"&gt;$maxTimeSpan&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;maxTimeSpan&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$maxTimeSpan&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;So now we have a business rule that states: There can be no TimeSpan longer than the configured maximum. How do we enforce that? We can construct TimeSpan instances as we like, nothing will ever enforce that configuration. Well there are - as always - multiple solutions to this problem. The one that I want to show you is the Factory:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;

&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TimeSpanFactory&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cd"&gt;/** @var TimeSpanConfiguration **/&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nv"&gt;$maxTimeSpan&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;TimeSpanConfiguration&lt;/span&gt; &lt;span class="nv"&gt;$timeSpanConfiguration&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// For the sake of simplicity we just give the factory the configuration directly.&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;timeSpanConfiguration&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$timeSpanConfiguration&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;createTimeSpan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;\DateTimeImmutable&lt;/span&gt; &lt;span class="nv"&gt;$from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;\DateTimeImmutable&lt;/span&gt; &lt;span class="nv"&gt;$until&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;TimeSpan&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// We just ask the configuration if the given from-until time span is valid.&lt;/span&gt;
        &lt;span class="c1"&gt;// That way we don't need any getters on the configuration. Neat.&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;timeSpanConfiguration&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;isValidTimeSpanFromUntil&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$until&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;\DomainException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'This time span is too long!'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TimeSpan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$until&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now, when constructing a new TimeSpan, we just use the TimeSpanFactory instead of the constructor of TimeSpan directly. This way we always get a valid TimeSpan that is not longer than the configured maximum.&lt;/p&gt;

&lt;p&gt;You may ask now: Well, I could still construct an invalid TimeSpan when using the constructor directly. And YES, you are right! This may be a problem depending on your team. If your team is small enough, you could just agree on always using the TimeSpanFactory instead of the constructor directly. But there is a solution that enforces you to use the Factory: Reflection. This may introduce some side effects you don't want, but I will show you anyway ;)&lt;/p&gt;

&lt;p&gt;First, make the constructor of TimeSpan &lt;code&gt;private&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;

&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TimeSpan&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cd"&gt;/** @var \DateTimeImmutable **/&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nv"&gt;$from&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="cd"&gt;/** @var \DateTimeImmutable **/&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nv"&gt;$until&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;\DateTimeImmutable&lt;/span&gt; &lt;span class="nv"&gt;$from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;\DateTimeImmutable&lt;/span&gt; &lt;span class="nv"&gt;$until&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$from&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nv"&gt;$until&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;\InvalidArgumentException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Invalid time span.'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$from&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;until&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$until&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Some other useful stuff goes in here...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now, there is no way to construct a TimeSpan with a simple &lt;code&gt;new&lt;/code&gt;. PHP will throw a fatal error when you try to do that. Well but if you can't construct it anymore, how can our TimeSpanFactory construct it then? Reflection to the rescue! Let's look at our new implementation of TimeSpanFactory:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;

&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TimeSpanFactory&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cd"&gt;/** @var TimeSpanConfiguration **/&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nv"&gt;$maxTimeSpan&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;TimeSpanConfiguration&lt;/span&gt; &lt;span class="nv"&gt;$timeSpanConfiguration&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// For the sake of simplicity we just give the factory the configuration directly.&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;timeSpanConfiguration&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$timeSpanConfiguration&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;createTimeSpan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;\DateTimeImmutable&lt;/span&gt; &lt;span class="nv"&gt;$from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;\DateTimeImmutable&lt;/span&gt; &lt;span class="nv"&gt;$until&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;TimeSpan&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// We just ask the configuration if the given from-until time span is valid.&lt;/span&gt;
        &lt;span class="c1"&gt;// That way we don't need any getters on the configuration. Neat.&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;timeSpanConfiguration&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;isValidTimeSpanFromUntil&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$until&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;\DomainException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'This time span is too long!'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;constructTimeSpan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$until&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;constructTimeSpan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;\DateTimeImmutable&lt;/span&gt; &lt;span class="nv"&gt;$from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;\DateTimeImmutable&lt;/span&gt; &lt;span class="nv"&gt;$until&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;TimeSpan&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$class&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ReflectionClass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;TimeSpan&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nv"&gt;$constructor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$class&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getConstructor&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nv"&gt;$constructor&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;setAccessible&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nv"&gt;$timeSpan&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$class&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;newInstanceWithoutConstructor&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nv"&gt;$constructor&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$timeSpan&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$until&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$timeSpan&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Usage:&lt;/span&gt;
&lt;span class="nv"&gt;$factory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TimeSpanFactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TimeSpanConfiguration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;\DateInterval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'PT2D'&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;

&lt;span class="nv"&gt;$timeSpan&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$factory&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;constructTimeSpan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;\DateTimeImmutable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'2019-02-17 17:00:00'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;\DateTimeImmutable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'2019-02-17 18:00:00'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="c1"&gt;// Fails due too to long time span&lt;/span&gt;
&lt;span class="nv"&gt;$timeSpan&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$factory&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;constructTimeSpan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;\DateTimeImmutable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'2019-02-17 17:00:00'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;\DateTimeImmutable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'2019-02-17 23:00:00'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="c1"&gt;// Also failes, but due to private constructor ;)&lt;/span&gt;
&lt;span class="nv"&gt;$timeSpan&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TimeSpan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;\DateTimeImmutable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'2019-02-17 17:00:00'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;\DateTimeImmutable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'2019-02-17 23:00:00'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Wa...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe9rru2rtg79lz2jne8is.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe9rru2rtg79lz2jne8is.jpg" alt="Wait, that's illegal!"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I agree, but I rather have a bullet proof domain model than the chance that someone constructs an invalid TimeSpan that breaks the business rule. This may be a junior developer that doesn't know that you should use the TimeSpanFactory, or even a senior that just has forgotten about the Factory.&lt;/p&gt;

&lt;p&gt;But - as I said - that depends on your team.&lt;/p&gt;

&lt;p&gt;Happy DDD'ing!&lt;/p&gt;

&lt;p&gt;PS: I wrote this post in less than 10 minutes, all samples are written from scratch within the markdown editor of dev.to, so please: If you find any bug, typo etc., let me know :)&lt;/p&gt;

</description>
      <category>php</category>
      <category>ddd</category>
    </item>
  </channel>
</rss>
