<?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>DEV Community: Carlos Gándara</title>
    <description>The latest articles on DEV Community by Carlos Gándara (@xoubaman).</description>
    <link>https://dev.to/xoubaman</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%2F34904%2Fa12e4744-e2fc-41ff-aa31-9867ca97281a.jpg</url>
      <title>DEV Community: Carlos Gándara</title>
      <link>https://dev.to/xoubaman</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/xoubaman"/>
    <language>en</language>
    <item>
      <title>Taking advantage of CQRS in legacy applications</title>
      <dc:creator>Carlos Gándara</dc:creator>
      <pubDate>Thu, 11 Sep 2025 08:31:45 +0000</pubDate>
      <link>https://dev.to/xoubaman/taking-advantage-of-cqrs-in-legacy-applications-4k76</link>
      <guid>https://dev.to/xoubaman/taking-advantage-of-cqrs-in-legacy-applications-4k76</guid>
      <description>&lt;p&gt;When we think about Command Query Responsibility Segregation (CQRS), chances are our mental model is the one for an application built around dispatching events in a write model, process them to update a read model, event stores, message buses, projections,...&lt;/p&gt;

&lt;p&gt;In this post we will explore how we can benefit from CQRS without all that tooling, which may seem impossible to introduce in legacy systems. To do so, we will explore Pattern CQRS as a low level approach to differentiate command and query operations.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I will refer to operations or use cases that change state as command or write. After one of these, the system is different as it was before. Example: activate a new user.&lt;/p&gt;

&lt;p&gt;For operations or use cases that read data I will use query or read. No matter how many times you run them, the system stays unchanged as the operation has no side effects. Example: listing all users. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Architectural CQRS vs Pattern CQRS
&lt;/h1&gt;

&lt;p&gt;CQRS in its essence is about separating the code responsible of changing state from the code responsible of reading data. Which is literally what the pattern name means.&lt;/p&gt;

&lt;p&gt;This separation may influence the whole application architecture or apply at a more granular way. Both options with their ups and downs.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note &lt;em&gt;Architectural&lt;/em&gt; and &lt;em&gt;Pattern CQRS&lt;/em&gt; are just names I made up for this post. This is not standardized terminology.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Architectural CQRS implies the architecture is built around it and maximizes the pattern benefits. In exchange, it requires specific tooling (like the mentioned before: events, buses, etc.). Since changing the architecture of an application is usually a costly process, even when iteratively, applying this approach to existing codebases may mean a significant effort.&lt;/p&gt;

&lt;p&gt;Pattern CQRS is a lower level thingy, and therefore easy to apply in a case-by-case basis. Therefore, it will be probably easier to refactor an existing application with this approach, even when the benefits are coming in smaller bits.&lt;/p&gt;

&lt;p&gt;There is this &lt;a href="https://medium.com/docplanner-tech/the-essence-of-cqrs-90bdc7ee0980" rel="noopener noreferrer"&gt;excellent post&lt;/a&gt; from Alberte Mozo, explaining the pattern initial formulation and how none the architectural or pattern approaches (and everything in between) are necessarily better or more pure, if being pure is even a relevant thing.&lt;/p&gt;

&lt;p&gt;Here we are interested in Pattern CQRS in a brownfield project, and we will use a simplified example to illustrate it. &lt;/p&gt;

&lt;h1&gt;
  
  
  A familiar scenario
&lt;/h1&gt;

&lt;p&gt;Let's assume an existing codebase with the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The application is organized in use cases.&lt;/li&gt;
&lt;li&gt;There is some abstraction to fetch entities from our domain model, like repositories.&lt;/li&gt;
&lt;li&gt;The entities are modeled to cover both command and query operations.&lt;/li&gt;
&lt;li&gt;Some read operations involve many entities.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For instance, we have a use case to activate users and another one to list all users. The &lt;code&gt;User&lt;/code&gt; entity is used in both, but listing users requires to show the subscription plan users have so we need to involve the &lt;code&gt;Subscription&lt;/code&gt; entity for the listing as well.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&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="c1"&gt;//Many other properties&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;Status&lt;/span&gt; &lt;span class="nv"&gt;$status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="kt"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;activate&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&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;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;canBeActivated&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;status&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;status&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;toActive&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;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;getStatus&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;string&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="n"&gt;status&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;toString&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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Subscription&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="c1"&gt;//many properties unrelated to listing users&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;Type&lt;/span&gt; &lt;span class="nv"&gt;$type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="kt"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;typeAsString&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;string&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="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;asString&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;The activation use case is a command and uses &lt;code&gt;User&lt;/code&gt; to change state:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ActivateUser&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;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="kt"&gt;UserRepository&lt;/span&gt; &lt;span class="nv"&gt;$userRepository&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="kt"&gt;UserId&lt;/span&gt; &lt;span class="nv"&gt;$userId&lt;/span&gt;
    &lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$userRepository&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getWithId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;activate&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;While listing users uses both entities as the data required is scattered among them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ListUsers&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;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="kt"&gt;UserRepository&lt;/span&gt; &lt;span class="nv"&gt;$userRepository&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="kt"&gt;SubscriptionRepository&lt;/span&gt; &lt;span class="nv"&gt;$subscriptionRepository&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;ListUserCollection&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$userRepository&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;findAll&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="nv"&gt;$response&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;ListUserCollection&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;        
        &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$users&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nv"&gt;$userSubscription&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$subscriptionRepository&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;forUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
            &lt;span class="nv"&gt;$response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$response&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="p"&gt;[&lt;/span&gt;
                    &lt;span class="s1"&gt;'email'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s1"&gt;'subscription_type'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$userSubscription&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;typeAsString&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                    &lt;span class="c1"&gt;//many other fields&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;return&lt;/span&gt; &lt;span class="nv"&gt;$response&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;There are a number of potential problems here.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Entities are messed up&lt;/strong&gt;. They cover both types of operations and chances are some of their properties are there just to show data, while some others are used also to perform business logic. The properties used for reading data use cases are accessible either via getters or public properties in order to return some response. This &lt;strong&gt;breaks the encapsulation&lt;/strong&gt; OOP principle and &lt;strong&gt;harms the ability to refactor and evolve&lt;/strong&gt; our domain model. Not to mention that the &lt;strong&gt;entities are bloated&lt;/strong&gt; with properties not intended for business logic.&lt;/p&gt;

&lt;p&gt;Our example is simplified, but we can assume &lt;code&gt;User&lt;/code&gt; has far too many properties. &lt;code&gt;Subscription&lt;/code&gt; as well, and it's specially painful here because we only care about the string representation of the type from it. We need to include getters for a string representation of user status and subscription type, which makes changing them more complex than being an internal concern of the entities.&lt;/p&gt;

&lt;p&gt;Another potential problem is &lt;strong&gt;performance and wasted resources&lt;/strong&gt;. Overall, read use cases are expected to be served faster because there is somebody waiting for a response in the other side of the wire. Since we use entities to access data, a read use case may require many of them to pick just small bits from each. Entities will include many other properties that are irrelevant for the current needs, but the resources and time are invested to fetch them anyway. &lt;/p&gt;

&lt;p&gt;In our example, if building a &lt;code&gt;Subscription&lt;/code&gt; requires many joins at database level, we are incurring on that overhead just to get the type.&lt;/p&gt;

&lt;h1&gt;
  
  
  CQRS benefits
&lt;/h1&gt;

&lt;p&gt;By applying CQRS we prevent the above issues by creating different models for the write and read operations. Entities are freed of read-only data and we introduce a separate read model that is only a data structure with no business logic involved.&lt;/p&gt;

&lt;p&gt;Our write model can evolve in a more flexible way because there are not extra properties and the amount of public interface exposed is reduced.&lt;/p&gt;

&lt;p&gt;The read model is ad-hoc for the query use cases and the data access operations can be optimized for faster responses.&lt;/p&gt;

&lt;p&gt;Both Architecture and Pattern CQRS help for a better entity modelling, while the optimized reads are way more powerful in Architecture CQRS than in the Pattern version, which may still require some query gymnastics to access all the data.&lt;/p&gt;

&lt;h1&gt;
  
  
  Implementing Pattern CQRS
&lt;/h1&gt;

&lt;p&gt;In Architecture CQRS the write model (the entities) publish events when there is a state change. These events are processed to update the persistence dedicated to the read model only and to read operations we use simple &lt;code&gt;SELECT&lt;/code&gt; queries. We can even use a different persistence technology to favor read speed. As commented, it influences the whole architecture and needs specific tooling to accommodate it.&lt;/p&gt;

&lt;p&gt;In Pattern CQRS we give up some of the benefits of the Architectural version, but its implementation is more straightforward. Introducing it in existing applications is overall simpler and gives immediate benefits.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a new model for the read use cases consisting only of the data they require.&lt;/li&gt;
&lt;li&gt;Create a new data access abstraction that fetches this model.&lt;/li&gt;
&lt;li&gt;Replace the usage of the write model repositories with the new abstraction, and use the read model to produce the response.&lt;/li&gt;
&lt;li&gt;Profit.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Applied to our example, the activate use case stays the same but the read is simplified to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ListUsers&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;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="kt"&gt;ListUsersQuery&lt;/span&gt; &lt;span class="nv"&gt;$query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;ListUserCollection&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;$query&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;findAll&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;Since the &lt;code&gt;ListUsersQuery&lt;/code&gt; will take care of doing the query to get the exact data needed.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;User&lt;/code&gt; entity no longer requires data intended to read operations and has a smaller public interface:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&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="c1"&gt;//Other properties, but none for read operations&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;Status&lt;/span&gt; &lt;span class="nv"&gt;$status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="kt"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;activate&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;//same as before&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;Changing its internal representation involves less changes since it's not exposed anymore.&lt;/p&gt;

&lt;h1&gt;
  
  
  Upsides
&lt;/h1&gt;

&lt;p&gt;As we see in our naive example we don't need to change the command use cases, and for the query use case we introduce a new model and the abstraction to get it from persistence. This can be done in an iterative way and with a reduced amount of changes introduced each time.&lt;/p&gt;

&lt;p&gt;While we migrate read use cases to Pattern CQRS, we can incrementally get rid of unused properties in our entities. They become less verbose and include only data used for command operations. A smaller public interface means better encapsulation and makes refactoring and evolving them easier than with a bigger public surface.&lt;/p&gt;

&lt;p&gt;Actually, the more we attach entities to read operations the more we are inclined to mimic the database when designing them, which harms the domain design flexibility. CQRS helps to reduce that temptation.&lt;/p&gt;

&lt;p&gt;The performance can potentially improve as well, reducing the queries to fetch only what we need.&lt;/p&gt;

&lt;p&gt;Finally, by applying Pattern CQRS we end up with a use case design prepared to transition to Architectural CQRS easily since the read use cases will be basically the same (many other changes are needed, but in other places; the transitions is easier but not trivial)&lt;/p&gt;

&lt;h1&gt;
  
  
  Downsides
&lt;/h1&gt;

&lt;p&gt;There is always a tradeoff and Pattern CQRS is no exception. We used a simple example in this post, but sometimes (always) reality is not that straightforward.&lt;/p&gt;

&lt;p&gt;If our read use case requires data that is computed through business logic, we would need to fetch the entities anyway to run the calculations (or to replicate the business logic in the queries, which is a very bad idea).&lt;/p&gt;

&lt;p&gt;For instance, if listing orders shows the order total and this value is not persisted but calculated in the &lt;code&gt;Order&lt;/code&gt; entity (by adding each order line total, apply taxes, discounts, etc.) we will need to fetch and use &lt;code&gt;Order&lt;/code&gt; to build our response.&lt;/p&gt;

&lt;p&gt;We should evaluate whether adopting CQRS is worth the effort, as it may reduce clarity and even degrade performance due to fetching entities on top of the read model.&lt;/p&gt;

&lt;p&gt;From a maintenance perspective, by adopting Pattern CQRS we are introducing a new model without fully breaking the persistence coupling between write and read models. We should expect certain maintenance overhead. Simple domains without relevant business logic may be totally fine mixing up write and read data since they tend to not change much, and we may be investing resources in a separation that may not reap any benefits.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;We have seen how we can benefit from CQRS by introducing it in existing applications without a big bang architectural change. How beneficial this can be should be analyzed in each case, since it is not a silver bullet, and it can sometimes do more harm than good.&lt;/p&gt;

&lt;p&gt;If you, as it happens to me, are annoyed by unreadable entities cluttered with getters and so attached to the database design that it is cumbersome to evolve them, consider giving Pattern CQRS a try. A single well-chosen use case refactor can show the potential of it right away and convince skeptics and those wary of over-engineering.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Cover image by &lt;a href="https://commons.wikimedia.org/wiki/User:PetarM" rel="noopener noreferrer"&gt;PetarM&lt;/a&gt;, under &lt;a href="https://creativecommons.org/licenses/by-sa/4.0/deed.en" rel="noopener noreferrer"&gt;Creative Commons Attribution-Share Alike 4.0 International&lt;/a&gt; license.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>oop</category>
      <category>architecture</category>
      <category>cqrs</category>
    </item>
    <item>
      <title>Understanding clean architectures</title>
      <dc:creator>Carlos Gándara</dc:creator>
      <pubDate>Mon, 09 Sep 2024 10:07:25 +0000</pubDate>
      <link>https://dev.to/xoubaman/understanding-clean-architectures-33j0</link>
      <guid>https://dev.to/xoubaman/understanding-clean-architectures-33j0</guid>
      <description>&lt;p&gt;The &lt;em&gt;clean architecture&lt;/em&gt; concept was introduced by Robert C. Martin &lt;a href="https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html" rel="noopener noreferrer"&gt;back in 2012&lt;/a&gt;. He later published a well known book about it with the slightly lazy but straightforward title &lt;a href="https://www.goodreads.com/book/show/18043011-clean-architecture" rel="noopener noreferrer"&gt;Clean Architecture&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In this post we will cover the foundations behind this architectural pattern.&lt;/p&gt;

&lt;p&gt;It is worth mentioning that I have not read the book. Therefore, the following content is not based directly on it but in its underlying concepts.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL:DR;
&lt;/h2&gt;

&lt;p&gt;In a clean architecture the application is divided into layers, assigning concrete responsibilities to each of them.&lt;/p&gt;

&lt;p&gt;Those layers wrap each other and communicate only inwards: an outer layer can use stuff from inner layers, but not the other way around. This is known as Dependency Rule.&lt;/p&gt;

&lt;p&gt;The more outward a layer is, the lower-level its  responsibilities are. The innermost layer takes care only of the higher level details: the domain model.&lt;/p&gt;

&lt;p&gt;That's basically it when it comes to how this architectural pattern structures things. The &lt;em&gt;how.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It is only by knowing the &lt;em&gt;why&lt;/em&gt; behind it that we will understand what we get in return and when it is worth to use it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Software purpose
&lt;/h2&gt;

&lt;p&gt;We create software to solve problems. We should at least. If it's not the case, please spend a bit of reflection on what we want this world to be and what are we doing to achieve it. Anyway. Solve problems.&lt;/p&gt;

&lt;p&gt;To solve a real world problem with software, we create a model that represents part of the real world that helps us to tackle its complexity.&lt;/p&gt;

&lt;p&gt;Software does not only have to deal with just the problems it solves, though. It runs in computers, it's written in a language, uses networks, servers, protocols...&lt;/p&gt;

&lt;p&gt;If we mix together all these technicalities with the problem model, we are putting a spoke in our wheels by making the model and the technical part more complex than they actually are. Which is something we usually want to avoid. Clean architectures help keep separated the stuff that do not belong together.&lt;/p&gt;

&lt;p&gt;Before moving forward with the clean architecture itself, we will take an interlude to talk about complexity and cognitive load, concepts tightly related to the goals of clean architectures.&lt;/p&gt;

&lt;h2&gt;
  
  
  Complexity is all over the place
&lt;/h2&gt;

&lt;p&gt;Complexity is, oversimplifying, how hard it is to grasp how all the moving parts of a system work together.&lt;/p&gt;

&lt;p&gt;More &lt;em&gt;complexity&lt;/em&gt; means more effort is required to understand, maintain, and extend a software system. This effort is known as cognitive load.&lt;/p&gt;

&lt;p&gt;Therefore, keeping cognitive load low by removing complexity is a good thing to do. Easier said than done, because complexity cannot be removed in its entirety.&lt;/p&gt;

&lt;p&gt;There are two types of complexity: essential and accidental.&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;essential complexity&lt;/em&gt; is intrinsic to the problem we want to solve, and it's there no matter what. It cannot be eliminated. Not even reduced.&lt;/p&gt;

&lt;p&gt;For instance, in an e-commerce we cannot realistically say "no, rejected payments are not a thing for us". Certainly life would be easier without them, but the reality is payments are sometimes rejected. This complexity is essential to the problem our application solves.&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;accidental complexity&lt;/em&gt; is what we humans, in all our messiness, add to things, consciously or not, making things harder than they essentially are. We cannot escape it, it's part of the human nature. We can, though, stay vigilant and mitigate it as much as we reasonably can (or want).&lt;/p&gt;

&lt;p&gt;A blatant example of accidental complexity would be adding load balancing and database sharding to an application intended to manage a small dental clinic. The application does not need that, and it makes harder to understand it.&lt;/p&gt;

&lt;p&gt;A more subtle example would be, in our previous e-commerce application, to mix up technical details like HTTP requests and the database table relations needed to fetch data, with the domain logic needed to manage something already complex enough like payments. By not keeping those different concerns separated, we are making both parts harder to understand.&lt;/p&gt;

&lt;h2&gt;
  
  
  What for
&lt;/h2&gt;

&lt;p&gt;Now that we have agreed on some definitions, we can state the purpose of a clean architecture:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;To keep our model of the real world separated from technical details, so we avoid introducing accidental complexity in both sides.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In other words, to reduce accidental complexity by keeping the essential complexity of running software separated from the essential complexity of the problem solved by the software.&lt;/p&gt;

&lt;p&gt;Clean architectures structure applications in a way that helps us to keep the accidental complexity (a part of it at least) under control.&lt;/p&gt;

&lt;h2&gt;
  
  
  The layers
&lt;/h2&gt;

&lt;p&gt;Layers are groupings of responsibilities. There can be any number of them at code level but attending to its purpose they boil down to three.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;👉 Indeed, the original post where the pattern was presented includes four layers. Which to my understanding is an implementation-level decision rather than a purpose-level grouping. Like with everything else, I'm just a guy with an opinion on the internet. Read, ponder, and build you own understanding without blindly follow anything.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fv5holc0wihogfmm7z493.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fv5holc0wihogfmm7z493.png" alt="A diagram showing three concentric layers: infrastructure is the outermost, application is the one in the middle and domain the one in the center" width="626" height="273"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In a clean architecture, we visualize layers as concentric circles (or half a circle to optimize space, he). The more we move inside, the higher level of detail the layer takes care of.&lt;/p&gt;

&lt;p&gt;The outermost layer is the &lt;strong&gt;Infrastructure Layer&lt;/strong&gt;, connecting the different technologies the application interacts with in the way the inner layers require. This is the lower level of detail our application has to deal with, technology specific stuff like HTTP headers, the format of request payloads, databases, etc.&lt;/p&gt;

&lt;p&gt;Next is the &lt;strong&gt;Application Layer&lt;/strong&gt; (also known as &lt;em&gt;Service Layer&lt;/em&gt;), holding a representation of the use cases the application exposes and taking care of orchestrating the execution of the right logic for the use case requested. It manages a higher level of detail by knowing the logic a use case needs, without any technical details involved.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;👉 The Application Layer does not need to always orchestrate Domain Layer logic, although it may seem so from the usual diagrams used to represent a clean architecture. For instance, use cases for plain read operations may not require any business logic.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The innermost one is the &lt;strong&gt;Domain Layer&lt;/strong&gt;, where our model of the problem to solve lives. This is the highest level of detail. By keeping our domain model isolated from the concerns of the Infrastructure and Application layers, we can approach its complexity without distractions, making it easier to evolve and change.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;👉 The framework we use to run our application is an infrastructural concern as well. We can think of it as if Application and Domain code is "portable" and should require no change if we switch to another framework.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The Dependency Rule
&lt;/h2&gt;

&lt;p&gt;The Dependency Rule defines the visibility between layers. It states that a layer can only depend on inner layers, never in outer layers. In other words, a layer cannot have code references to anything that is declared in an outer layer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F4o8ykogsr8gy0vszzb0x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F4o8ykogsr8gy0vszzb0x.png" alt="Diagram showcasing how it is allowed to import code from inner layers, but it is forbidden to import code from outer layers" width="626" height="354"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What we achieve with the Dependency Rule is that no details of a layer leak into the others. By applying inversion of dependencies (the "I" in SOLID), inner layers define abstractions that outer layers implement. The abstraction is defined by the inner layer, and therefore sticks to its level of abstraction, and it's not polluted by lower level details.&lt;/p&gt;

&lt;p&gt;The classic example are Domain repositories. At Domain level we define an interface which is implemented in the Infrastructure layer. But this interface sets a contract expressed in Domain language, with no technicalities involved. In the Infrastructure layer, the implementation will take care of mapping the data to the right tables, which are lower level details that should not concern the Domain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Anatomy of a clean architecture
&lt;/h2&gt;

&lt;p&gt;It's about time we come with somewhat practical examples after all this theory.&lt;/p&gt;

&lt;p&gt;In the Domain Layer we have our domain model, an abstraction of the real world problem. The design may not be the best, but it's good enough to illustrate how the thing works:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface PaymentRepository {
    fn findById(PaymentId id): Payment
}

class Payment {
    private Status status;
    private RejectionDate rejectedOn;

    fn reject(Date when) {
        status = Status.rejected();
        rejectedOn = RejectionDate.fromDate(when);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our domain model is written in pure domain language. There are no references to databases, HTTP requests, message queues or any other technology. Neither there are references the framework.&lt;/p&gt;

&lt;p&gt;When we go to the code to see what rejecting a payment means, the code tells us directly, and we do not need extra cognitive load to separate the business logic from other unrelated details. Analogously, the &lt;code&gt;PaymentRepository&lt;/code&gt; is a contract the Domain defines in its own terms. The implementations will live in the Infrastructure, dealing with the technical details of the technologies used.&lt;/p&gt;

&lt;p&gt;At the Application Layer we have the use case that represents a payment must be rejected:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class RejectPaymentUseCase {
    fn RejectPaymenUseCase (
        private PaymentRepository repository,
        private Clock clock
    );

    fn execute(RejectPayment request) {
        payment = repository.findById(PaymentId.fromValue(request.paymentId));
        payment.reject(Clock.now());
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Application Layer just orchestrates the logic needed to fulfill the "reject payment" use case. It does not know what it means at business level, only what must be executed to do it. Analogously to the Domain Layer, there is no interference from technical details. &lt;/p&gt;

&lt;p&gt;It is in the Infrastructure Layer where we find technical references:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class RejectPaymentHttpController {
    fn RejectPaymentHttpController (
        private RejectPaymentUseCase useCase
    );

    fn execute(HttpRequest request): void {
        payload = JsonHelper.deserialize(request.payload);
        useCase.execute(
            new RejectPayment(payload.paymentId);
        );
    }
}

class SqlPaymentRepository &amp;lt; PaymentRepository {
    fn findById(PaymentId $id): Payment {
        //details of database tables, prepared statements and other DB stuff
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The entry points to the application are the ones that handle the low level details of the underlying technology. In this case the HTTP controller knows about HTTP requests, deserializing JSON payloads, etc. Same for the repository implementation: at Application Layer level, the use case knows nothing about the persistence details of a Payment, it just knows the contract the Domain Layer defines.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;👉 Contracts can be defined by Application Layer as well, it's not an exclusive treatment for the Domain.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;While adhering to the contracts specified by inner layers, they prevent this complexity to leak into layers with different purposes.&lt;/p&gt;

&lt;p&gt;In this sneak peek into what a clean architecture looks like we have deliberately used a quite simple example. There is way much more to it. The purpose of this example is to just show how the layers are taking care of their own concerns, liberating other layers of extraneous details.&lt;/p&gt;

&lt;p&gt;Real life™️ will require a much more complex implementation because there are many more things to model and take into consideration: message buses, event driven design, the outbox pattern, CQRS, configurations and environments... the list is huge. Some stuff is optional, some other contextual. But rest assured there is more and the above is not a blueprint to start with.&lt;/p&gt;

&lt;h2&gt;
  
  
  Humans after all
&lt;/h2&gt;

&lt;p&gt;As with every pattern, it is up to us to be consistent with it. In case of clean architecture there is no standard implementation (unless you take the one from Robert C. Martin as such... just be aware there are other valid options).&lt;/p&gt;

&lt;p&gt;The most common pitfall when going clean is to make the Application Layer too smart, leaking Domain logic in our use cases instead of just using the right parts of the domain model. And that's something the architecture cannot prevent.&lt;/p&gt;

&lt;p&gt;It would be also tempting to make the Infrastructure Layer to run some domain logic to get a persisted entity into a certain state.&lt;/p&gt;

&lt;p&gt;Or to introduce technical details into the domain model because it seems convenient.&lt;/p&gt;

&lt;p&gt;While I would discourage to do any of this, it might make sense under certain circumstances. It is our decision to contravene the architecture foundations at a given moment.&lt;/p&gt;

&lt;p&gt;At this point we should already have the understanding of what we are giving in exchange. And that probably the transgressions should not stay there for long.&lt;/p&gt;

&lt;h2&gt;
  
  
  When and when not
&lt;/h2&gt;

&lt;p&gt;There is a trade-off. There always is.&lt;/p&gt;

&lt;p&gt;As we have seen, there is a level of essential complexity in a clean architecture itself. Not only knowing about the layers, their responsibilities, and the Dependency Rule. There is also all the extra salt we can or must add for the architecture to actually do the work.&lt;/p&gt;

&lt;p&gt;Turns out in our attempt to reduce complexity we are adding more complexity. What a world!&lt;/p&gt;

&lt;p&gt;So when does it make sense to use clean architectures? The math is simple: when the problem we are solving is complex enough on its own that the additional complexity introduced by clean architecture is outweighed by what we gain in return.&lt;/p&gt;

&lt;p&gt;Clean architectures will work best when we are dealing with the core domain of our business. This is usually complex enough to compensate the effort of having such an architecture. We want our core to be easy to iterate, and clean architectures are good at that by keeping the domain model isolated. Not so critical parts of the system may not be worth the effort. When the problem is not complex enough a more dirty approach can suffice for the same effectiveness with a lower effort.&lt;/p&gt;

&lt;p&gt;In our e-commerce example we have seen payments are complex and a clean architecture pays back. But something accessory like the comments of products might be simple enough so that a hardcore-framework MVC approach will provide the same result in less time with no perceptible penalties.&lt;/p&gt;

&lt;p&gt;Architectures are chosen to support our needs. If the needs change, maybe an architectural change is required as well. If our comments subsystem becomes a differential part of the business and grows in functionalities and complexity, our good old MVC system could become overwhelmed, and we will need to transition to a different architecture to support it. Maybe a clean one. Embrace the change!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;👉 It could make sense that within the same application we may go clean for part of it and use another architecture for the less complex use cases. Symmetry has its advantages: if everything works the same way, it's easier to understand. But is it worth all the indirection for the most basic use cases? Well... it depends.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What is not
&lt;/h2&gt;

&lt;p&gt;Clean architecture is not a synonym of Ports and Adapters (aka Hexagonal Architecture). Neither it is a synonym or a requirement for CQRS, Event Sourcing, Event Driven Architectures, or Domain Driven Design.&lt;/p&gt;

&lt;p&gt;It is possible to go with any of those without a clean architecture. Although clean architectures are great friends of those other patterns.&lt;/p&gt;

&lt;h2&gt;
  
  
  Concluding
&lt;/h2&gt;

&lt;p&gt;We should have now a clear understanding of the principles behind clean architectures (or, at least, my version of them).&lt;/p&gt;

&lt;p&gt;We didn't dig much into implementation details, though. There is a lot to say about it. Reading about the message bus and the command + command handler patterns is a good follow-up to take the most out of a clean architecture, along with approaches that focus on domain modeling, like Domain Driven Design.&lt;/p&gt;

&lt;p&gt;That's all. Feedback is always welcome so drop a comment if you want.&lt;/p&gt;

&lt;p&gt;Be kind. And as happy as possible.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The cover picture is the science library of Upper Lusatia in Görlitz, Germany. The photo was taken by Ralf Roletschek (&lt;a href="//Roletschek.at"&gt;Roletschek.at&lt;/a&gt;), who holds the copyright, and it's available at &lt;a href="https://commons.wikimedia.org/wiki/File:13-11-02-olb-by-RalfR-03.jpg" rel="noopener noreferrer"&gt;Wiki Commons&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>cleancode</category>
      <category>oop</category>
    </item>
    <item>
      <title>Structuring Modular Monoliths</title>
      <dc:creator>Carlos Gándara</dc:creator>
      <pubDate>Mon, 11 Dec 2023 14:56:14 +0000</pubDate>
      <link>https://dev.to/xoubaman/modular-monolith-3fg1</link>
      <guid>https://dev.to/xoubaman/modular-monolith-3fg1</guid>
      <description>&lt;p&gt;A &lt;a href="https://en.wikipedia.org/wiki/Monolithic_application" rel="noopener noreferrer"&gt;monolith&lt;/a&gt; is a self-contained software application responsible for the whole set of functionalities of a system.&lt;/p&gt;

&lt;p&gt;It is a term with negative connotations. Not because there is an inherent flaw in it, but because of the context surrounding it. Which most of the time is that the company growth was not balanced with appropriate architectural design.&lt;/p&gt;

&lt;p&gt;In this post we will explore a way of structuring monolith applications that avoids the most common pitfalls associated with this way of building and shipping applications.&lt;/p&gt;

&lt;p&gt;Following there are a number of guidelines to have a healthy monolith. Even when the naming or the language used seems to refer to absolutes, the value is in what we want to achieve with each decision. There are many ways to get there and here we just describe one.&lt;/p&gt;

&lt;h2&gt;
  
  
  The ugly monolith
&lt;/h2&gt;

&lt;p&gt;Monoliths are often associated to the (un)architectural pattern named &lt;a href="http://www.laputan.org/mud/" rel="noopener noreferrer"&gt;big ball of mud&lt;/a&gt;. The usual stinky stuff we find there is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Everything is accessed by everyone, everywhere.&lt;/li&gt;
&lt;li&gt;Persistence is shared across all the monolith. &lt;/li&gt;
&lt;li&gt;A trend to have &lt;a href="https://en.wikipedia.org/wiki/God_object" rel="noopener noreferrer"&gt;god objects&lt;/a&gt; and over-abstractions.&lt;/li&gt;
&lt;li&gt;The framework is everywhere, there is no isolation from it or for other vendor libraries.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Although it's true a distributed system would mitigate some of these problems, it won't be guaranteed and for sure not for free. There is little correlation between these disturbing circumstances and shipping our application as a one or many units. A messed up monolith is a messenger. Instead of blaming the messenger, we could better try to understand the message and get out of the mud.&lt;/p&gt;

&lt;p&gt;How? Structuring our monolith it in a way that fosters separation of responsibilities and defines clear boundaries between the different domains it includes. Monoliths can be nice.&lt;/p&gt;

&lt;h2&gt;
  
  
  The modular monolith
&lt;/h2&gt;

&lt;p&gt;A &lt;em&gt;domain&lt;/em&gt; is &lt;a href="https://www.oxfordlearnersdictionaries.com/definition/english/domain?q=domain" rel="noopener noreferrer"&gt;"an area of knowledge or activity"&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We call &lt;em&gt;module&lt;/em&gt; the aggregation of all the code that takes care of a certain domain -or a group of domains- within our monolith. &lt;/p&gt;

&lt;p&gt;In a modular monolith:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Modules are the &lt;strong&gt;high level organizational units&lt;/strong&gt;. Although they live withing the same monolith, we manage them as if they were &lt;strong&gt;isolated applications&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;They have &lt;strong&gt;limited visibility of each other&lt;/strong&gt;. We cannot call arbitrary parts of a module internal implementation, avoiding the high coupling this implies.&lt;/li&gt;
&lt;li&gt;Each module has &lt;strong&gt;its own persistence layer&lt;/strong&gt;. So changes in a module data schema do not directly affect others.&lt;/li&gt;
&lt;li&gt;A module is ideally &lt;strong&gt;own by a single team&lt;/strong&gt;. Otherwise, Conway's Law will manifest and the need to communicate between the teams will result in a module sneakily split into two.&lt;/li&gt;
&lt;li&gt;Modules communicate via direct code calls, controlled by each module, or messaging. Both ways are explicit. &lt;strong&gt;Each module controls its own boundaries&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fp2vyoi97w96zgu8344q0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fp2vyoi97w96zgu8344q0.png" alt="Big ball of mud vs modular monolith patterns" width="800" height="419"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For instance, in an e-commerce application we could have domains like Product Catalog, Order Handling, Payments, Shipping, etc. Sometimes, depending on the concrete case, we will have a module for each of them, or we may decide it's a good idea to group together Order Handling and Shipping if they are closely related.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Product&lt;/code&gt; in the Product Catalog module will not be polluted by Order Handling related actions. Order Handling will have its own independent &lt;code&gt;Product&lt;/code&gt; model.&lt;/p&gt;

&lt;p&gt;To query product data, the Product Catalog module will expose a client with a defined contract for doing so (code call communication). To inform a new product was created, the Product Catalog module will publish a message in a shared bus (messaging communication) so other modules can react to it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which modules?
&lt;/h2&gt;

&lt;p&gt;Figuring out the right modules is no easy task.&lt;/p&gt;

&lt;p&gt;We must take our time for doing domain discovery and come up with a reasonable structure of modules. Chances are they won't be right in the first attempt. Software is an ever-changing thing, and we will need to rethink and adjust our modules to reflect that. Which is fine. The intention of this post is not to cover that specific aspect, though.&lt;/p&gt;

&lt;p&gt;Techniques like &lt;a href="https://www.eventstorming.com/book/" rel="noopener noreferrer"&gt;Event Storming&lt;/a&gt;, &lt;a href="https://domainstorytelling.org/book" rel="noopener noreferrer"&gt;Domain Storytelling&lt;/a&gt;, or &lt;a href="https://github.com/ddd-crew/context-mapping" rel="noopener noreferrer"&gt;Context Mapping&lt;/a&gt; can help with the domain discovery and identifying our modules.&lt;/p&gt;

&lt;h2&gt;
  
  
  High level organization
&lt;/h2&gt;

&lt;p&gt;This is how the high level structure of a modular monolith could look like (the numbers in the left means belonging to the same organizational element):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#1 .github/
#1 .docker/
#2 docs/
#3 src/
#3    Module1/
#3    Module2/
#3        Module2A/
#3        Module2B/
#3    Module3
#4    ModuleBus/
#5    Boilerplate/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;#1&lt;/strong&gt; In the root we have the general &lt;strong&gt;operational stuff&lt;/strong&gt;. Note we don't have shared dependencies, as they are defined at module level.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;#2&lt;/strong&gt; There is space for &lt;strong&gt;transversal documentation&lt;/strong&gt;. Besides docs on how to set up environments, pipelines, deployments, etc., this is the right place to document guidelines on the architectural styles to default to (more on this in a moment).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;#3&lt;/strong&gt; Inside &lt;code&gt;src&lt;/code&gt; we set a &lt;strong&gt;high level structure&lt;/strong&gt; that tells us first sight what are the different activities our system covers. Nesting modules is fine for a more meaningful grouping, although there is no shared code in a parent module.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;#4 #5&lt;/strong&gt; There are two eyebrow-raising artifacts, though. &lt;code&gt;ModuleBus&lt;/code&gt; and &lt;code&gt;Boilerplate&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ModuleBus&lt;/code&gt; goal is to provide lightweight tooling for modules to publish messages that could be consumed by other modules, in a pub-sub fashion. All modules have access to it. More details in a moment.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Boilerplate&lt;/code&gt; is an intentionally terrible name for what we usually see as &lt;code&gt;Common&lt;/code&gt;, &lt;code&gt;Shared&lt;/code&gt;, or &lt;code&gt;Utils&lt;/code&gt;: tools or models we don't want to repeat over and over... unless maybe we do want?&lt;/p&gt;

&lt;p&gt;"Base" models seem a convenient and harmless thing to have. However, if there is free access to them from everywhere in the monolith they tend to attract new concrete aspects that are required by just on module. This tends to cause over-abstractions to make room for too many parties interests, and recurrent breaking changes caused by the high coupling of many moving parts to the same shared code.&lt;/p&gt;

&lt;p&gt;The proposal here is to not allow direct usage of &lt;code&gt;Boilerplate&lt;/code&gt; code. The shared libraries and models are there, but cannot be used directly. Instead, modules copy the shared stuff they need in their own &lt;code&gt;Boilerplate&lt;/code&gt; namespace and use their own version, which can evolve -or not- without interfering with other modules.&lt;/p&gt;

&lt;h2&gt;
  
  
  Module internals
&lt;/h2&gt;

&lt;p&gt;In each module we will find some common artifacts and the module implementation itself.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/
    Module1/
        [module implementation]
        Client/
        Messaging/
        docs/
            adr/
                adr1.md
                adr2.md
                ...
        dependencies.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the implementation we will do whatever makes sense, being it a clean architecture, a full framework one, or whatever else. The complexity of the domains, among other factors, will dictate it. Being modular does not mean we cannot choose the most appropriate architecture for each module.&lt;/p&gt;

&lt;p&gt;Dependencies are defined per module as well. This allows each module to use its own toolset and not get restricted by the module that take more time to upgrade, preventing the use of more recent dependencies.&lt;/p&gt;

&lt;p&gt;Modules have their own documentation. Remember we mentioned adding general architecture guidelines in the doc at root level? The module doc is the place to confirm they are followed or not, along with the reason for changing anything and what the change is. &lt;a href="https://www.ozimmer.ch/practices/2023/04/03/ADRCreation.html" rel="noopener noreferrer"&gt;Architecture Decision Records&lt;/a&gt; are a great tool for that purpose.&lt;/p&gt;

&lt;p&gt;In the area of common artifacts, we have the &lt;code&gt;Client&lt;/code&gt; and &lt;code&gt;Messaging&lt;/code&gt; namespaces, used for the communication between modules.&lt;/p&gt;

&lt;h2&gt;
  
  
  Talking with the outside
&lt;/h2&gt;

&lt;p&gt;Since we treat each module as a separate application, when the time comes to communicate with other module we should assume it is somewhere else, like there is a network in between. Therefore, is each module defining what others modules can do and how to do it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code call communication&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One benefit of being in the same application is that we can use direct code calls that do not rely on the network to succeed. In our proposal, a module provides with &lt;em&gt;clients&lt;/em&gt; visible to other modules which act as the only direct entry points via code, defining the functional surface the module exposes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/
    Module1/
        ...
        Client/
            ClientV1.code
            ClientV1Mock.code
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In terms of visibility, a module is allowed to import and use other modules' clients. And that's the only single piece of code they can import from the other modules. Ideally a client is defined as an interface, allowing to go with a direct code call implementation or an over-the-network implementation, in case it's needed (for instance, by an actual external application). &lt;/p&gt;

&lt;p&gt;Clients are maintained by the team owning the module, which provide with a mocked version of it as well. This way, client modules have reliable test double that is up-to-date with the client input and output schemas.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Messaging communication&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The client is covering direct code calls, when a module requests something to another module. With &lt;code&gt;Messaging&lt;/code&gt; we cover the indirect communication, when something happens in a module that could be of interest for another module, in a pub-sub fashion.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/
    Module1/
        ...
        Messaging/
            Publishing/
                SomethingHappenedHere.code
            SubscribedTo/
                SomethingHappenedElsewhere.code
    ModuleBus/
        MessageBus.code
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;ModuleBus&lt;/code&gt; is the tool we provide for the modules to publish messages about their internal activity. Similarly to the clients, it defines a contract to publish messages, and it will take care of delivering it to the interested subscribers.&lt;/p&gt;

&lt;p&gt;Modules will define which messages they publish and which messages from other modules they want to subscribe to. When a module publishes a message in the bus, it takes care to notify all the interested subscribers.&lt;/p&gt;

&lt;p&gt;The highlight with this bus is that we can do in-memory messaging without the need to go through a message broker and the inherent complexity of async communication, while keeping the ability to be async when it makes sense. Furthermore, since from the modules' point of view there is a single contract, we can use the implementation of the &lt;code&gt;ModuleBus&lt;/code&gt; to transition from in-memory to async in a transparent way as needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  The persistence
&lt;/h2&gt;

&lt;p&gt;Each module has its own isolated persistence system, only accessible by the module itself. As with everything there is a degree of convention involved. The isolation may consist in a totally separated database or a subset of prefixed tables in the same database.&lt;/p&gt;

&lt;p&gt;We want to avoid shared data models that are polluted by data from unrelated domains. It's fine to have &lt;code&gt;product_catalog_products&lt;/code&gt; and &lt;code&gt;order_handling_products&lt;/code&gt; tables, even if both refer to "product". Product means something different in each context. The one from Order Handling should not care and should not be affected if we add a new column in the Product Catalog one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Greenfield vs brownfield: migration strategies
&lt;/h2&gt;

&lt;p&gt;So far we have described how to structure a monolith in a way it will look fantastic. This is relatively easy in a greenfield project, when building a system from scratch.&lt;/p&gt;

&lt;p&gt;The reality is that most of the time we deal with already existing systems. Even more, our greenfield project will become a brownfield project in no time, where things are not as fantastic as we thought when we started.&lt;/p&gt;

&lt;p&gt;Here are some strategies to deal with transitions from non-modularized to modularized monoliths. They are based on the premise that we want to be incremental, avoiding big bang releases where we replace big chunks of functionality with a fresh rewrite. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Migration events and responses&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Because it's common to find big classes doing too many things, sometimes it's just not possible to replace them at once with a modularized version.&lt;/p&gt;

&lt;p&gt;Instead, replace smaller parts of functionality with the modularized version, which will communicate back with the original functionality. Emit events or return ad-hoc responses so the original code can resume the logic not migrated yet. Even if that means breaking module visibility rules or leaking muddy monolith stuff into our pristine modules... as long as it is a temporary measure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Shared persistence&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To migrate to a modular monolith usually requires a time window when the logic in the new module shares the persistence with the older code. Because we need to support the working software, because we cannot just take over a table used in many places, or because many other reasons.&lt;/p&gt;

&lt;p&gt;When moving some domain into a module, prepare a specific plan to deal with the database migration. The strategy here consists in not sticking to a dogmatic "modules &lt;strong&gt;do not&lt;/strong&gt; share databases", but to be realistic while keeping a strong compromise to remove the persistence dependency once it's feasible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Avoid on demand "modules"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As it has been stressed a few times already, identifying the right modules is not small task. Because sometimes we want to move fast, we may be tempted to create "modules" for everything, even when it does not match with the purpose and meaning of a module (hence the quotes). The result is an absurd number of modules, often with suspicious similarities in their name.&lt;/p&gt;

&lt;p&gt;Do not create a "module" just for isolating something from the non-modular part of the monolith. The benefits of modularization come from how they aggregate and isolate related logic. We can improve the design of some part of our monolith within the same monolith.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Decisions are not forever&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We may fail to define the right modules at first. Or we may succeed at it, but the problem space evolves and what once was right isn't anymore. It's probable that the current monolith will pollute our understanding, and we will -unconsciously or not- replicate the existing structure, which may not be ideal.&lt;/p&gt;

&lt;p&gt;It is ok to discard or merge modules, or to shrink or expand them because we didn't put the boundaries in the right place. It's part of the learning process. Do not stick to what is there just because it's already there.&lt;/p&gt;

&lt;h2&gt;
  
  
  Concluding
&lt;/h2&gt;

&lt;p&gt;We have covered a number of patterns to structure monolith applications, so they have solid organizational foundations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use modules as organizational units.&lt;/li&gt;
&lt;li&gt;Limit the visibility a module offers to the others using contracts controlled by the module itself.&lt;/li&gt;
&lt;li&gt;Provide a way for messaging communication among modules. &lt;/li&gt;
&lt;li&gt;Do not share the persistence layer. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As pointed out, the value is in the purpose of the proposed patterns, not in the particular suggestions -which, in fact, are kinda naive on purpose. Still, we can mess up in each module concrete implementation. Once again let's stress how important is the domain discovery and setting the best boundaries we can.&lt;/p&gt;

&lt;p&gt;If you have any other experience with modular monoliths -or any other feedback- it would be nice to hear about it in the comments. All good advice is welcome for the sake of monoliths around the world.&lt;/p&gt;

&lt;h2&gt;
  
  
  Credits
&lt;/h2&gt;

&lt;p&gt;For the diagrams I've used &lt;a href="https://excalidraw.com/" rel="noopener noreferrer"&gt;Excalidraw&lt;/a&gt;, borrowing libraries from &lt;a href="https://github.com/mateuszbaransanok" rel="noopener noreferrer"&gt;Mateusz Baran&lt;/a&gt; and &lt;a href="https://anumitha.com" rel="noopener noreferrer"&gt;Anumitha Apollo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The cover picture is from the 1957 movie &lt;a href="https://www.imdb.com/title/tt0050720/" rel="noopener noreferrer"&gt;The Monolith Monsters&lt;/a&gt; which, according to &lt;a href="https://en.wikipedia.org/wiki/The_Monolith_Monsters#References_in_other_media" rel="noopener noreferrer"&gt;Wikipedia&lt;/a&gt;, was the inspiration for the Tiberium mineral in the Comand &amp;amp; Conquer games O_o&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>monolith</category>
      <category>oop</category>
      <category>patterns</category>
    </item>
    <item>
      <title>Understanding Hexagonal Architecture</title>
      <dc:creator>Carlos Gándara</dc:creator>
      <pubDate>Sun, 15 Oct 2023 15:38:46 +0000</pubDate>
      <link>https://dev.to/xoubaman/understanding-hexagonal-architecture-3gk</link>
      <guid>https://dev.to/xoubaman/understanding-hexagonal-architecture-3gk</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Alistair Cockburn was kind enough to give his opinion on this post. Based on this, I have adjusted it a bit, highlighting the parts that changed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The goal of the Hexagonal Architecture (aka ports and adapters, or HA in this post) pattern is, as originally formulated by its author &lt;a href="https://alistaircockburn.com/" rel="noopener noreferrer"&gt;Mr. Alistair Cockburn&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Allow an application to equally be driven by users, programs, automated test or batch scripts, and to be developed and tested in isolation from its eventual run-time devices and databases.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In a &lt;a href="https://dev.to/xoubaman/what-is-not-hexagonal-architecture-1kh7"&gt;previous post&lt;/a&gt; we summarized the way it works as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Hexagonal Architecture promotes the separation of an application internals from its interactions with the external world.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;We have our application, represented as a hexagon. Outside the hexagon there are the external actors: users interacting with a graphical interface, messaging systems, databases, vendor APIs, etc.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The application defines the ways for it to interact with external actors. Each of these contracts is a port. Ports are expressed in application language, like parts of a use case. Adapters are the connections of the external actors with the application using a port. They are interchangeable ways of interacting with the application using different technologies.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Edited on 2024-08-02: The above paragraph was incorrectly stating that adapters are implementations of the ports, which is only half true. It's fixed now.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In this post we will dig deeper in each of the parts of the pattern and link them to code examples.&lt;/p&gt;

&lt;h2&gt;
  
  
  Driving and being driven
&lt;/h2&gt;

&lt;p&gt;Before jumping into more definitions, let's first consider how our applications work from the perspective of the interactions with the external actors.&lt;/p&gt;

&lt;p&gt;Some of these actors &lt;em&gt;use&lt;/em&gt; our application (e.g. a call to our REST API). Other actors &lt;em&gt;are used&lt;/em&gt; by our application instead (e.g. a database).&lt;/p&gt;

&lt;p&gt;We call the former &lt;em&gt;driver actors&lt;/em&gt; and the latter &lt;em&gt;driven actors&lt;/em&gt;. How they interact with our application happens will determine the way we define the contracts the application sets for them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F2obk0pgtfqqkdcq69abz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F2obk0pgtfqqkdcq69abz.png" alt="Driver and driven actors in Hexagonal Architecture" width="691" height="588"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Analogously, this distinction applies to ports, adapters, and sides of the application.&lt;/p&gt;

&lt;h2&gt;
  
  
  The ports
&lt;/h2&gt;

&lt;p&gt;Ports are the contracts the application settles for the interaction with the external actors. Depending on the type of actor we are dealing with, driver of driven, this contract will look different.&lt;/p&gt;

&lt;p&gt;Driver ports define how driver actors interact with the application. Therefore, they specify the input that must be provided in order to ask the application to perform the action the actor is interested in.&lt;/p&gt;

&lt;p&gt;Driven ports define how the application will interact with the driven actor. Therefore, they specify what they want from the actor.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fwpxagxiugtoj7ckmuhfx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fwpxagxiugtoj7ckmuhfx.png" alt="Ports in Hexagonal Architecture" width="615" height="320"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since ports are defined by the application they are written in pure "application language", removing coupling to any detail of concrete technologies. Our application will not care about any technologies, because ports are isolating it from them.&lt;/p&gt;

&lt;p&gt;Examples!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To create a user we need their email and password. The driver port for this use case defines this data as the contract the actor must adhere to in order to use the application. Whoever you are, if you want me to create a user, you must give me this.&lt;/li&gt;
&lt;li&gt;Users are modeled in our application with the &lt;code&gt;User&lt;/code&gt; entity. The driven port for storing users defines that there must be a way to store &lt;code&gt;User&lt;/code&gt; entities.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The adapters
&lt;/h2&gt;

&lt;p&gt;Actors interact with the application. Ports define how these interactions happen. Adapters fill the space between the actors and the application, enabling the conversation between them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fko7aoub10jxx7tiv47j7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fko7aoub10jxx7tiv47j7.png" alt="Adapters in Hexagonal Architecture" width="575" height="311"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Adapters adapt (didn't see that coming) the details of different technologies into what the application has defined beforehand through ports. In the process, those details do not permeate inside our application, keeping it clean. If any response is expected by the actor, it's the adapter responsibility to produce it.&lt;/p&gt;

&lt;p&gt;Following our previous examples, our port to create users specifies the application requires an email and a password. We may have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;For the "user interacting with a graphical interface" actor, an adapter for an HTTP REST API that takes the values from the HTTP request. It also returns the 202 response to the client.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For the "company CRM system" actor, an adapter for a message broker that gets the values from the message payload. The adapter takes care of sending the ACK of the message as well.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For some weird integration with an "old system" actor, an adapter reading the values from a CSV file this system is putting in our FTP server each night.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Wiring everything together: the Configurator
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Edited on 2024-08-02: The first version of the post was not mentioning the Configurator.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;On top of our application, the ports it defines, and the different adapters that connect with the ports, we need something that takes care of using the right elements in the right moment. This is what the pattern refers to as the Configurator.&lt;/p&gt;

&lt;p&gt;Most of the times we use a framework when building software applications: Ruby on Rails, Spring, .NET, Django, etc. The framework usually takes care of the wiring of the different moving pieces, for instance by providing a service container. In an application built applying ports and adapters, that would be the Configurator.&lt;/p&gt;

&lt;p&gt;It is something we may take for granted, but we must be aware that when not using a framework that provides this type of functionality, we must implement ourselves a mechanism to provide the hexagon with the right adapters for each request.&lt;/p&gt;

&lt;h2&gt;
  
  
  The benefits
&lt;/h2&gt;

&lt;p&gt;With what have covered so far we have achieved significant benefits.&lt;/p&gt;

&lt;p&gt;First, our application may be technology-agnostic. Its communication with the outside is defined via ports, with the adapters taking care of converting each technology quirks to what the port defines, which is what the application understands.&lt;/p&gt;

&lt;p&gt;In practice, the application does not know about the database structure, that's for the database adapter to handle. Or if we get input data from an HTTP request or a CLI command, in JSON or protobuff, from Rabbit or from Kafka.&lt;/p&gt;

&lt;p&gt;Second, with each port acting as entry point (or exit, depending on the port being driver or driven) we can use any number of different adapters. Therefore, our application can be extended just plugging in a new adapter. Pretty much as the strategy pattern.&lt;/p&gt;

&lt;p&gt;And there is a third massive benefit: testing.&lt;/p&gt;

&lt;p&gt;To test our application behavior without the need to have some real technology in place, we can -and certainly must- implement a test adapter that acts as a replacement.&lt;/p&gt;

&lt;p&gt;For the driver ports, we don't need an actual message broker, or to mimic an HTTP request. A test adapter will just call the application sticking to the port contract.&lt;/p&gt;

&lt;p&gt;For the driven ports, we don't need an actual database up and running. We can use faster and simpler in-memory implementations. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F9qd2f082catmenfuk9i8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F9qd2f082catmenfuk9i8.png" alt="Test adapters in Hexagonal Architecture" width="643" height="314"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In fact, the port + test adapter combo allow to move on with the application implementation without worrying about with which technology the integrations will actually happen.&lt;/p&gt;

&lt;p&gt;These decisions can be deferred until the last reasonable moment avoiding attaching ourselves to a certain technology too early, something that could influence further design for the wrong reason&lt;/p&gt;

&lt;p&gt;For instance, we can use in memory persistence adapters without the need to pick a concrete database early on. We design our application without being influenced by the constraints the chosen database has, and once we have further developed our system we can pick the best database for it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Naming ports and adapters
&lt;/h2&gt;

&lt;p&gt;There is no recipe for naming in HA. Alistair Cockburn is a firm proponent of use cases, and his explanations of the pattern point to name ports and adapters in a use case oriented way. However, doing so or not does not change what the pattern solves. And patterns are about solving recurrent problems, not about doing it with a certain wording.&lt;/p&gt;

&lt;p&gt;Alistair would propose to call ports following the naming pattern &lt;code&gt;For[Doing][Something]&lt;/code&gt;. Examples for driver ports: &lt;code&gt;ForPlacingOrders&lt;/code&gt;, &lt;code&gt;ForConfiguringSettings&lt;/code&gt;, etc. For the driven side: &lt;code&gt;ForStoringUsers&lt;/code&gt;, &lt;code&gt;ForNotifyingAlerts&lt;/code&gt;, etc. Which is pretty cool, but sadly not something I've seen in the wild.&lt;/p&gt;

&lt;p&gt;It's more common to find driver ports as &lt;code&gt;PlaceOrder&lt;/code&gt; or &lt;code&gt;ConfigureSettings&lt;/code&gt; and driven as &lt;code&gt;UserRepository&lt;/code&gt; and &lt;code&gt;AlertNotifier&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In the adapter side the trick is to reference the technology we are adapting. We can have &lt;code&gt;CliCommandForPlacingOrders&lt;/code&gt; or &lt;code&gt;MysqlDatabaseForStoringUsers&lt;/code&gt;. If not following Cockburn's naming pattern we could go with &lt;code&gt;PlaceOrderApiController&lt;/code&gt; or &lt;code&gt;RabbitMqAlertNotifier&lt;/code&gt;. There is also this pattern of adding the &lt;code&gt;Using[Technology]&lt;/code&gt; suffix (credits to &lt;a href="https://frankdejonge.nl/" rel="noopener noreferrer"&gt;Frank de Jonge&lt;/a&gt; for this one), resulting in &lt;code&gt;PlaceOrderUsingRestApi&lt;/code&gt; or &lt;code&gt;UserRepositoryUsingPostgreSql&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Find the convention you are comfortable with and be consistent with it. Just mind that the most the naming express the architecture, the better.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is "the application"?
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Edited on 2024-08-02: edited to make it more concise.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;One aspect not usually covered in the literature about HA is what the &lt;em&gt;application&lt;/em&gt; or the &lt;em&gt;hexagon&lt;/em&gt; actually is, which can be frustrating for newcomers. &lt;/p&gt;

&lt;p&gt;The HA application is one element of the pattern. Ports are at its boundary. Therefore, adapters are outside of the application. HA is about isolating the application with the boundaries.&lt;/p&gt;

&lt;p&gt;The application perceived by the external world is the whole system. Including the HA application, the adapters, the configurator, and any other code or files needed for it to run. &lt;/p&gt;

&lt;p&gt;For a system to run we need some tooling that is outside the HA pattern. This is what is called a &lt;em&gt;walking skeleton&lt;/em&gt;: the minimum code in our system that allows to run it. When using a framework, we can consider it our walking skeleton even when it comes with way more built-in features than the minimum needed to run. HA examples simplified for learning purposes may only need a small script as walking skeleton.&lt;/p&gt;

&lt;p&gt;For what is worth, the concept of walking skeleton was coined by... Alistair Cockburn. The software industry indeed owns a lot to him and his work. For deeper reading on the concept I cannot less than recommend the book &lt;a href="https://www.goodreads.com/book/show/4268826-growing-object-oriented-software-guided-by-tests" rel="noopener noreferrer"&gt;Growing Object-Oriented Software, Guided by Tests&lt;/a&gt;, which has a chapter dedicated to it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Request lifecycle in Hexagonal Architecture
&lt;/h2&gt;

&lt;p&gt;Now that we know all the moving parts we can foresee how systems built applying HA work.&lt;/p&gt;

&lt;p&gt;Scenario: the company CRM has created a new client. The business policy when this happens is that we create a user for the client, send an email to notify her, and propagate the user was created so other systems can react to this action. Our application takes care of user creation and exposes a REST API, which is called by the CRM.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fxydi2kbjd6fcuegg9xuj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fxydi2kbjd6fcuegg9xuj.png" alt="A request lifecycle in Hexagonal Architecture" width="800" height="386"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pretty much a standard request for any system, no special complexity here.&lt;/p&gt;

&lt;p&gt;The CRM is the driver external actor. Our application defines the &lt;code&gt;CreateUser&lt;/code&gt; driver port, which has an adapter for the REST API: &lt;code&gt;CreateUserUsingRestAPI&lt;/code&gt;. There is also a driven port &lt;code&gt;UserRepository&lt;/code&gt; for user storage and another one &lt;code&gt;UserCreatedNotifier&lt;/code&gt;. The adapters for them are &lt;code&gt;UserRepositoryUsingPostgres&lt;/code&gt;, &lt;code&gt;UserCreatedNotifierUsingEmail&lt;/code&gt; and &lt;code&gt;UserCreatedNotifierUsingRabbitMQ&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Our application, which is built using our framework of choice, receives the request and detects it's arriving via HTTP. It wires together the adapters inside whatever service we have defined for handling this request and executes it.&lt;/p&gt;

&lt;p&gt;When doing so, the application is not polluted with HTTP request payloads, content types, or headers. The adapter transforms all of that into what the port defines.&lt;/p&gt;

&lt;p&gt;In the driver side, the application knows nothing about the database tables involved in persisting an user, or how the payload of the RabbitMQ messages should be. The ports define they will persist a user and will notify about it being created, and the adapters take care of transforming that application-defined instructions into what each technology requires.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code examples
&lt;/h2&gt;

&lt;p&gt;Before jumping into code, an aspect that cannot be emphasized enough: HA is just about ports and adapters.&lt;/p&gt;

&lt;p&gt;It dictates nothing about how the application should be organized internally. There is no recipe for the number of layers our application should have, not even if it should have layers at all.&lt;/p&gt;

&lt;p&gt;Command buses and handlers, DDD patterns, onions and upper case Clean Architectures, big balls of mud, etc. are all valid ways of implementing the internals of an application which applies Hexagonal Architecture. But there is no requirement or guideline dictated by the pattern on how it should be done.&lt;/p&gt;

&lt;p&gt;Therefore, the following examples should be taken as ways of illustrating how ports and adapters work together. Not as the right way™️ to &lt;em&gt;be hexagonal&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Now, the ports for our "create user" use case could look like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Since the writing of the original post I've come to realize that this first code example is not accurate. Driver adapters &lt;em&gt;use&lt;/em&gt; the application and this example proposes the application to use them. Although we would get the same benefits, the second code example is the one actually applying Hexagonal Architecture.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface CreateUser {
    buildRequest(): CreateUser;
}

interface UserRepository {
    add(User user): void;
}

interface UserCreatedNotifier {
    notify(UserCreated event): void;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The adapters would be implementations for those interfaces using the different technologies suggested by their name.&lt;/p&gt;

&lt;p&gt;Our application (in terms of HA) has a service to create the users, which gets as dependencies the ports involved in the use case:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class CreateUserHandler {
    private CreateUser createUser;
    private UserRepository userRepository; 
    private array&amp;lt;UserCreatedNotifier&amp;gt; notifiers;

    fn handle(): void
    {
        var request createUser.buildRequest();
        var user = new User(request.email(), request.password());
        userRepository.add(user);
        notifiers.each(x =&amp;gt; x.notify(new UserCreated(user.email())));
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our framework is configured to inject the right implementations -the adapters- for the current request and to call the &lt;code&gt;handle&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;We can notice how using test adapters we could test the business logic of our handler without dependencies to actual infrastructure services: a &lt;code&gt;TestCreateUser&lt;/code&gt; could provide baked test values, a &lt;code&gt;InMemoryUserRepository&lt;/code&gt; would not need any underlying database system running, etc.&lt;/p&gt;

&lt;p&gt;A different approach is when driver ports are not defined as interfaces, but as data structures the adapters must provide to the application.&lt;/p&gt;

&lt;p&gt;Frameworks are good identifying the technologies used by driver actors, and we delegate to them invoking the right adapter. The adapter will pass the request contract to the application. This approach offers the same benefits as the driver-port-as-interface, delegating to the built-in tools of the framework the driver adapters' implementation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# replaces the interface
class CreateUser {
    public readonly string email;
    public readonly string password;
}

# the adapter is a framework controller
class CreateUserController {

    private CreateUserHandler handler;

    fn createUser(HttpRequest request) {
        handler.handle(
            new CreateUser(
                request.payload.get('email'),
                request.payload.get('password')
            )
        );
    }
}

# the application no longer expects the port as dependency, but as a parameter
class CreateUserHandler {
    private UserRepository userRepository; 
    private array&amp;lt;UserCreatedNotifier&amp;gt; notifiers;

    fn handle(CreateUser request): void
    {
        var user = new User(request.email(), request.password());
        userRepository.add(user);
        notifiers.each(x =&amp;gt; x.notify(new UserCreated(user.email())));
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  When and when not
&lt;/h2&gt;

&lt;p&gt;Patterns define well proved ways of solving common problems. The problem HA tackles is the difficulty to maintain, test, and evolve applications when they are too coupled to concrete technologies. But "too coupled" is a very contextual and subjective measure. What is valid for one team or project might not be for others.&lt;/p&gt;

&lt;p&gt;Furthermore, context changes over time. What is a reasonable decision today may not be so tomorrow.&lt;/p&gt;

&lt;p&gt;My personal take is that HA is actually so simple and the overload it implies so small, that it is the default approach I would use for any greenfield project. It just feels natural to abstract away the technical details using ports. Remember: HA is just ports and adapters, it does not necessarily imply DDD, buses, presenters, etc.&lt;/p&gt;

&lt;p&gt;However, there are contextual factors that might justify not going with this pattern. The effort to move existing applications to HA may not be worth if the application is not expected to be extended and already has good test coverage. In a more social aspect of it, for teams of hardcore-framework developers (which is a legit standpoint) the switch to an architecture that pushes the framework away from the application core could cause a lot of friction, which might not compensate the expected benefits.&lt;/p&gt;

&lt;p&gt;As always, no magic recipes. The advice would be to try it, explore it enough to understand what it gives and takes, and choose it when it fits.&lt;/p&gt;

&lt;h2&gt;
  
  
  Concluding
&lt;/h2&gt;

&lt;p&gt;Hopefully this post has been useful to get to know the Hexagonal Architecture pattern. Maybe there is a degree of frustration because how high level it actually is. We devs (humans!) tend to look for guided solutions to apply without much thinking, and HA is quite lax in those terms. It's more a set of guidelines to avoid creepy scenarios than any guided way of building applications.&lt;/p&gt;

&lt;p&gt;For less abstract guidelines there are other patterns that will put us more "on rails". HA just don't mind if you use these other patters or not. It only cares of protecting the boundaries of your application.&lt;/p&gt;

&lt;p&gt;In following posts we will cover possible ways of designing the internals of our application while sticking to HA. With a bit of luck they won't take as long as this one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Credits
&lt;/h2&gt;

&lt;p&gt;For the diagrams I've used &lt;a href="https://excalidraw.com/" rel="noopener noreferrer"&gt;Excalidraw&lt;/a&gt;, borrowing libraries from &lt;a href="https://libraries.excalidraw.com/?target=_excalidraw&amp;amp;referrer=https%3A%2F%2Fexcalidraw.com%2F&amp;amp;useHash=true&amp;amp;token=ilQVFmSp5QMlA0FVrZjQ0&amp;amp;theme=light&amp;amp;version=2&amp;amp;sort=default#youritjang-software-architecture" rel="noopener noreferrer"&gt;Youri Tjang&lt;/a&gt;, &lt;a href="https://libraries.excalidraw.com/?target=_excalidraw&amp;amp;referrer=https%3A%2F%2Fexcalidraw.com%2F&amp;amp;useHash=true&amp;amp;token=ilQVFmSp5QMlA0FVrZjQ0&amp;amp;theme=light&amp;amp;version=2&amp;amp;sort=default#drwnio-drwnio" rel="noopener noreferrer"&gt;Drwn.io&lt;/a&gt;, &lt;a href="https://libraries.excalidraw.com/?target=_excalidraw&amp;amp;referrer=https%3A%2F%2Fexcalidraw.com%2F&amp;amp;useHash=true&amp;amp;token=ilQVFmSp5QMlA0FVrZjQ0&amp;amp;theme=light&amp;amp;version=2&amp;amp;sort=default#dwelle-network-topology-icons" rel="noopener noreferrer"&gt;David Luzar&lt;/a&gt; and &lt;a href="https://libraries.excalidraw.com/?target=_excalidraw&amp;amp;referrer=https%3A%2F%2Fexcalidraw.com%2F&amp;amp;useHash=true&amp;amp;token=ilQVFmSp5QMlA0FVrZjQ0&amp;amp;theme=light&amp;amp;version=2&amp;amp;sort=default#claracavalcante-baby-characters" rel="noopener noreferrer"&gt;Ana Clara Cavalcante&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The cover picture is from Penny Richards, distributed under the Creative Commons license. It can be found &lt;a href="https://commons.wikimedia.org/wiki/File:CrochetHexagonsRainbow.png" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>hexagonal</category>
      <category>patterns</category>
      <category>cleancode</category>
    </item>
    <item>
      <title>What is (not) Hexagonal Architecture</title>
      <dc:creator>Carlos Gándara</dc:creator>
      <pubDate>Tue, 01 Nov 2022 10:16:44 +0000</pubDate>
      <link>https://dev.to/xoubaman/what-is-not-hexagonal-architecture-1kh7</link>
      <guid>https://dev.to/xoubaman/what-is-not-hexagonal-architecture-1kh7</guid>
      <description>&lt;p&gt;Hexagonal Architecture (HA) is one of those "buzzwords" we hear a lot in the development world. This post tries to explain a bit what is it about and, more important, what it is not. Don't expect a thorough tour over the pattern here, but a short introduction and a reflection over what floats around it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mmmm... so what is Hexagonal Architecture?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It is an architectural pattern coined by &lt;a href="https://twitter.com/TotherAlistair" rel="noopener noreferrer"&gt;Dr. Alistair Cockburn&lt;/a&gt; in 2005. It promotes the separation of an application internals from its interactions with the external world.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;And what is not?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Many things. Probably they will appear sooner or later in this fictional conversation. In fact, as the author, I'm pretty sure they will appear :D&lt;/p&gt;

&lt;p&gt;For now, I can tell you it's a term that has been corrupted as many others in the industry, like Devops, Microservices,or Agile. Although the term Hexagonal Architecture has been less bastardized than these other examples, there is plenty of fantasy around it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How the pattern works?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We have our application, represented as an hexagon. Outside the hexagon there are the external actors: users interacting with a graphical interface, messaging systems, databases, vendor APIs, etc.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Edited on 2024-08-02: The following paragraph was incorrectly stating that adapters are implementations of the ports, which is only half true. It has been fixed. For more details, take a look &lt;a href="https://dev.to/xoubaman/understanding-hexagonal-architecture-3gk"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The application defines the ways for it to interact with external actors. Each of these contracts is a port. Ports are expressed in application language, like parts of a use case. Adapters are the connections of the external actors with the application using a port. They are interchangeable ways of interacting with the application using different technologies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where is the value?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;HA facilitates easier to understand, easier to test, and easier to extend applications.&lt;/p&gt;

&lt;p&gt;The isolation of the application from the outside world using ports means the application is not "polluted" with the details of external actors, reducing the cognitive load needed to understand the application logic.&lt;/p&gt;

&lt;p&gt;The interchangeability of the adapters allows to have a test adapter for each port which can be used as replacement of the real actor, instead of forcing us to spin up the real stuff to test our application. Specially handy when the actor is a human being.&lt;/p&gt;

&lt;p&gt;The combo of a port defining the interaction contract plus its multiple possible adapters allows to plug-in new technologies without having to modify the application. A new adapter for the new technology will do the trick.&lt;/p&gt;

&lt;p&gt;All those three benefits are potential, though. HA is not a recipe to guarantee we don't produce a mess. But for sure the chances to do so are drastically reduced.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why an hexagon?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The hexagon has no special meaning. It was just convenient when Cockburn came up with the pattern: easy to draw, easy to showcase the pattern, and not already taken for another recognizable diagram out there. Actually, after some time he realized a better name would be ports and adapters, but by then the hexagonal was too rooted in the community.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Should I use Hexagonal Architecture in all my applications?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There are very few universal things in software development, and no pattern is any of them. HA has its usages and they are wide, but it's not a good solution for every single case. The context of each application will determine if going hexagonal is the right approach. The benefits it provides can be irrelevant in some cases, not only for the nature of the application but also for its contextual circumstances: fixed lifetimes, tooling already in place, social aspects of the team, etc.&lt;/p&gt;

&lt;p&gt;The pattern shines the more in the situations where many entry points for the same use case exist, which fits with most of the modern enterprise applications. Even when there are not those many entry points, the ability to use test adapters can be beneficial enough to justify applying it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How should I arrange my code to follow Hexagonal Architecture?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Arrange it in any way you want, as long as the interactions with the external actors are done through an API defined by the application (a port).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But is not this a Clean Architecture? Should not HA tell me where to put my stuff?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Nope. HA indeed serves as an excellent base for clean architectures (note the small letters), and indeed &lt;strong&gt;is&lt;/strong&gt; the base for the &lt;a href="https://www.goodreads.com/book/show/18043011-clean-architecture" rel="noopener noreferrer"&gt;Clean Architecture&lt;/a&gt; (note the capital letters), understood as the "brand" commercialized by Robert C. Martin. But they are not the same, since Clean Architecture is an opinionated implementation of HA. The same applies for the &lt;a href="https://jeffreypalermo.com/2008/07/the-onion-architecture-part-1/" rel="noopener noreferrer"&gt;Onion Architecture&lt;/a&gt;, the other popular superset of HA.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Really? And all this stuff about layers and command buses the people that does Hexagonal Architecture uses?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That's one popular way of implementing what is inside (and outside!) the hexagon, but the pattern does not enforce or forbid any of it. It just says to put a port in the application boundary when it has to interact with some external actor.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;And what about Domain-Driven Design?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It's another misconception that DDD equals HA, or that one cannot exist without the other. Certainly HA is an excellent support for some of the DDD practices and patterns, but you can perfectly make use of any of them separately. Same for CQRS and Event Sourcing, in case you were about to ask about them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I'm kinda disappointed...&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Be not. Hexagonal Architecture is a powerful pattern, don't be fooled by its simplicity. As many other brilliant things, it's simple in the surface but has a fascinating depth.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I really was expecting something more concrete I could apply&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That's normal. We developers like recipes we can directly use to solve our problems. It's natural that we try to narrow what gives us too much freedom into something tangible we can execute "on rails". We want solutions and we want them fast. Since HA is really lax in this sense, we have convinced ourselves that it is another different thing which guides us more strictly.&lt;/p&gt;

&lt;p&gt;Worth to say that all these things that are usually mixed up with Hexagonal Architecture are not less valuable because they are not exactly Hexagonal Architecture.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is the point of this post, then?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I was hoping that clarifying some of the myths around HA could help to understand that the complexity usually associated to it is actually part of other patterns and techniques that may or may not rely on HA.&lt;/p&gt;

&lt;p&gt;We should be aware that we should not discard the benefits HA provides because we are forced to deal with this complexity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Interesting. I'm intrigued now about this pure HA vs adorned HA&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Curious way of putting it. Anyway, in following posts I will try to dig more in both.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Looking forward to it!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>hexagonal</category>
      <category>cleancode</category>
      <category>pattern</category>
    </item>
    <item>
      <title>Kitchen clocks, health and productivity: the Pomodoro Technique</title>
      <dc:creator>Carlos Gándara</dc:creator>
      <pubDate>Sun, 30 Jan 2022 19:27:28 +0000</pubDate>
      <link>https://dev.to/xoubaman/kitchen-clocks-health-and-productivity-the-pomodoro-technique-1170</link>
      <guid>https://dev.to/xoubaman/kitchen-clocks-health-and-productivity-the-pomodoro-technique-1170</guid>
      <description>&lt;p&gt;&lt;em&gt;&lt;a href="https://bgfons.com/download/5184" rel="noopener noreferrer"&gt;Cover image&lt;/a&gt; taken from &lt;a href="https://bgfons.com" rel="noopener noreferrer"&gt;https://bgfons.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The Pomodoro Technique is a time management technique. Using it when developing may positively impact not only our productivity, but also our health.&lt;/p&gt;

&lt;p&gt;Here we will cover its basics and some tips on how to use it in the context of software development.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Pomodoro Technique
&lt;/h2&gt;

&lt;p&gt;The technique has a number of steps to organize our activities, any of them. For the whole day. It focuses on maximizing the use of our mind without the burden of a complicated framework. It is fairly simple. Not easy at all, but simple.&lt;/p&gt;

&lt;p&gt;I encourage you to fully &lt;a href="http://friend.ucsd.edu/reasonableexpectations/downloads/Cirillo%20--%20Pomodoro%20Technique.pdf" rel="noopener noreferrer"&gt;read it&lt;/a&gt;. Then, as it should be with any tool, embrace it all or skip what does not work for you knowing why every piece is there and the consequences of dropping them.&lt;/p&gt;

&lt;p&gt;In this post the focus will be in the execution part as it is what I think has the most impact when coding.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using Pomodoros
&lt;/h2&gt;

&lt;p&gt;Premises:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Distractions are a productivity killer.&lt;/li&gt;
&lt;li&gt;Our brain works way better if we give it some rest from time to time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are not empty claims, they are backed scientifically [&lt;a href="https://www.sciencedaily.com/releases/2011/02/110208131529.htm" rel="noopener noreferrer"&gt;1&lt;/a&gt;][&lt;a href="https://blog.rescuetime.com/context-switching/" rel="noopener noreferrer"&gt;2&lt;/a&gt;].&lt;/p&gt;

&lt;p&gt;The Pomodoro Technique proposes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Working in time-boxed periods during which we should keep the focus in what we are doing, avoiding distractions.&lt;/li&gt;
&lt;li&gt;Taking small breaks between each of these periods giving some room to our brain to process whatever we are doing.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Going more into details, the "canonical" Pomodoro execution is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Work in periods of 25 minutes, which is called a Pomodoro.&lt;/li&gt;
&lt;li&gt;After each Pomodoro, take a 5 minute break.&lt;/li&gt;
&lt;li&gt;After the fourth Pomodoro in a row, take a longer break of 10-20 minutes.&lt;/li&gt;
&lt;li&gt;Start over.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Usually the summaries of the technique stop here, which in my opinion misses the point. Actually, the time-frames are not that important and can be adjusted to fit the activity or individual taste. Just "doing Pomodoros" brings marginal results compared to consciously take into account the premises mentioned before.&lt;/p&gt;

&lt;p&gt;What we must pay attention to is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;During a Pomodoro, focus 100% in the task at hand, discarding distractions.&lt;/li&gt;
&lt;li&gt;During a break don't do anything demanding for your brain. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These two points deserve way more attention that the concrete amounts of time per Pomodoro.&lt;/p&gt;

&lt;h2&gt;
  
  
  The distractions
&lt;/h2&gt;

&lt;p&gt;A distraction means we will try to do two things at the same time and losing the focus because of the context switching.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://www.scienceabc.com/humans/can-humans-actually-multitask.html" rel="noopener noreferrer"&gt;human brain is bad at multitasking&lt;/a&gt;. Actually, it is not able to do so. Instead it fakes it switching between tasks very fast, not doing them in parallel.&lt;/p&gt;

&lt;p&gt;In the other hand, if we are in the zone and we get distracted, it will take us &lt;a href="https://www.npr.org/2015/09/22/442582422/the-cost-of-interruptions-they-waste-more-time-than-you-think?t=1643449417881" rel="noopener noreferrer"&gt;more than 20 minutes&lt;/a&gt; to get to the previous level of concentration. Yes, this means our days are a dramatic waste of energy.&lt;/p&gt;

&lt;p&gt;Half of the The Pomodoro Technique is about removing distractions. Both the &lt;em&gt;external&lt;/em&gt; ones that come to us (chat messages, incoming email pop-ups, somebody jumping in with a question,...) and the &lt;em&gt;internal&lt;/em&gt; ones that we do to ourselves (like thinking on what to have for dinner while doing a refactor).&lt;/p&gt;

&lt;p&gt;The number of internal distractions we inadvertently do to ourselves is insane. The technique suggests, pen and paper nearby, to take a note every time we found we are being self-distracted. A simple scratch will suffice, it is about the amount not about the details. Once we have this graphic visualization of them it is easier to start to avoid doing so many.&lt;/p&gt;

&lt;p&gt;About external distractions, the strategy is to delay them as much as possible. It is very unlikely something cannot wait a max of 25 minutes. Most probably it can wait hours or even days. Every time something "urgent" appears, learn to kindly reply you will check it in some minutes, or ask how long it could wait. Take a note about what you committed to tackle later and group these tasks together in dedicated Pomodoros.&lt;/p&gt;

&lt;p&gt;The result of those two simple moves are more productive Pomodoros: distractions and context switching are reduced and the external requests have our full dedication as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  The breaks
&lt;/h2&gt;

&lt;p&gt;Breaks are for giving some rest to our brain. Not to answer emails, doomscrolling over social media or review the last messages in  the company chat (including the channel #puppies).&lt;/p&gt;

&lt;p&gt;During a break do something not mentally demanding. Go make a tea, stare through a window, walk a bit. Do nothing at all. Allow your brain to organize itself after these past 25 minutes on full focus (this is called &lt;a href="https://www.verywellmind.com/what-is-assimilation-2794821" rel="noopener noreferrer"&gt;assimilation&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;It is refreshing, we will be less tired, and getting back into the zone for the next Pomodoro will happen effortlessly.&lt;/p&gt;

&lt;p&gt;If otherwise we spend the break time doing something our brain pays attention to, the result will be a harder and longer time to be concentrated again and an increasing tiresomeness.&lt;/p&gt;

&lt;p&gt;For the longer break every four Pomodoros consider even going for short walk. If we are able to disconnect from what we were doing it will still be easy to catch up and we will be increasing the odds of an &lt;em&gt;aha moment&lt;/em&gt; because of the time we give our brain to accommodate and assimilate.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pomodoros in the developer life
&lt;/h2&gt;

&lt;p&gt;Coding is a intellectual activity, demanding to our brain and that pushes to a sedentary lifestyle. Pomodoros may help with all of that. Its structure can be used in our advantage to mitigate many of the problems associated with the life as a developer.&lt;/p&gt;

&lt;p&gt;We are used to deal with all sorts of instant notifications. Re-evaluate the need of getting a pop-up alert every time you get an email or a new chat message. Mute all channels you can. Those are distractions that will impact your focus during a Pomodoro. Establish a routine to read them in batches and delay everything that can be delayed.&lt;/p&gt;

&lt;p&gt;Coding is usually done seating, resulting in long periods of time in the same position. Use the breaks to get up. Walk a bit. Do some stretching.&lt;/p&gt;

&lt;p&gt;Most likely we are staring to screens when coding. Continuously focusing at the same distance is pernicious for the eyes as well. During breaks we can apply &lt;a href="https://en.wikipedia.org/wiki/Computer_vision_syndrome" rel="noopener noreferrer"&gt;the 20-20-220 rule&lt;/a&gt; looking through a window to something far away to force our eyes to refocus.&lt;/p&gt;

&lt;p&gt;Finally, working from home is quite a thing nowadays. Doing otherwise ungrateful housework tasks are good candidates for the breaks. They are done by muscle memory and do not require mental effort, giving the needed space to our brain to rearrange. This is a win-win: convenient Pomodoro breaks and the dishwasher emptied.&lt;/p&gt;

&lt;h2&gt;
  
  
  Concluding
&lt;/h2&gt;

&lt;p&gt;We did a shallow review of what the Pomodoro technique is, putting the view in what I think is the most relevant, and often forgotten, aspect of it. Again, I recommend fully reading the manual to have a better view of the whats and the whys.&lt;/p&gt;

&lt;p&gt;Applying it correctly is not easy and generates some friction at the beginning, because it impacts in so many points of our usual day. I've being using it for years and now and then I fail to stick to the technique. Those days usually end up in worse mood than they should, because the waste of productivity becomes patent.&lt;/p&gt;

&lt;p&gt;To conclude, some well deserved trivia:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Pomodoro Technique was created by Francesco Cirillo in 1980.&lt;/li&gt;
&lt;li&gt;Pomodoro is the Italian word for tomato.&lt;/li&gt;
&lt;li&gt;The name comes from these kitchen clocks used to track the time when cooking stuff. Cirillo used them to time-box his Pomodoros.&lt;/li&gt;
&lt;li&gt;Here is &lt;a href="https://francescocirillo.com/pages/pomodoro-technique" rel="noopener noreferrer"&gt;official website&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Give it a try and don't hesitate to comment with your experience.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>health</category>
    </item>
    <item>
      <title>Given-When-Then tests</title>
      <dc:creator>Carlos Gándara</dc:creator>
      <pubDate>Mon, 27 Dec 2021 20:29:53 +0000</pubDate>
      <link>https://dev.to/xoubaman/given-when-then-tests-43ee</link>
      <guid>https://dev.to/xoubaman/given-when-then-tests-43ee</guid>
      <description>&lt;p&gt;Consider this test written in the "traditional" format in a test framework of the &lt;em&gt;&lt;a href="https://en.wikipedia.org/wiki/XUnit" rel="noopener noreferrer"&gt;xUnit&lt;/a&gt;&lt;/em&gt; family:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cd"&gt;/** @test */&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;calculatesOrderCost&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$itemA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Item&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;withPrice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nv"&gt;$itemB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Item&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;withPrice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nv"&gt;$shippingCost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ShippingCost&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;asPercentage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nv"&gt;$order&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;Order&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nv"&gt;$order&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;addItems&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$itemA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$itemB&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nv"&gt;$order&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;applyShippingCost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$shippingCost&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;assertEquals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;88&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$order&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;totalCost&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;In this post we will analyze the benefits of using the GWT format instead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cd"&gt;/** @test */&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;calculatesOrderCost&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&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="nf"&gt;givenAnItemWithPrice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&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="nf"&gt;andAnItemWithPrice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;60&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="nf"&gt;andAShippingCostOfPercent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&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="nf"&gt;whenOrderIsCreated&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="nf"&gt;thenTotalOrderCostIs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;88&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;h2&gt;
  
  
  What is GWT
&lt;/h2&gt;

&lt;p&gt;Basically what happened is that we moved the different parts of the test to dedicated methods of any of the GWT types:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;G&lt;/strong&gt;iven, meaning the state of the system required to execute the code under test.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;W&lt;/strong&gt;hen, meaning the execution of the code under test.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;T&lt;/strong&gt;hen, meaning what is the expected output after executing the code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Since each of these blocks is very likely to have more than one step, each of the blocks can include &lt;em&gt;And&lt;/em&gt; methods as shown in the example.&lt;/p&gt;

&lt;p&gt;GWT comes from BDD (&lt;strong&gt;B&lt;/strong&gt;ehavior &lt;strong&gt;D&lt;/strong&gt;riven &lt;strong&gt;D&lt;/strong&gt;evelopment), an approach to testing coined by &lt;a href="https://dannorth.net/introducing-bdd/" rel="noopener noreferrer"&gt;Dan North&lt;/a&gt; with a focus on behaviour, which in turn has lead to the creation of dedicated test frameworks (such as Cucumber, Behat or SpecFlow). In BDD, using GWT is the basis to write the test scenarios, whilst in &lt;em&gt;xUnit&lt;/em&gt; frameworks is not that common to see this format and certainly more cumbersome to do. They're frameworks were not written with GWT in mind. However, using GWT there provides noticeable benefits as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  The benefits
&lt;/h2&gt;

&lt;p&gt;What we achieve with the GWT format is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Better readability&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Making the tests resemble human readable descriptions of what our application does moves them towards the desirable state where our tests are "living documentation". They reflect what the system does and they will change along with the system when required, making them always up to date documentation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Reduce the cognitive load&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To get what's going on in the test we can read each step of it without the visual noise produced for the code required to implement it. The example is pretty naive for simplicity purposes, but we can easily imagine &lt;code&gt;Item&lt;/code&gt; or &lt;code&gt;Order&lt;/code&gt; would require a lot more parameters to be instantiated while we only care about the ones involving the cost in this case.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Verify the behavior of the system under test instead of its implementation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Testing the implementation instead of behavior &lt;a href="https://dev.to/xoubaman/writing-better-tests-4apd"&gt;is not desirable&lt;/a&gt;. It makes our tests and production code less prepared for refactoring and change. Because in GWT we describe what the system does, the test is less prone to fall in the trap of being coupled with the implementation.&lt;/p&gt;

&lt;p&gt;It is important to note that GWT does not guarantee any of the above benefits, neither it means they cannot be achieved using another approach or other techniques. It &lt;em&gt;just&lt;/em&gt; makes them easier to accomplish.&lt;/p&gt;

&lt;h2&gt;
  
  
  Trade-offs and considerations
&lt;/h2&gt;

&lt;p&gt;There are few things in software development that have no trade-off included, and BDD and GWT tests are not an exception.&lt;/p&gt;

&lt;p&gt;BDD frameworks rely on Gherkin language to define the steps of a test in a separate feature file, and using regular expressions find the matching method implementation. For instance &lt;code&gt;Given '1' items with price '80' euro*&lt;/code&gt; will be matched with a method &lt;code&gt;givenItemsWithPrice(int $amount, int $price)&lt;/code&gt;. &lt;em&gt;xUnit&lt;/em&gt; frameworks are not prepared for this type of pattern matching and the methods in GWT tests do not read as good as the pure BDD counterparts. In our &lt;em&gt;xUnit&lt;/em&gt; tests we will have just the method implementation, not the more readable feature file.&lt;/p&gt;

&lt;p&gt;Another aspect to consider is that when using GWT everything is encapsulated in separate methods and tests tend to store stuff in class properties to use them later on. This means tests may have more properties and state than what we may be used to, with later methods relying on properties set by prior ones. Sometimes this may produce null pointer exceptions and tests that are harder to follow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cd"&gt;/** @test **/&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;shipingToAddress&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&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="nf"&gt;givenAnAddress&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="nf"&gt;whenOrderIsShipped&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="nf"&gt;thenPackageIsSent&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;givenAnAddress&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// We need an address property&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;address&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;Address&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'sesame street'&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;whenOrderIsShipped&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$shippingService&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;ShippingService&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="c1"&gt;// This method relies on an address previously set, producing a confusing error when it is not&lt;/span&gt;
    &lt;span class="nv"&gt;$shippingService&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;shipTo&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;address&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;Finally, GWT tests work better when we are testing code involving business rules. When testing classes more related to infrastructure, utilities, data manipulation,... GWT does not work that well and result in cumbersome tests that feel forced:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cd"&gt;/** @test **/&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;sanitizeTextGWT&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&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="nf"&gt;givenATextWithAccents&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="nf"&gt;whenSanitizingTheText&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="nf"&gt;thenAccentsAreRemoved&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="cd"&gt;/** @test **/&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;sanitizeText&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Maybe GWT does not provide much value compared to this&lt;/span&gt;
    &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;assertEquals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'aa'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Sanitizer&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;sanitize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&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;As with every tool, the point is to use the it to solve our problems, not to bend the problems to force them into it. &lt;/p&gt;

&lt;h2&gt;
  
  
  Tips and tricks
&lt;/h2&gt;

&lt;p&gt;Here are some techniques and soft rules that I found give good results when using the GWT approach in &lt;em&gt;xUnit&lt;/em&gt; tests.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do not use And&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Using &lt;em&gt;and&lt;/em&gt; at the beginning of a method reads pretty well when we write our first tests, but could lead to weird situations when a test needs the steps starting with &lt;em&gt;and&lt;/em&gt; but none of the ones starting with &lt;em&gt;Given&lt;/em&gt;, &lt;em&gt;When&lt;/em&gt; or &lt;em&gt;Then&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cd"&gt;/** @test */&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;carReactsToAdverseWeather&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&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="nf"&gt;givenThereIsMist&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// In this test rain is relevant&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;andItIsRaining&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// So this reads nice&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;whenWeatherIsScanned&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="nf"&gt;thenMistLightsAreTurnOn&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="nf"&gt;andDriveAssitanceOnWetRoadIsTurnOn&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="cd"&gt;/** @test */&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;carReactsToNotSoAdverseWeather&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&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="nf"&gt;andItIsRaining&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// We don't care about the mist ant it reads weird &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;whenWeatherIsScanned&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="nf"&gt;andDriveAssitanceOnWetRoadIsTurnOn&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Same here&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead, avoid &lt;em&gt;and&lt;/em&gt; prefix and use always &lt;em&gt;given&lt;/em&gt;, &lt;em&gt;when&lt;/em&gt; or &lt;em&gt;then&lt;/em&gt;. It won't read as good as with &lt;em&gt;and&lt;/em&gt;, but the benefit is greater than the loss.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cd"&gt;/** @test */&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;carReactsToAdverseWeather&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&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="nf"&gt;givenThereIsMist&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="nf"&gt;givenItIsRaining&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="nf"&gt;whenWeatherIsScanned&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="nf"&gt;thenMistLightsAreTurnOn&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="nf"&gt;thenDriveAssitanceOnWetRoadIsTurnOn&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;&lt;strong&gt;Test error cases catching exceptions into a property&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;xUnit&lt;/em&gt; frameworks provide a fancy way of dealing with exceptions when throwing them is the expected behavior. However, it does not fit well in GWT because it would break the test structure or produce "technical sentences" in a otherwise human-readable test. A way of avoiding that is to use a try-catch inside the &lt;em&gt;When&lt;/em&gt; method saving the exception in a property for a later, more meaningful assertion:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cd"&gt;/** @test **/&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;shipingToAddress&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&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="nf"&gt;givenAnAddress&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="nf"&gt;givenClientHasNoFunds&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="nf"&gt;whenOrderIsShipped&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="nf"&gt;thenOrderFailedDuetoNoPayment&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;whenOrderIsShipped&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&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;shippingService&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;ship&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="nv"&gt;$ex&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;exceptionWhenShippingOrder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$ex&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;private&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;thenOrderFailedDuetoNoPayment&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;assertInstanceOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;NoPaymentException&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;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;exceptionWhenShippingOrder&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;&lt;strong&gt;Reduce the number of properties with return values and method parameters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The body of a GWT is composed of a bunch of methods, one after the other. If we do just that, we will be forced to use lots of properties to hold the values generated in by &lt;em&gt;Given&lt;/em&gt; methods to use them in the following steps. This may hurt the readability of tests and makes them harder to follow because we cannot notice it unless we go into each of the methods, it is not visible explicitly in the test body.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cd"&gt;/** @test */&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;calculatesOrderCost&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&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="nf"&gt;givenAnItemWithPrice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Requires storing a property for the item&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;givenAnItemWithPrice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Another property&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;andAShippingCostOfPercent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Another property&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;whenOrderIsCreated&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Will use the previously set properties&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;thenTotalOrderCostIs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;88&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;But our methods can return stuff and accept parameters, and we can avoid overuse of properties playing with that (which is actually an advantage compared to BDD frameworks).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cd"&gt;/** @test */&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;calculatesOrderCost&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$oneItem&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="nf"&gt;givenAnItemWithPrice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nv"&gt;$anotherItem&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="nf"&gt;givenAnItemWithPrice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nv"&gt;$shippingCost&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="nf"&gt;andAShippingCostOfPercent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&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="nf"&gt;whenOrderIsCreated&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$shippingCost&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$oneItem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$anotherItem&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="nf"&gt;thenTotalOrderCostIs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;88&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;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Writing tests in GWT form could result in more valuable tests, because it makes easier to describe the behavior of the system and it kinda enforce us to write our tests &lt;em&gt;the right way&lt;/em&gt; ™️. Give it a try to check how well it fits with you code style, always taking into account that, as like any other tool, it comes with a number of benefits but also trade-offs.&lt;/p&gt;

&lt;p&gt;Hopefully this post has spark some curiosity. Let me know in the comments :)&lt;/p&gt;

&lt;p&gt;PS: because I could not figure out something adequate as cover image, I've just randomly used a pic of one of the most mesmerizing animals out there, a Red Panda.&lt;/p&gt;

</description>
      <category>testing</category>
      <category>bdd</category>
      <category>php</category>
    </item>
    <item>
      <title>Refactoring with baby steps</title>
      <dc:creator>Carlos Gándara</dc:creator>
      <pubDate>Sun, 09 May 2021 15:37:42 +0000</pubDate>
      <link>https://dev.to/xoubaman/refactoring-with-baby-steps-3mgg</link>
      <guid>https://dev.to/xoubaman/refactoring-with-baby-steps-3mgg</guid>
      <description>&lt;p&gt;In &lt;a href="https://dev.to/xoubaman/a-mockumentary-about-value-objects-3ad8"&gt;a previous post&lt;/a&gt; we introduced the blessings Value Objects grant to our code. However, if we are not using them since the beginning we might ponder if it is worth messing up our whole codebase to introduce VOs. I can tell you it is totally worth it.&lt;/p&gt;

&lt;p&gt;However, it is not that simple to introduce VOs (or any other change for that matter) into an existing codebase. In this post, we will see how to safely do it applying refactor techniques in small steps.&lt;/p&gt;

&lt;p&gt;All the code changes presented here, and more, are published in &lt;a href="https://github.com/xoubaman/refactoring-with-baby-steps" rel="noopener noreferrer"&gt;this Github repository&lt;/a&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  Precondition: test coverage
&lt;/h2&gt;

&lt;p&gt;First things first, no matter the kind of change we want to introduce we need to be sure that we are not breaking our current code. The way of assuring it is through tests. Depending on the test coverage we have and its quality, on average we can face one of these three scenarios:&lt;/p&gt;

&lt;p&gt;A) We have decent tests that cover the &lt;strong&gt;behavior&lt;/strong&gt; of the code we want to change.&lt;br&gt;
B) We have tests but they are &lt;strong&gt;coupled to the implementation&lt;/strong&gt; of the code.&lt;br&gt;
C) There are &lt;strong&gt;no tests&lt;/strong&gt; at all.&lt;/p&gt;

&lt;p&gt;If we are in scenario C, the first step to take is writing the tests. Ideally, the ones that put us in scenario A.  &lt;/p&gt;

&lt;p&gt;If we already have tests we can be in scenario A, which is a cozy environment for refactor and the code can be changed with little to no changes in tests. If we are in scenario B we will probably need a good deal of changes in the tests.&lt;/p&gt;

&lt;p&gt;Introducing Value Objects can be considered a soft change in terms of impact on the component being modified. Value Objects apply when passing data around or operating with it. They don't substitute complex dependencies (e.g. accessing the database). We should expect a reduced amount of changes in the tests when introducing them, but that's highly dependant on the codebase we are dealing with.&lt;/p&gt;
&lt;h2&gt;
  
  
  The process
&lt;/h2&gt;

&lt;p&gt;Refactoring in baby steps means we take small and safe steps, one at a time. Like babies do.&lt;/p&gt;

&lt;p&gt;We will start in a green state (the tests are passing), and we will introduce one single change and run the tests. This change will be the smallest possible we can figure out that moves us in the direction of what we want to achieve. Sometimes they will mean a "step back" in terms of code quality, like introducing duplication, optional parameters, weird method naming, etc. But that's ok because those are temporal intermediate states until we reach our refactor purpose.&lt;/p&gt;

&lt;p&gt;After any change, if the tests are still green we happily proceed to introduce the next change. If the tests become red, we will know exactly which change caused it. Either we undo it and start over from the last green state, which will be only one change away, or we identify the reason for the error and correct it. &lt;/p&gt;

&lt;p&gt;Most of the time the smallest possible change is not bigger than a single line. Identifying the reason for a red in the tests becomes quite easy because the amount of code directly affected is small. When we modify larger chunks of code it is more likely we would not know where we introduced an error and we would invest more time, on average, to figure it out. &lt;/p&gt;
&lt;h2&gt;
  
  
  Should I apply baby steps &lt;em&gt;always&lt;/em&gt;?
&lt;/h2&gt;

&lt;p&gt;No. But...&lt;/p&gt;

&lt;p&gt;During the process described here, some of the steps may look ridiculous and we could think we could take a group of them and apply them together straight away. That's fine as long as we do it consciously. That we &lt;em&gt;know&lt;/em&gt; we are tackling a number of smaller steps at once, and we have the mental discipline to roll back the changes and start over, one small step at a time if it is needed. We cannot get to this position unless we practice enough applying baby steps to the point we internalize it.&lt;/p&gt;

&lt;p&gt;We will notice we take a lot of steps to reach our refactor goal and we don't spend a lot of time fixing possible errors. Because the time spent fixing wrong decisions is minimal (because the decisions are minimal as well) we will be advancing at a continuous pace. The process is overall faster and safer than taking a big chunk of changes at once and having to think about what we did wrong when it does not work.&lt;/p&gt;

&lt;p&gt;With practice comes experience, and with experience comes the confidence to take bigger steps. But we should always have the baby steps tool ready if things get messy.&lt;/p&gt;
&lt;h2&gt;
  
  
  The code we will refactor
&lt;/h2&gt;

&lt;p&gt;Now we will apply refactoring with baby steps in a simple code example but juicy enough to showcase the process, set in the context of the &lt;a href="https://dev.to/xoubaman/a-mockumentary-about-value-objects-3ad8"&gt;aforementioned Value Objects post&lt;/a&gt;: a Jira-like software managing Story Points as primitive &lt;code&gt;int&lt;/code&gt; values.&lt;/p&gt;

&lt;p&gt;The method we will refactor is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SprintReport&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="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$completedStoryPoints&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;addCompletedStoryPoints&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$amount&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;void&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;$amount&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&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;'SP cannot be less than 0'&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;completedStoryPoints&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nv"&gt;$amount&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;Diligent as we are, it is covered by the following (truncated) tests :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;final&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SprintReportTest&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;TestCase&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cd"&gt;/** @test */&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;completedPointsDoNotChangeWhenAddingZeroStoryPoints&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="mf"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="cd"&gt;/** @test */&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;failsWhenAddingLessThanZeroStoryPoints&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="mf"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="cd"&gt;/** @test */&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;registersStoryPointsWhenAddingAValidAmountToAnEmptyReport&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="mf"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="cd"&gt;/** @test */&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;addsUpStoryPointsWhenAddingToANonEmptyReport&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="mf"&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;For reference, this is how a test actually looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;final&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SprintReportTest&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;TestCase&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;SprintReport&lt;/span&gt; &lt;span class="nv"&gt;$sprintReport&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;setUp&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;parent&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;setUp&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;sprintReport&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;SprintReport&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="cd"&gt;/** @test */&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;addsUpStoryPointsWhenAddingToANonEmptyReport&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&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;sprintReport&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;addCompletedStoryPoints&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&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;sprintReport&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;addCompletedStoryPoints&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="nv"&gt;$expected&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;SprintReport&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;assertEquals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$expected&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;sprintReport&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;And our &lt;code&gt;StoryPoint&lt;/code&gt; Value Object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StoryPoint&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="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$value&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;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;int&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="n"&gt;value&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;h2&gt;
  
  
  The first refactor
&lt;/h2&gt;

&lt;p&gt;Now that the ground is settled, we start to refactor. We will refer to the current implementation as the "old method" and the one we are introducing as the "new method".&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Adding an empty method&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fw1498kdhkv4frpi0ujy3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fw1498kdhkv4frpi0ujy3.png" alt="Step 1-01" width="800" height="557"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A new empty method that accepts our &lt;code&gt;StoryPoint&lt;/code&gt; VO as parameter. Nobody is using it yet so it should not break anything. We run the tests and indeed they are still green.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Instantiate a &lt;code&gt;StoryPoint&lt;/code&gt; using the int value&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F4jk44ss6qw24pvfob8kt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F4jk44ss6qw24pvfob8kt.png" alt="Step 1-02" width="800" height="291"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the old method, we instantiate a &lt;code&gt;StoryPoint&lt;/code&gt; from the int parameter. Tests are green, life is simple.&lt;/p&gt;

&lt;p&gt;These two first steps may seem stupid. Well, we don't think (at least I hope so) babies are stupid because they start walking with small steps that are extremely conservative compared to their usual crawling. They are afraid of failing and so we are. They have pretty much less to lose than us being cautious, and still they are. There is something to learn here.&lt;/p&gt;

&lt;p&gt;Indeed, with time and experience, we will happily be applying these two steps at once without hesitation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Duplicate the guard clause in the new method&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F3u59rtlb4fhk1gpi7lg0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F3u59rtlb4fhk1gpi7lg0.png" alt="Step 1-03" width="800" height="228"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This one is more interesting. We duplicate the clause guard checking the value of the story point is valid in our new method. Because the value is encapsulated in the VO, we check it using the getter we have for it.&lt;strong&gt;This is not a good approach from a VO point of view&lt;/strong&gt;, the VO should be self-validated and the fact we have an instance means it is valid. In other words, the validation should happen inside the VO. But our focus right now is to get rid of the old method using primitives and replace it with usages of our VO. After that, we will be in a better position to apply a second refactor and make our VO self validated.&lt;/p&gt;

&lt;p&gt;The tests are still green.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Call the new method after the guard clause&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fvdr0o6ixqmv9ev4ztifa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fvdr0o6ixqmv9ev4ztifa.png" alt="Step 1-04" width="800" height="350"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that we actually call the code we duplicated in the previous step and the tests are green, we know that our duplicated guard works as expected when the input is valid. However, we don't know if we did a mistake when checking invalid input since the guard in the old method will fail and prevent our new method from being executed. But we are in an optimal scenario to verify our new guard validates correctly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5: Delete the old guard clause&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fe15mczhosabyrjh21nrd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fe15mczhosabyrjh21nrd.png" alt="Step 1-05" width="800" height="351"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Actually, the recommended approach here would be to comment out the old guard, run the test, check they are green, and actually remove the old guard clause. Commenting code is safer than cutting text or rely on the undo operation of our editor. When we comment we always "move forward" and the code is "persisted" instead of going backward with undo or put our hopes in the hands of the volatility of the clipboard.&lt;/p&gt;

&lt;p&gt;When we totally delete the old guard clause and verify the tests are green, we can confirm our new guard clause correctly validates both valid and invalid input.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 6: Duplicate and comment out the increase of story points&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F58cihjvx9aw7xwstvtua.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F58cihjvx9aw7xwstvtua.png" alt="Step 1-06" width="800" height="233"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Replacing this part of the old method is tricky: we cannot keep the old one and the new one at the same time because it is an operation that modifies the state of our &lt;code&gt;SprintReport&lt;/code&gt; and keeping both would do the modification twice. We duplicate it adapted to the usage of &lt;code&gt;StoryPoint&lt;/code&gt; but commented out. Doing so we can easily switch between both implementations to verify tests are green and go back to the old one in case they are not.&lt;/p&gt;

&lt;p&gt;With the commented new code tests are still green.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 7: Uncomment the new increase, delete the old one&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fwdlm6xkuxh4nxyplb227.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fwdlm6xkuxh4nxyplb227.png" alt="Step 1-07" width="800" height="497"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Doing the switch between implementations commenting and uncommenting each of them allows us to run the tests for each with the ability to switch back if we broke something in our new code. Once we verify we did not, we can delete the old implementation for good.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 8: Update the tests to use the new method&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fwdlm6xkuxh4nxyplb227.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fwdlm6xkuxh4nxyplb227.png" alt="Step 1-08" width="800" height="497"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At this point, we have a new method using the VO as parameter and an old method that only instantiates the VO from the &lt;code&gt;int&lt;/code&gt; parameter and calls the new method. We can now replace all of the usages of the old method with the new one. The spectrum of this change will affect the tests and the whole application.&lt;/p&gt;

&lt;p&gt;Depending on how many times the old method is used this change could imply a lot of updates in different parts of the application and may not be a good mass update to tackle at this point. Maybe it is better to iteratively update its remaining usages when going through the code using it while we work on other tasks. We can make this explicit for future devs renaming the method to something that evidences it is recommended to use the new method or flagging it as deprecated.&lt;/p&gt;

&lt;p&gt;In any case, the following steps are not especially sexy: automated renames using the IDE and "search and replace" usages of the old method. We will skip them here, but you can check them in the &lt;a href="https://github.com/xoubaman/refactoring-with-baby-steps" rel="noopener noreferrer"&gt;repository&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The second refactor
&lt;/h2&gt;

&lt;p&gt;Although we have a method expecting a &lt;code&gt;StoryPoint&lt;/code&gt; that substitutes the old one dealing with primitives, we still have room for improvement in other areas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;SprintReport&lt;/code&gt; still uses &lt;code&gt;int&lt;/code&gt; for tracking the Story Points.&lt;/li&gt;
&lt;li&gt;The validation of a correct amount of Story Points happens outside the VO.&lt;/li&gt;
&lt;li&gt;The addition of Story Points in a report uses the internal value of the VO, instead of doing the addition using a &lt;code&gt;add()&lt;/code&gt; method exposed by the &lt;code&gt;StoryPoint&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Covering all this stuff would take too much for this already too long post, so we will focus on the first one showcasing another technique to apply baby steps when refactoring: adding optional parameters with a default value.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Add a new optional &lt;code&gt;StoryPoint&lt;/code&gt; parameter to the constructor&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F580vzrqr3mvu1fwx1vyo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F580vzrqr3mvu1fwx1vyo.png" alt="Step 2-01" width="487" height="154"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The new parameter defaults to null, hence any previous usage of the constructor won't fail and tests are green. Doing so we allow to introduce usages of the new constructor parameter and adapt the class to use it while not breaking any existing code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Conditionally set the initial story points from the VO parameter when provided&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F9g2gmpsti9o4bp6202c4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F9g2gmpsti9o4bp6202c4.png" alt="Step 2-02" width="670" height="306"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now our constructor sets the initial Story Points from the optional parameter when it is provided. Nobody does so yet and the tests are green. At this point, we are in the position of iteratively provide the optional parameter while keeping our &lt;code&gt;SprintReport&lt;/code&gt; functional.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Update the tests to provide the optional parameter&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F5alrt1jlh2o63gy0xtmx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F5alrt1jlh2o63gy0xtmx.png" alt="Step 2-03" width="800" height="279"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since this is an educational post our class is quite simple and only used in the tests, so we just need to update them. However, in reality, there would be more usages of &lt;code&gt;SprintReport&lt;/code&gt;, and adapting all of them might be a huge effort.&lt;/p&gt;

&lt;p&gt;An alternative to going over all &lt;code&gt;SprintReport&lt;/code&gt; constructor usages is to add a new static factory method to it, allowing to incrementally update our codebase to use the VO typed parameter while keeping compatibility with the &lt;code&gt;int&lt;/code&gt; one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class SprintReport
{
    public static function withCompleteStoryPoints(StoryPoint $completed): self
    {
        return new self($completed-&amp;gt;value(), $completed);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since here we only have the tests using it, we update them right away.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Duplicate and comment the assignment of completed Story Points&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F08egz61rgi3d65fc2emj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F08egz61rgi3d65fc2emj.png" alt="Step 2-04" width="679" height="297"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With this step we will allow, by switching between the conditional assignment and this new one, to verify all the usages of &lt;code&gt;SprintReport&lt;/code&gt; constructor are updated. When commenting the conditional block and using the new one, any test covering a usage that is not providing the VO parameter will fail.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5: Delete the conditional block from constructor&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fty318vhsxd1mcuntw8hg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fty318vhsxd1mcuntw8hg.png" alt="Step 2-05" width="673" height="356"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once we are sure all the constructor usages provide the VO parameter, we can delete the conditional assignment.&lt;/p&gt;

&lt;p&gt;At this point we can perform automated refactors with our IDE, changing the constructor signature to accept only the VO parameter and completing our change to remove the usage of Story Points as integers.&lt;/p&gt;

&lt;h2&gt;
  
  
  More refactors
&lt;/h2&gt;

&lt;p&gt;As mentioned before, there are several other changes we could do in &lt;code&gt;SprintReport&lt;/code&gt; and in &lt;code&gt;StoryPoint&lt;/code&gt; to improve our implementation and usage of Value Objects for this case.&lt;/p&gt;

&lt;p&gt;That would be too much to describe here, but you can check in the &lt;a href="https://github.com/xoubaman/refactoring-with-baby-steps" rel="noopener noreferrer"&gt;repository&lt;/a&gt; the next steps to make the most out of the encapsulation Value Object pattern provides. In small and safe steps :D&lt;/p&gt;

&lt;h2&gt;
  
  
  Final words
&lt;/h2&gt;

&lt;p&gt;A TL;DR version of this post could be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Always have tests in place.&lt;/li&gt;
&lt;li&gt;Apply the smaller change possible, run the tests. They will be probably green because the change was minimal.&lt;/li&gt;
&lt;li&gt;If tests are not green, fixing or going back to the previous step is trivial because the change was minimal.&lt;/li&gt;
&lt;li&gt;We save time refactoring in baby steps.&lt;/li&gt;
&lt;li&gt;Maybe we don't notice we save time just because we don't spend time figuring out what we did wrong when introducing a non-trivial change.&lt;/li&gt;
&lt;li&gt;With practice and experience, we will be able to take bigger steps. But we should do it consciously and be able to fall back to baby steps if things get messy.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As with any stuff, it will take some time to get used to this type of approach to refactoring. As with the good stuff, once you are into it it is difficult to turn back.&lt;/p&gt;

&lt;p&gt;For a more profound and consistent read about refactoring and object-oriented programming in general, I can recommend you the book &lt;a href="https://sandimetz.com/99bottles" rel="noopener noreferrer"&gt;99 bottles of OOP&lt;/a&gt; by Sandy Metz, Katrina Owen, and TJ Stankus. I recommend it even if you have no interest in refactoring with baby steps. It may be one of the best books about writing OOP out there.&lt;/p&gt;

&lt;p&gt;And that's all for today. As always, feedback is much appreciated. See you!&lt;/p&gt;

&lt;p&gt;PS: I talk about Story Points here because it is a handy example, but I discourage using them. &lt;a href="https://twitter.com/RonJeffries/status/493915127293296640" rel="noopener noreferrer"&gt;And so do the people who invented them&lt;/a&gt;. You have been warned.&lt;/p&gt;

&lt;p&gt;PS2: If anyone knows any decent software to generate visually appealing diff images, please let me know. Going screenshot as I did here is hell.&lt;/p&gt;

</description>
      <category>refactoring</category>
      <category>php</category>
      <category>goodpractices</category>
    </item>
    <item>
      <title>A mockumentary about Value Objects</title>
      <dc:creator>Carlos Gándara</dc:creator>
      <pubDate>Tue, 12 Jan 2021 21:15:51 +0000</pubDate>
      <link>https://dev.to/xoubaman/a-mockumentary-about-value-objects-3ad8</link>
      <guid>https://dev.to/xoubaman/a-mockumentary-about-value-objects-3ad8</guid>
      <description>&lt;p&gt;Some weeks ago, this happened:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fx5125okr4m62x50uautb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fx5125okr4m62x50uautb.png" alt="Precision for the win" width="567" height="72"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is a screenshot from the actual changelog of &lt;a href="https://apps.apple.com/us/app/jira-cloud-by-atlassian/id1006972087" rel="noopener noreferrer"&gt;the Jira app in the App Store&lt;/a&gt;. Two thoughts outstand from the several that arose when I saw it for the first time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In which scenario this may be considered worthy to be highlighted.&lt;/li&gt;
&lt;li&gt;What a good case it is for explaining the power of Value Objects (VOs).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's take a number of assumptions about how Jira is implemented in order to illustrate what the Value Objects pattern is and why it is one of the most powerful patterns in object-oriented programming. Needless to say, the example is 100% made up and not based on the actual Jira code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pattern definition
&lt;/h2&gt;

&lt;p&gt;The definition of Value Object &lt;a href="https://en.wikipedia.org/wiki/Value_object" rel="noopener noreferrer"&gt;according to wikipedia&lt;/a&gt; is&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A small object that represents a simple entity whose &lt;strong&gt;equality is not based on identity&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I would say they are not necessarily small, although it is legit to claim they are &lt;em&gt;usually&lt;/em&gt; small. Furthermore, there are other non-mandatory but highly desirable characteristics of Value Objects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They are immutable.&lt;/li&gt;
&lt;li&gt;They attract behavior related to the concept they represent.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Leveraging encapsulation and semantics
&lt;/h2&gt;

&lt;p&gt;Coming back to our new outstanding Jira feature, let's assume the ability to have decimal story points is that important because a) it was not possible before and b) there is a fair amount of work behind making it possible.&lt;/p&gt;

&lt;p&gt;Let's assume as well, and it looks like a fair assumption, that Jira has a massive codebase. It is a huge application and it has been around for a while. Probably Story Points are all around the place since they are a relevant piece of the average adoption of Scrum, a field in which Jira kind of excels.&lt;/p&gt;

&lt;p&gt;Now consider the following code snippets from a possible implementation of some of the concepts Jira handles (in PHP, just in case it is not clear enough the not-real nature of the code exposed):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Task&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$title&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$storyPoints&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;estimation&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Sprint&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;TaskList&lt;/span&gt; &lt;span class="nv"&gt;$tasks&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$totalStoryPoints&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;estimation&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;int&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;addTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Task&lt;/span&gt; &lt;span class="nv"&gt;$task&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SprintReport&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$completedStoryPoints&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;addCompletedStoryPoints&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$amount&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;void&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;All the references to &lt;code&gt;int&lt;/code&gt; values are actually references to Story Points. As the code is now, allowing decimals for them is far from trivial: we have seven different appearances to change only in this small bit of code. Imagine the whole codebase or even the implementation of the methods outlined here.&lt;/p&gt;

&lt;p&gt;Now, if we consider the following Value Object to model the concept of Story Point:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StoryPoint&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="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$value&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;value&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;int&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="n"&gt;value&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;and how the code would look like using it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Task&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$title&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;StoryPoint&lt;/span&gt; &lt;span class="nv"&gt;$estimation&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;estimation&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;StoryPoint&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Sprint&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;TaskList&lt;/span&gt; &lt;span class="nv"&gt;$tasks&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;StoryPoint&lt;/span&gt; &lt;span class="nv"&gt;$totalStoryPoints&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;estimation&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;StoryPoint&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;addTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Task&lt;/span&gt; &lt;span class="nv"&gt;$task&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SprintReport&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;StoryPoint&lt;/span&gt; &lt;span class="nv"&gt;$completedStoryPoints&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;addCompletedStoryPoints&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;StoryPoint&lt;/span&gt; &lt;span class="nv"&gt;$amount&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;void&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;The change from integer to float, allowing decimals, implies only two changes: the two &lt;code&gt;int&lt;/code&gt; references in the &lt;code&gt;StoryPoint&lt;/code&gt; Value Object. And probably whatever mapping you are doing in your persistence system to translate a Story Point to a database column supporting decimals, something required whatsoever.&lt;/p&gt;

&lt;p&gt;Confronting our VO with the pattern definition it hardly could be smaller than that, although size is not a key aspect.&lt;/p&gt;

&lt;p&gt;It is identified by its value, meaning we don't care about having one instance of it or another as long as they hold the same value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$aStoryPointVO&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;StoryPoint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nv"&gt;$anotherStoryPointVO&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;StoryPoint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;//using one VO or the other is indifferent&lt;/span&gt;
&lt;span class="c1"&gt;//and would result in an equivalent Task&lt;/span&gt;
&lt;span class="nv"&gt;$aTask&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;Task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'task-id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Task title'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$aStoryPointVO&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our VO sticks to the definition and that's good. In the end... well, it is a VO. Out of the box, Value Objects provide encapsulation, greatly reducing the number of places to modify when introducing a change in the concept they represent, and semantics. The other two aspects we mentioned before, immutability and attracting behavior, are not "built-in" and they depend on our diligence.&lt;/p&gt;

&lt;h2&gt;
  
  
  Attracting behavior
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjqsl30j5c59so9beegaa.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjqsl30j5c59so9beegaa.jpeg" alt="Attracting behavior" width="478" height="308"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Attracting behavior is something that comes naturally and bolsters the encapsulation and meaningfulness of the Value Object. Immutability is quite related to it as well. We will use the method &lt;code&gt;addCompletedStoryPoints&lt;/code&gt; in our &lt;code&gt;SprintReport&lt;/code&gt; example to illustrate both. Consider this not desirable way of implementing it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SprintReport&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;StoryPoint&lt;/span&gt; &lt;span class="nv"&gt;$completedStoryPoints&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;//Don't do this&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;addCompletedStoryPoints&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;StoryPoint&lt;/span&gt; &lt;span class="nv"&gt;$amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$previousValue&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;completedStoryPoints&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;value&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nv"&gt;$addedValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$amount&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;value&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;completedStoryPoints&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;StoryPoint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$previousValue&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$addedValue&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;With this operation we are breaking the encapsulation provided by the Value Object: the client code (the method) knows that the internal representation of the value of &lt;code&gt;StoryPoint&lt;/code&gt; is an integer and we fall into the same trap as before, because a change in this internal value will lead to updates on several parts of our codebase -the Value Object itself plus all parts that know too much about its internals and use them, like in the code above.&lt;/p&gt;

&lt;p&gt;The logic that belongs to a VO should be put &lt;em&gt;inside&lt;/em&gt; the VO. Adding two &lt;code&gt;StoryPoint&lt;/code&gt; is an operation that makes sense only inside &lt;code&gt;StoryPoint&lt;/code&gt; because only &lt;code&gt;StoryPoint&lt;/code&gt; should know about its internals. That's what attracting behavior means and it does very good work on empowering our code encapsulation and semantics.&lt;/p&gt;

&lt;p&gt;Consider this VO-free piece of code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$age = 21;
$storyPoints = 3;

$somethingVeryWrong = $age + $storyPoints;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When your code works with primitives to handle concepts of your domain (which by the way is a code smell named &lt;a href="https://refactoring.guru/smells/primitive-obsession" rel="noopener noreferrer"&gt;primitive obsession&lt;/a&gt;), the programming language cannot prevent you from doing such things. Types and Value Objects do.&lt;/p&gt;

&lt;p&gt;So, how to approach adding Story Points? Putting the add operation in &lt;code&gt;StoryPoint&lt;/code&gt; and passing another &lt;code&gt;StoryPoint&lt;/code&gt; to be added:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StoryPoint&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="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$value&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;value&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;int&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="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;//We are skipping the return type on purpose. Stay tuned!&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;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;StoryPoint&lt;/span&gt; &lt;span class="nv"&gt;$storyPoint&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;This way we guarantee that nobody knows about the internals of our VO and can nonsensically add random unrelated values to them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Immutability
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1xuhzd1t4iw2b6m81hr4.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1xuhzd1t4iw2b6m81hr4.jpeg" alt="Avoid mutant VOs!" width="478" height="351"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When implementing the &lt;code&gt;add&lt;/code&gt; operation in our &lt;code&gt;StoryPoint&lt;/code&gt; VO we may be tempted to go like the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StoryPoint&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="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$value&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;value&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;int&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="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;//Don't do this&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;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;StoryPoint&lt;/span&gt; &lt;span class="nv"&gt;$storyPoint&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;value&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;value&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$storyPoint&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;value&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;For sure we are sticking to the encapsulation, but we are introducing mutability as well. And we mentioned we want our VOs to be immutable when possible. Mutability is something to avoid because it is a source of hard to track bugs. Consider the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$fiveStoryPoints&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;StoryPoint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nv"&gt;$report&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;SprintReport&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nv"&gt;$report&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;addCompletedStoryPoints&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$today&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$fiveStoryPoints&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;//Can we trust our $fiveStoryPoints are still five?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As long as our &lt;code&gt;StoryPoint&lt;/code&gt; public interface (the &lt;code&gt;add&lt;/code&gt; method) is changing the state of the instance like in the previous implementation, we cannot guarantee its value was not changed inside the call to &lt;code&gt;addCompletedStoryPoints&lt;/code&gt;. Of course, we can open &lt;code&gt;addCompletedStoryPoints&lt;/code&gt; and check there is no call to the &lt;code&gt;add&lt;/code&gt; method there, but that's a manual approach that does not scale very well.&lt;/p&gt;

&lt;p&gt;The way to make our VOs immutable is returning a new fresh VO as a result of the operation. Here is the implementation plus the usage in &lt;code&gt;SprintReport&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StoryPoint&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="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$value&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;value&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;int&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="n"&gt;value&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;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;StoryPoint&lt;/span&gt; &lt;span class="nv"&gt;$storyPoint&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;StoryPoint&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;value&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$storyPoint&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;value&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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SprintReport&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;StoryPoint&lt;/span&gt; &lt;span class="nv"&gt;$completedStoryPoints&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;addCompletedStoryPoints&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;StoryPoint&lt;/span&gt; &lt;span class="nv"&gt;$amount&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;completedStoryPoints&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;completedStoryPoints&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$amount&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;Although it may seem a waste of memory and resources, those are not aspects we should care bout in the vast majority of the situations -garbage collection will take care of the instances not referenced soon enough- and the value we get in exchange is far more significant.&lt;/p&gt;

&lt;p&gt;Some literature claims immutability is not a mandatory aspect of VOs, although highly desirable. To be honest, I've never found a situation where mutability was justified, but it does not mean there are none. As with all the "rules" in software development, it is on the developer's good reasoning to decide when to bend them in a given context. Default to immutable VOs and if you find a scenario where it is not advisable, please let me know :)&lt;/p&gt;

&lt;h2&gt;
  
  
  Final word
&lt;/h2&gt;

&lt;p&gt;Hopefully, this post has given a good grasp on the benefits the Value Object pattern provides to any OOP codebase, even using a naive example to illustrate it. Introducing them in greenfield applications or code suffering from primitive obsession pays off from the first minute, so I cannot encourage you enough to use them.&lt;/p&gt;

&lt;p&gt;In a following article, we will see how to introduce our &lt;code&gt;StoryPoint&lt;/code&gt; Value Object in this made-up Jira codebase we have, applying refactoring techniques in baby steps. Probably the two most powerful tools available in OOP. Stay tuned! &lt;/p&gt;

</description>
      <category>patterns</category>
      <category>php</category>
    </item>
    <item>
      <title>Ambiguity hurts communication. And we should care about it</title>
      <dc:creator>Carlos Gándara</dc:creator>
      <pubDate>Sun, 13 Dec 2020 20:30:01 +0000</pubDate>
      <link>https://dev.to/xoubaman/the-three-most-misused-terms-in-software-development-and-how-to-deal-with-them-3odf</link>
      <guid>https://dev.to/xoubaman/the-three-most-misused-terms-in-software-development-and-how-to-deal-with-them-3odf</guid>
      <description>&lt;p&gt;&lt;strong&gt;Update from December 2023:&lt;/strong&gt; Three years after writing this not-so-fortunate post, I deeply regret the title I gave it in the first place (&lt;em&gt;The three most misused terms in software development and how to deal with them&lt;/em&gt;), which follows a clickbait pattern so sadly common in the present days. A mix of getting caught in the wave and an absurd thirst for popularity? Probably.&lt;/p&gt;

&lt;p&gt;The content was never good, but at least there is an idea somehow worth behind it. I've edited the title to something less crappy. Apologies.&lt;/p&gt;

&lt;p&gt;The original content starts here:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;There are only two hard things in Computer Science: cache invalidation and naming things.&lt;br&gt;
-- Phil Karlton&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Bad naming hurts communication, and communication is a first-class citizen in an activity like software development. Here we will be discussing the three most common -in my personal ranking, although they should appear for a fact in any top ten- wrongly used terms in the development jargon.&lt;/p&gt;

&lt;h2&gt;
  
  
  Service
&lt;/h2&gt;

&lt;p&gt;This is the absolute winner of the most overloaded term in software development. It covers a range that goes from massive external applications, Facebook as a whole can be an &lt;em&gt;authentication service&lt;/em&gt;, to virtually any class in a codebase, when in the context of a &lt;em&gt;service container&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The multiple meanings the word service has are not bad &lt;em&gt;per se&lt;/em&gt;. It is a broad term and that's necessary in a world that is that much into abstractions. However, this generality could mean a serious penalty to communication quality if not used in an agreed and seamlessly understood context.&lt;/p&gt;

&lt;p&gt;One real personal experience: I spent half an hour totally disoriented in a meeting "to discuss services dependencies" until I realized the services were not the "microservices" I thought, in the context of software architecture, but the relations between "doctor services" in the context of medical activity, like blood analysis, dental surgery, and the like. By the time I got it was too late to catch up.&lt;/p&gt;

&lt;p&gt;In several situations there is a better word than service, or it can be expressed together with another word that narrows the meaning to common ground. When we cannot find an alternative, better to settle first what kind of services are being discussed and do it again when the conversation jumps to another type.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mock
&lt;/h2&gt;

&lt;p&gt;In the context of testing, the broad usage of &lt;em&gt;Mock&lt;/em&gt; means a replacement of a dependency of the code being tested to isolate this code from the dependency.&lt;/p&gt;

&lt;p&gt;Actually, that's the definition of a &lt;em&gt;test double&lt;/em&gt; and the term mock has overtaken its supertype in everyday talking.&lt;/p&gt;

&lt;p&gt;Mocks are only one of the five types of test doubles, the most complex of all of them. They have a number of drawbacks and some benefits over other test doubles. I've written a full article dedicated to test doubles if you want to dig more into the differences.&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/xoubaman" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F34904%2Fa12e4744-e2fc-41ff-aa31-9867ca97281a.jpg" alt="xoubaman"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/xoubaman/the-hitchhiker-guide-to-test-doubles-53m3" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;The hitchhiker guide to test doubles&lt;/h2&gt;
      &lt;h3&gt;Carlos Gándara ・ Sep 9 '19&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#testing&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#php&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;The problem is that the indiscriminate use of &lt;em&gt;mock&lt;/em&gt; for any kind of test double has created a trend of using them for every situation a double is needed and spreading the belief that they are the only tool available for such purpose. That's not true.&lt;/p&gt;

&lt;p&gt;It is important to know as much as possible the tools at your disposal and chose the right one. Mocks have their use cases, use them when they fit, and other doubles when a mock is an overkill (which probably is most of the time by the way).&lt;/p&gt;

&lt;h2&gt;
  
  
  Refactor
&lt;/h2&gt;

&lt;p&gt;Refactor is "the process of restructuring existing code —changing the factoring— without changing its external behavior" (&lt;a href="https://en.wikipedia.org/wiki/Code_refactoring" rel="noopener noreferrer"&gt;wikipedia&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;However, the common usage refers to "the process of writing code in a place where there was code before". It would be more economic and accurate to say "I am changing code", but we geeks like to sound sophisticated (I guess) and we prefer to wrongly use a word with some echoes of a sci-fi movie, losing the chance to communicate better in the process.&lt;/p&gt;

&lt;p&gt;Not changing the external behavior of a piece of code means the same input will produce the same output. How you process this input and calculate this output is the implementation, and what you change when refactoring.&lt;/p&gt;

&lt;p&gt;This has a strong link with (well written) tests: when refactoring you don't touch anything on the tests, just the code making them pass. Otherwise, you are changing, updating, expanding, rewriting... Don't use refactor when doing that and miss the opportunity to transmit a precise message of what you are actually doing.&lt;/p&gt;

&lt;h2&gt;
  
  
  But is it that bad?
&lt;/h2&gt;

&lt;p&gt;It is. Every time we wrongly use one of these terms, or any other for the matter, we lose the opportunity to communicate better. This eventually translates to a waste of time, which is really bad.&lt;/p&gt;

&lt;p&gt;At the same time, it would be a tough and pointless battle to try to eradicate them. Mostly because they are the right word to use in certain moments and contexts, and also because their adoption is too deep in the day to day life. However, we should develop the ability to detect when their usage is harming the communication and act accordingly, pointing it out or gently introducing accurate alternatives.&lt;/p&gt;

&lt;p&gt;PS: I sincerely apologize for the slightly clickbait title :P&lt;/p&gt;

</description>
      <category>communication</category>
    </item>
    <item>
      <title>Book review: Just Enough Software Architecture</title>
      <dc:creator>Carlos Gándara</dc:creator>
      <pubDate>Sun, 19 Apr 2020 17:15:44 +0000</pubDate>
      <link>https://dev.to/xoubaman/book-review-just-enough-software-architecture-57oc</link>
      <guid>https://dev.to/xoubaman/book-review-just-enough-software-architecture-57oc</guid>
      <description>&lt;p&gt;Last year I attended the first edition of the &lt;a href="https://gsas.io/" rel="noopener noreferrer"&gt;GSAS&lt;/a&gt; conference. The &lt;a href="https://gsas.io/2019/#gsasspeakers" rel="noopener noreferrer"&gt;speaker roster&lt;/a&gt; was impressive and included George Fairbanks. Was because of it that I decided to read &lt;em&gt;Just Enough Software Architecture, a risk-driven approach&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;The outcome of the conference didn't live up to my expectations. The tone felt distant and somehow settling a differentiation between architects and developers, some kind of elitist barrier (and here for sure I am failing to describe precisely my impressions due to lack of English vocabulary). That was weird because most of the talks, the one from Fairbanks included, were not explicitly suggesting it at all.&lt;/p&gt;

&lt;p&gt;Turns out I got a similar impression from the book. There is valuable information on it, that's for sure, but the tone and a big part of it feel distant, maybe too academic, despite of Fairbanks efforts to provide meaningful examples and an informal tone.&lt;/p&gt;

&lt;p&gt;The book is structured in two main blocks. The first one introduces Risk-Driven Software Architecture, its main highlight and indeed an interesting approach. How you should architect your application based on the risks and quality attributes you know it requires, doing the right trade-offs to find a balance between deliverability and engineering. For instance, do not build an astonishingly scalable system if none of your quality attributes is performance. The way Fairbanks introduces this technique is enjoyable and well-illustrated, with solid examples for all of the standpoints.&lt;/p&gt;

&lt;p&gt;The second block, though, is composed of thoroug descriptions of ways of representing models of the architecture, at different levels and with different techniques. This translates to, and I know I am oversimplifying here, diagrams.&lt;/p&gt;

&lt;p&gt;Almost two-thirds of the book revolves around levels of detail, types of architecture representations, and the relations between them. The amount of theory and detail is noticeable and it is hard to relate big chunks of content to what I currently need as a software developer ( which might mean this disappointment is caused by a mix of expectations and momentum in my career). It took me a lot of time to finish the book because of the low engagement with this second block, especially after a first one way more practical and concise.&lt;/p&gt;

&lt;p&gt;Coming back to the conference perception, there is good stuff in the book and some things I will definitely take into account in my current and future projects. But at the same time, there is something hard to describe about it that made the reading not satisfactory. A contradiction between an approach to architecture encouraging doing just the necessary, and a tour about theoretical aspects of model representations that feel like way more than the necessary.&lt;/p&gt;

&lt;p&gt;A first part that relates to software developers and a second part that relates to architects.&lt;/p&gt;

</description>
      <category>books</category>
      <category>architecture</category>
    </item>
    <item>
      <title>About mothers, builders, and how to reduce duplication in your tests</title>
      <dc:creator>Carlos Gándara</dc:creator>
      <pubDate>Mon, 03 Feb 2020 18:49:42 +0000</pubDate>
      <link>https://dev.to/xoubaman/about-mothers-builders-and-how-to-reduce-duplication-in-your-tests-25gg</link>
      <guid>https://dev.to/xoubaman/about-mothers-builders-and-how-to-reduce-duplication-in-your-tests-25gg</guid>
      <description>&lt;p&gt;Applying the builder pattern when creating the fixture data in our tests will provide several relevant benefits: better readability, more explicit test scenarios, and resilience to refactors.&lt;/p&gt;

&lt;p&gt;It sounds too good to do not give it a try, doesn't it?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Disclaimer: code examples are in PHP but the concepts discussed refer to OOP, so don't get scared by the dollar symbols and the arrows. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Harmless changes with unexpected consequences
&lt;/h2&gt;

&lt;p&gt;A non-desirable but common scenario: an apparently harmless, small change in production code causes zillions of tests to fail. We did stick to SOLID, DRY and plenty of other buzzwords while coding. Then, how can this be possible? Why we have to tediously update several apparently unrelated tests?&lt;/p&gt;

&lt;p&gt;There are multiple possible reasons for this to happen. One of them is how we create fixture data in our tests. Consider the following scenario:&lt;/p&gt;

&lt;p&gt;We have an application that processes orders, modeled in the &lt;code&gt;Order&lt;/code&gt; class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;final&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Order&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;Uuid&lt;/span&gt; &lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$items&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$address&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;DateTime&lt;/span&gt; &lt;span class="nv"&gt;$deliveryDeadline&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;Uuid&lt;/span&gt; &lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$items&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="kt"&gt;DateTime&lt;/span&gt; &lt;span class="nv"&gt;$deliveryDeadline&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;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$id&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;items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$items&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;address&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$address&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;deliveryDeadline&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$deliveryDeadline&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;//Fancy business logic here&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In production code, we did the smart move of instantiating &lt;code&gt;Order&lt;/code&gt; class only in the &lt;code&gt;CreateNewOrder&lt;/code&gt; service when creating a new one, or in the &lt;code&gt;OrderRepository&lt;/code&gt; when we get an existing order from the database.&lt;/p&gt;

&lt;p&gt;As good or bad this modeling may look, our startup is starting to get some revenue out of it. The best part is that the code is extensively tested. For instance, we have this test taken from the more than forty we have involving an &lt;code&gt;Order&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cd"&gt;/** @test */&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;order_cannot_be_processed_when_delivery_deadline_is_reach&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$order&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;Order&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nc"&gt;Uuid&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(),&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;Item&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Dynamite Headdy'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'GOLD'&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;Item&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Gunstar Heroes'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;12500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'GOLD'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s1"&gt;'Rincewind, Mage Tower, Ankh-Morpork, 00752, Discworld'&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;DateTime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'yesterday'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;assertFalse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$order&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;canBeProcessed&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;Feels good to have business logic properly tested. However, our company is having more and more problems from customers living in some parts of Ankh-Morpork -no surprises- and we want to stop sending stuff to a certain zip codes. For that, we decide to model the address as an &lt;code&gt;Address&lt;/code&gt; value object so we can easily evaluate when an order is being delivered to a forbidden zip code:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;final&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Address&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$street&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$city&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$zipCode&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$country&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="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;hasBannedZipCode&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;bool&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;We write a test for the new behavior:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cd"&gt;/** @test */&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;order_cannot_be_processed_when_address_has_a_banned_zipcode&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$order&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;Order&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nc"&gt;Uuid&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(),&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;Item&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Speck of dust'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'GOLD'&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;Item&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Higgins bosom'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'GOLD'&lt;/span&gt;&lt;span class="p"&gt;),&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;Address&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Rincewind'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Mage Tower'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Ankh-Morpork'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;BANNED_ZIPCODE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Discworld'&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;DateTime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'yesterday'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;assertFalse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$order&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;canBeProcessed&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;Changes in the code are straightforward. We implement the &lt;code&gt;canBeProcessed()&lt;/code&gt; method using the new &lt;code&gt;Address&lt;/code&gt; value object and the new test passes. Now we can expect to update &lt;code&gt;CreateNewOrder&lt;/code&gt; and &lt;code&gt;OrderRepository&lt;/code&gt; classes to deal with the change in &lt;code&gt;Order&lt;/code&gt; constructor. But when we run the test suite we see forty of them in red. Not surprisingly, the ones involving orders.&lt;/p&gt;

&lt;p&gt;In our production code, we took care of minimizing the places where we instantiate a new &lt;code&gt;Order&lt;/code&gt; (band reference not intended) to reduce the reach of changes like the one we just did, but we forgot about our tests that are instantiating orders all around.&lt;/p&gt;

&lt;p&gt;There are other undesirable effects on the approach we took. One is that &lt;code&gt;Order&lt;/code&gt; instantiation is causing a lot of noise because of this complexity when we usually care only about one aspect of it -the zip code in the above example. The other is the inability to visually detect if we are messing up the order of the parameters in the address.&lt;/p&gt;

&lt;p&gt;Luckily, we are here to see how builders mitigate such situations.&lt;/p&gt;
&lt;h2&gt;
  
  
  Introducing the builder pattern
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fihhdvl0irbnn83b8afj5.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fihhdvl0irbnn83b8afj5.jpeg" alt="Thanks, Jim" width="375" height="350"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://en.wikipedia.org/wiki/Builder_pattern" rel="noopener noreferrer"&gt;builder pattern&lt;/a&gt; is one of the &lt;a href="https://www.amazon.com/Design-Patterns-Object-Oriented-Addison-Wesley-Professional-ebook/dp/B000SEIBB8" rel="noopener noreferrer"&gt;GoF Design Patterns&lt;/a&gt;. It consists in separating the -usually complex- construction of an object from its representation.&lt;/p&gt;

&lt;p&gt;Twisting it a bit, the suggestion here is to use builders for any object or data structure you create more than once in your tests.&lt;/p&gt;

&lt;p&gt;A possible public interface for a builder for our &lt;code&gt;Order&lt;/code&gt; might be:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;final&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderBuilder&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;build&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;Order&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;withId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Uuid&lt;/span&gt; &lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;self&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;withItems&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$items&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;self&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;withAddress&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Address&lt;/span&gt; &lt;span class="nv"&gt;$address&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;self&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;withDeliveryDeadline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;DateTime&lt;/span&gt; &lt;span class="nv"&gt;$deliveryDeadline&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;self&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;The &lt;code&gt;build()&lt;/code&gt; method return an &lt;code&gt;Order&lt;/code&gt; instance with any setup we define through the &lt;code&gt;withX()&lt;/code&gt; methods. Internally we define default values for all the parameters involving instantiating an &lt;code&gt;Order&lt;/code&gt;, so we don't need to call all the &lt;code&gt;withX()&lt;/code&gt; methods every time -that would miss big part of the point of using these builders.&lt;/p&gt;

&lt;p&gt;Our previous test looks now like:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cd"&gt;/** @test */&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;order_cannot_be_processed_when_address_if_from_a_banned_zipcode&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$address&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;Address&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Rincewind'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Mage Tower'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Ankh-Morpork'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;BANNED_ZIPCODE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Discworld'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nv"&gt;$order&lt;/span&gt; &lt;span class="o"&gt;=&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;OrderBuilder&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;withAddress&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;assertFalse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$order&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;canBeProcessed&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;Way more readable, concise, and explicit about the purpose of the test. Even more, we can have an &lt;code&gt;AddressBuilder&lt;/code&gt; as well and reduce all the irrelevant code needed to create a complete address.&lt;/p&gt;

&lt;p&gt;If now we need to change anything else in the &lt;code&gt;Order&lt;/code&gt; modeling, we have drastically reduced the points we need to change in our tests to do so. For instance, a change from the array of &lt;code&gt;Item&lt;/code&gt; to an &lt;code&gt;ItemCollection&lt;/code&gt;, so we can filter certain types of items to apply discounts, will require only to change the &lt;code&gt;OrderBuilder&lt;/code&gt;, because it is the only point in our test suite we create &lt;code&gt;Order&lt;/code&gt; instances. Profit.&lt;/p&gt;

&lt;p&gt;Builders are as well very handy to generate plain structures, like request payloads or configuration files, and they do un awesome work removing the mysticism of magic numbers in the tests: it is more understandable &lt;code&gt;withDiscount(10)&lt;/code&gt; than a lonely, meaningless &lt;code&gt;10&lt;/code&gt; in the middle of some constructor call.&lt;/p&gt;
&lt;h2&gt;
  
  
  Introducing object mother pattern
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fs46a2j52am6dhf654qk3.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fs46a2j52am6dhf654qk3.jpeg" alt="There is only one" width="640" height="359"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.martinfowler.com/bliki/ObjectMother.html" rel="noopener noreferrer"&gt;Object mother&lt;/a&gt; is a pattern where a class is used to create example objects, exposing a number of explicit factory methods.&lt;/p&gt;

&lt;p&gt;If we start noticing we are building the same &lt;code&gt;Order&lt;/code&gt; configuration in several tests we are still duplicating code. For instance, if our orders over 50 total price are susceptible to special discounts and many other advantages, we will do the following setup multiple times:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cd"&gt;/** @test */&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;order_has_free_shipping_when_total_amount_is_50_eur_or_more&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$item&lt;/span&gt; &lt;span class="o"&gt;=&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;ItemBuilder&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;withPrice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;51&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nv"&gt;$order&lt;/span&gt; &lt;span class="o"&gt;=&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;OrderBuilder&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;withItems&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nv"&gt;$item&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;assertTrue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$order&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;hasFreeShipping&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;Using an object mother class for order would reduce the previous example to:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cd"&gt;/** @test */&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;order_has_free_shipping_when_total_amount_is_50_eur_or_more&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$order&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OrderMother&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;ofAmountGreaterThan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;assertTrue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$order&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;hasFreeShipping&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;Object mothers do the same work as builders when it comes to reduce duplication and noise in tests, although we must be careful to don't hide the duplication inside the object mother and bloat it with multiple instantiations of the same class, incurring in the same problem as before -although at a lesser scale, for sure.&lt;/p&gt;

&lt;p&gt;Another issue we can run into is starting to use the object mother for everything, even for slight variations of the same data setup, overcharging them with factory methods with names too long to represent to the specificness of each case. A builder would work better in that case. &lt;/p&gt;

&lt;p&gt;That said, why not combine both? We can add factory methods to our builders and if they start to become too cumbersome, move all the mother-ish methods to a proper object mother that internally uses a builder. Or have an object mother for builders with setups that we can tweak for concrete, edgy cases. Sky and your needs and context are the limit.&lt;/p&gt;
&lt;h2&gt;
  
  
  A builder implementation example
&lt;/h2&gt;

&lt;p&gt;This is an example of how you can implement a builder in PHP:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;final&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MetalSlugCharacterBuilder&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$base&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="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;base&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="s1"&gt;'name'&lt;/span&gt;   &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'Marco Rossi'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'weapon'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;RocketLauncher&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="s1"&gt;'bombs'&lt;/span&gt;  &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;10&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;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;MetalSlugCharacter&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;MetalSlugCharacter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&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;base&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;withName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;self&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="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$name&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;withWeapon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Weapon&lt;/span&gt; &lt;span class="nv"&gt;$weapon&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;self&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="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'weapon'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$weapon&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;withBombs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$bombs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;self&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="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'bombs'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$bombs&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;Furthermore, I even wrote a small library to reduce the amount of boilerplate and the time required to code a builder, plus some extra goodies. You can check it here:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/xoubaman" rel="noopener noreferrer"&gt;
        xoubaman
      &lt;/a&gt; / &lt;a href="https://github.com/xoubaman/builder" rel="noopener noreferrer"&gt;
        builder
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A lightweight PHP library to build... builders
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;



&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Same as we care about avoiding unnecessary repetition in our production code, our tests deserve the same attention, if not more. Builder and object mother are two patterns that will help us to have a more consistent test suite, where tests fail because they should and not because we forgot to update the n-ish instantiation of some class.&lt;/p&gt;

</description>
      <category>testing</category>
      <category>cleancode</category>
      <category>design</category>
      <category>php</category>
    </item>
  </channel>
</rss>
