<?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: João Hélio</title>
    <description>The latest articles on DEV Community by João Hélio (@joaohelio).</description>
    <link>https://dev.to/joaohelio</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%2F851786%2F8f8d37cf-a0b1-4406-9a6e-1ed669073fec.png</url>
      <title>DEV Community: João Hélio</title>
      <link>https://dev.to/joaohelio</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/joaohelio"/>
    <language>en</language>
    <item>
      <title>The Four Principles of Design Thinking in Software Architecture</title>
      <dc:creator>João Hélio</dc:creator>
      <pubDate>Wed, 12 Feb 2025 09:20:42 +0000</pubDate>
      <link>https://dev.to/marleyspoon/the-four-principles-of-design-thinking-in-software-architecture-o8d</link>
      <guid>https://dev.to/marleyspoon/the-four-principles-of-design-thinking-in-software-architecture-o8d</guid>
      <description>&lt;p&gt;Design Thinking is less a process and more a way to think about problems and solutions from the people's perspective and how the architecture affects the stakeholders.&lt;/p&gt;

&lt;p&gt;In this post, I’m going to highlight the four principles of Design Thinking and how they can be applied to software development to guide our design activities.&lt;/p&gt;

&lt;p&gt;🔹 &lt;strong&gt;Design for Humans&lt;/strong&gt;&lt;br&gt;
We design software for people and with people, in the end, &lt;strong&gt;software development is an intensely social and collaborative activity&lt;/strong&gt;. The idea to &lt;em&gt;create a software&lt;/em&gt; architecture &lt;em&gt;isolated&lt;/em&gt; from the team &lt;em&gt;is a myth&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;As we design a system, we work closely with our team, fostering mutual respect by actively listening, assuming positive intent, and embracing human-centered design principles.&lt;/p&gt;

&lt;p&gt;Empathizing with the humans who directly and indirectly interact with the architecture makes us a better designer, communicators, and leaders.&lt;/p&gt;

&lt;p&gt;🔹 &lt;strong&gt;Preserve Ambiguity&lt;/strong&gt;&lt;br&gt;
Ambiguity in engineering is dangerous. Once we've made a design decision, we must share it with precision and clarity. However, &lt;strong&gt;design decisions that do not directly influence a quality attribute or reduce risk threatening our ability to deliver software are more about detailed design than architecture&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Such decisions can safely be left open for downstream designers to settle outside the architecture. &lt;/p&gt;

&lt;p&gt;🔹 &lt;strong&gt;Design is Redesign&lt;/strong&gt;&lt;br&gt;
The redesign rule encourages us to think about what we already know by exploring patterns and past designs. As time goes on and as we build more software, our institutional knowledge about how to design great software improves. Other teams have probably seen a problem similar to the one you are facing currently. Hopefully, someone documented a pattern you can use as a starting point for your architecture.&lt;/p&gt;

&lt;p&gt;When designing software architectures, &lt;strong&gt;we'll spend more time refining existing designs than creating new ones&lt;/strong&gt;. One of the least effective ways to design an architecture is to ignore the software system that came before us.&lt;/p&gt;

&lt;p&gt;🔹 &lt;strong&gt;Make the Architecture Tangible&lt;/strong&gt;&lt;br&gt;
While the structures in the architecture can exist in code, this does not make the architecture any more tangible.&lt;/p&gt;

&lt;p&gt;Code is difficult to read and does not make discussions about quality attributes, coarse-grained components, design rationale, or the consequences of our decisions any easier.&lt;/p&gt;

&lt;p&gt;If we want to share an architecture with others, then we need to make it real in a way that code by itself will not allow.&lt;/p&gt;

&lt;p&gt;The tangible rule is closely related to the human rule. Humans &lt;strong&gt;must be able to relate to ideas to internalize them.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reference&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Design It&lt;/strong&gt;: From Programmer to Software Architect by Michael Keeling&lt;/p&gt;

&lt;p&gt;What are your thoughts? Let’s discuss it! 👇  &lt;/p&gt;

</description>
      <category>designthinking</category>
    </item>
    <item>
      <title>Thinking in Abstractions</title>
      <dc:creator>João Hélio</dc:creator>
      <pubDate>Wed, 09 Oct 2024 09:57:49 +0000</pubDate>
      <link>https://dev.to/marleyspoon/thinking-in-abstractions-4hde</link>
      <guid>https://dev.to/marleyspoon/thinking-in-abstractions-4hde</guid>
      <description>&lt;p&gt;A quick fix in the code can solve many issues, but it may create complexity that becomes difficult to maintain over time. This happens as more and more rules are added to address specific problems within a general context. Let's look at a use case and explore some potential solutions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use Case
&lt;/h3&gt;

&lt;p&gt;Imagine you have a general &lt;code&gt;Order&lt;/code&gt; class, but now the business requires handling two specific cases. The &lt;strong&gt;Halloween Order&lt;/strong&gt; must contain at least ten line items, while the &lt;strong&gt;Christmas Order&lt;/strong&gt; can be empty but must include at least one add-on.&lt;/p&gt;

&lt;h3&gt;
  
  
  First Try: &lt;code&gt;IF-ELSE&lt;/code&gt; Statement
&lt;/h3&gt;

&lt;p&gt;We can attempt to handle this with conditionals like the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Order&lt;/span&gt;
  &lt;span class="nb"&gt;attr_accessor&lt;/span&gt; &lt;span class="ss"&gt;:line_items&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:plan&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:add_ons&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;line_items&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;plan&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Basic'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Standard'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;add_ons&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt;
    &lt;span class="vi"&gt;@line_items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;line_items&lt;/span&gt;
    &lt;span class="vi"&gt;@plan&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;plan&lt;/span&gt;
    &lt;span class="vi"&gt;@type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;
    &lt;span class="vi"&gt;@add_ons&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;add_ons&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;validate&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vi"&gt;@type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;'Standard'&lt;/span&gt;
      &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="s1"&gt;'Total amount must be greater least one line item'&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vi"&gt;@line_items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;empty?&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vi"&gt;@type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;'Halloween'&lt;/span&gt;
      &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="s1"&gt;'Halloween order must have at least ten line items'&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vi"&gt;@line_items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;size&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vi"&gt;@type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;'Christmas'&lt;/span&gt;
      &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="s1"&gt;'Christmas order must have at least one add-on'&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vi"&gt;@add_ons&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;empty?&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Example usage
halloween_order = Order.new([], 'Premium', 'Halloween')
halloween_order.validate
=&amp;gt; `validate': Halloween order must have at least ten line items (RuntimeError)

christmas_order = Order.new([], 'Enterprise', 'Christmas')
christmas_order.validate
=&amp;gt; `validate': Total amount must be greater least one line item (RuntimeError)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Pros
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Simplicity in Small-Scale Scenarios&lt;/strong&gt;: using &lt;code&gt;if-else&lt;/code&gt; statements can be the quickest way to implement logic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fewer Lines of Code&lt;/strong&gt;: For simple conditional logic may result in fewer lines of code at first.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No Need for Overhead in Basic Use Cases&lt;/strong&gt;: In situations where we don’t expect many changes or extensions to the logic, &lt;code&gt;if-else&lt;/code&gt; can avoid unnecessary overhead.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Cons
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Mixed Responsibilities&lt;/strong&gt;: The &lt;code&gt;Order&lt;/code&gt; class is now responsible for both general order logic and the specific rules for Halloween and Christmas orders.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Difficult to Extend&lt;/strong&gt;: Adding a new order type means modifying the core &lt;code&gt;Order&lt;/code&gt; class, which introduces risk and reduces flexibility.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Harder to Test&lt;/strong&gt;: We can end up having a test that is hard to understand when specific rules are incorporated.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Second try: Abstraction Through Inheritance
&lt;/h3&gt;

&lt;p&gt;We can create &lt;strong&gt;specialized classes&lt;/strong&gt; that capture the architectural intent. By abstracting common behaviour into a base class and allowing each type to manage its own rules.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Order&lt;/span&gt;
  &lt;span class="nb"&gt;attr_accessor&lt;/span&gt; &lt;span class="ss"&gt;:line_items&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:plan&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:add_ons&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;line_items&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;plan&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Basic'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;add_ons&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt;
    &lt;span class="vi"&gt;@line_items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;line_items&lt;/span&gt;
    &lt;span class="vi"&gt;@plan&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;plan&lt;/span&gt;
    &lt;span class="vi"&gt;@add_ons&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;add_ons&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;validate&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="s1"&gt;'Total amount must be greater least one line item'&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vi"&gt;@line_items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;empty?&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HalloweenOrder&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Order&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;line_items&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;plan&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Basic'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;add_ons&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;line_items&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;plan&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;add_ons&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;validate&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="s1"&gt;'Halloween order must have at least ten line items'&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vi"&gt;@line_items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;size&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ChristmasOrder&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Order&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;line_items&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;plan&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Basic'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;add_ons&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;line_items&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;plan&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;add_ons&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;validate&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="s1"&gt;'Christmas order must have at least one add-on'&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vi"&gt;@add_ons&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;empty?&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Example usage
halloween_order = HalloweenOrder.new([], 'Premium')
halloween_order.validate                                 
=&amp;gt; `validate': Halloween order must have at least ten line items (RuntimeError)

christmas_order = ChristmasOrder.new([], 'Enterprise')
christmas_order.validate
=&amp;gt; `validate': Christmas order must have at least one add-on (RuntimeError)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Pros
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Separation of Concerns&lt;/strong&gt;: The base &lt;code&gt;Order&lt;/code&gt; class only handles shared behaviour. The specific rules for &lt;code&gt;HalloweenOrder&lt;/code&gt; and &lt;code&gt;ChristmasOrder&lt;/code&gt; are handled in their respective classes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability&lt;/strong&gt;: Adding a new order type (e.g., &lt;code&gt;EasterOrder&lt;/code&gt;, &lt;code&gt;BlackFridayOrder&lt;/code&gt;) is easy.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Easier to Test&lt;/strong&gt;: Testing new use cases doesn't require a shared setup.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Cons
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Overhead for Simple Use Cases&lt;/strong&gt;: When the use case is simple, setting up multiple classes and abstractions can introduce unnecessary complexity.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Over-Engineering&lt;/strong&gt;: YAGNI ("You Aren’t Gonna Need It") we might introduce abstractions for future possibilities that never materialize.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;More Classes to Maintain&lt;/strong&gt;: Abstracting logic into specialized classes can increase the number of files and classes, which means more "moving parts". &lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;The patch and the module abstraction methods have their place in software design. The key is to assess the complexity and evolution of the system.&lt;/p&gt;

&lt;p&gt;Start simple and refactor when complexity arises. This balance ensures the architecture remains maintainable and adaptable without becoming overly complicated.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Retro Guide</title>
      <dc:creator>João Hélio</dc:creator>
      <pubDate>Mon, 20 Nov 2023 09:20:37 +0000</pubDate>
      <link>https://dev.to/marleyspoon/retro-guide-2l6p</link>
      <guid>https://dev.to/marleyspoon/retro-guide-2l6p</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;The sprint retrospective is a moment for our team to reflect on the past sprint, celebrate successes, and identify areas for improvement. By fostering a culture of continuous learning, we aim to enhance our work process and achieve even greater success in the future. To achieve this, strategic planning is essential, ensuring that the retrospective becomes a well-orchestrated effort toward sustained improvement and growth.&lt;/p&gt;

&lt;h2&gt;
  
  
  Directives
&lt;/h2&gt;

&lt;p&gt;At the heart of our retrospective is the understanding that everyone did their best given the circumstances. We value cooperation, recognizing that our unique strengths are amplified when we work together. Hope and trust emerge through engagement, and we seize this opportunity to unite around a shared vision for the future.&lt;/p&gt;

&lt;h2&gt;
  
  
  Context
&lt;/h2&gt;

&lt;p&gt;Gaining insight into the project context provides a clear understanding of our position in the project, making it particularly valuable for the sprint retrospective. If time constraints prevent context discussion during other events like sprint review or planning, consider incorporating it as an introduction to the retrospective.&lt;/p&gt;

&lt;p&gt;Here are some aspects of the context that might be relevant to a retrospective:&lt;/p&gt;

&lt;h4&gt;
  
  
  Start or End of a Project
&lt;/h4&gt;

&lt;p&gt;Whether the retrospective marks the beginning or end of a project, the context would include specific project goals, team changes, initial expectations, and achievements.&lt;/p&gt;

&lt;h4&gt;
  
  
  Team Changes
&lt;/h4&gt;

&lt;p&gt;If there have been significant changes to the team composition (members joining or leaving), the context may include how these changes impacted team dynamics and performance.&lt;/p&gt;

&lt;h4&gt;
  
  
  Implementation of New Processes
&lt;/h4&gt;

&lt;p&gt;If the team has recently adopted new processes or tools, context can address the effectiveness of these changes and how they have influenced workflow.&lt;/p&gt;

&lt;h4&gt;
  
  
  Development Cycle
&lt;/h4&gt;

&lt;p&gt;Timing in the development cycle iteration (such as a specific sprint) is essential. Discussions can focus on goals met, user stories delivered, and obstacles faced during this sprint.&lt;/p&gt;

&lt;h4&gt;
  
  
  External Events
&lt;/h4&gt;

&lt;p&gt;External events, such as changes in customer demands, industry updates, or unexpected challenges, provide crucial context for understanding how the team responded to these external factors.&lt;/p&gt;

&lt;h4&gt;
  
  
  Performance Metrics
&lt;/h4&gt;

&lt;p&gt;Quantitative metrics such as team velocity, user story completion rate, or code quality can be part of the context, providing an objective basis for analysis.&lt;/p&gt;

&lt;h4&gt;
  
  
  Customer Feedback
&lt;/h4&gt;

&lt;p&gt;If there was customer feedback during or after the sprint, that feedback becomes part of the context, helping the team understand how their deliverables are perceived.&lt;/p&gt;

&lt;h4&gt;
  
  
  Organizational Objectives
&lt;/h4&gt;

&lt;p&gt;Contextualizing the retrospective about the organization's broader goals helps align the team's priorities with the company's overall goals.&lt;/p&gt;

&lt;h4&gt;
  
  
  Evaluation of Training or Culture Changes
&lt;/h4&gt;

&lt;p&gt;If the team participated in training or if the organization is going through cultural changes, this context is crucial to evaluate how these initiatives are being absorbed and applied.&lt;/p&gt;

&lt;h4&gt;
  
  
  Focus on the Current Sprint
&lt;/h4&gt;

&lt;p&gt;Direct the discussion to the most recent sprint, ensuring that observations and learnings are specific to the team's current situation.&lt;/p&gt;

&lt;h4&gt;
  
  
  Specific Goal Orientation
&lt;/h4&gt;

&lt;p&gt;This allows a team to focus on specific areas that need attention and improvement.&lt;/p&gt;

&lt;h4&gt;
  
  
  Connection to Long-Term Goals
&lt;/h4&gt;

&lt;p&gt;The retrospective should be seen as part of a continuous improvement process. Timing/context helps link the discussion to the long-term goals of the team and organization.&lt;/p&gt;

&lt;h4&gt;
  
  
  Identification of Trends Over Time
&lt;/h4&gt;

&lt;p&gt;You can identify trends over multiple sprints, which can lead to relevant insights into performance patterns and consistent areas for improvement.&lt;/p&gt;

&lt;h2&gt;
  
  
  Participant Preparation
&lt;/h2&gt;

&lt;p&gt;For our retrospective to be effective, the team members are encouraged to reflect on specific questions before the meeting to facilitate a more insightful discussion:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What worked well:&lt;/strong&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Standout moments in the sprint.
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Example: "The continued refinement of the Rewards topic was a highlight, allowing us to define the goals of the domain better."&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Effective practices or processes.
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Example: "Adopting the clean architecture concepts has helped us to create a more scalable system."&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Exceptional collaboration between team members.
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Example: "Close collaboration between developers and PMs during the Q&amp;amp;A phase facilitated rapid identification and resolution of bugs."&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Individual skills that contributed to success.
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Example: "John's problem-solving skills were instrumental in overcoming unexpected challenges during development."&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Aspects of the work that led to overall success.
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Example: "Clarity in user stories helped avoid misunderstandings and allowed smoother implementation."&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Positive changes compared to the previous sprint.
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Example: "Implementing &lt;code&gt;excellent_migrations&lt;/code&gt; tool reduced the bugs to zero when creating a new migration."&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Each team member's main contributions.
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Example: "Maria effectively led the resolution of a critical problem, demonstrating her ability to deal with challenging situations."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What can be improved:&lt;/strong&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Main obstacles or challenges faced.
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Example: "Integration with the legacy API system was more complicated than expected, causing significant delays."&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Communication difficulties negatively impact the team.
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Example: "The lack of regular updates on task progress has confused me about priorities. When we say 'I'm working on it and don't have any blockers' on Dailies meeting, we lose the opportunity to receive feedback and share knowledge."&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Aspects of the work process that can be optimized.
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Example: "Reviewing milestones and deadlines regularly can give us evidence to adapt to the current tasks."&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Recurring issues that need addressing.
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Example: "Dependence on a single specialist for certain critical tasks has caused bottlenecks. We must diversify knowledge within the team."&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Gaps in the team’s skills or knowledge.
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Example: "The lack of expertise in a new technology impacted the efficient implementation of a feature. We must seek training."&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Handling external pressures or tight deadlines.
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Example: "Deadline pressure has affected code quality. We should explore strategies to maintain an appropriate balance between speed and quality."&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Tasks or activities that did not contribute significantly.
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Example: "Allocating extensive resources to infrequently requested functionality may have been unnecessary. We must evaluate the value before initiating such tasks."&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Checkin
&lt;/h2&gt;

&lt;p&gt;Collect the participants' sentiments. This sets the tone for a focused and constructive discussion.&lt;/p&gt;

&lt;h2&gt;
  
  
  Continuous Improvement
&lt;/h2&gt;

&lt;p&gt;Engage in data collection, emotional expression, and acknowledgment of positive aspects. Explore opportunities for enhancement to commit to continuous improvement.&lt;/p&gt;

&lt;h2&gt;
  
  
  Filtering
&lt;/h2&gt;

&lt;p&gt;Prioritize discussion topics to generate insights within the available time efficiently. Streamline the conversation to focus on the most crucial areas.&lt;/p&gt;

&lt;h2&gt;
  
  
  Checkout
&lt;/h2&gt;

&lt;p&gt;As the meeting concludes, assign responsibilities for action items identified during the retrospective. Clearly define who will be responsible for each task.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In summary, the retrospective process is designed to promote a culture of continuous improvement within our team. By encouraging thoughtful participant preparation, considering relevant context, and fostering open communication, we aim to glean valuable insights for enhancing our work processes. Through these efforts, we aspire to create a collaborative environment that consistently strives for excellence.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.funretrospectives.com"&gt;Fun Retrospectives&lt;/a&gt;: A diverse collection of activities and techniques for engaging retrospectives.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;The Retrospective Handbook - A guide for agile teams&lt;/em&gt; by Patrick Kua: A practical guide for agile teams running effective retrospectives.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Agile Retrospectives - Making Good Teams Great&lt;/em&gt; by Esther Derby, Diana Larsen, Ken Schwaber: A comprehensive overview of conducting effective agile retrospectives.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>agile</category>
    </item>
    <item>
      <title>The Request and Response Model in the Clean Architecture</title>
      <dc:creator>João Hélio</dc:creator>
      <pubDate>Thu, 31 Aug 2023 10:00:27 +0000</pubDate>
      <link>https://dev.to/marleyspoon/the-request-and-response-model-in-the-clean-architecture-517c</link>
      <guid>https://dev.to/marleyspoon/the-request-and-response-model-in-the-clean-architecture-517c</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;One of the key concepts within the Clean Architecture is the Request and Response model, which helps to separate the core application logic from external concerns such as user interfaces and frameworks. In this article, we'll explore the Request and Response model and demonstrate its implementation using Ruby.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Request and Response Model
&lt;/h3&gt;

&lt;p&gt;The Request and Response model is a pattern that promotes a clear separation between the inputs and outputs of the application. By doing so, the architecture becomes more adaptable to changes and easier to test, as the core logic is not tightly coupled to any specific framework or external component.&lt;/p&gt;

&lt;h3&gt;
  
  
  Request
&lt;/h3&gt;

&lt;p&gt;A request in the Clean Architecture represents the input to a use case or an operation within the application. It encapsulates the necessary data required for the operation to be executed. Requests are usually simple data structures and do not contain any business logic. They act as a boundary between the external world (such as UI) and the application's core.&lt;/p&gt;

&lt;h3&gt;
  
  
  Response
&lt;/h3&gt;

&lt;p&gt;On the other hand, a response represents the output of a use case or operation. It contains the result of the operation, including any data that needs to be presented to the user or propagated to other parts of the application. Similar to requests, responses are also typically simple data structures.&lt;/p&gt;

&lt;h3&gt;
  
  
  Implementing
&lt;/h3&gt;

&lt;p&gt;Let's consider a simple example of a blog application. We'll implement the Request and Response model for a use case where a user wants to create a new blog post.&lt;/p&gt;

&lt;p&gt;In the following example, we define &lt;code&gt;PostRequest&lt;/code&gt; as a &lt;code&gt;Dry::Validation::Contract&lt;/code&gt; and &lt;code&gt;PostResponse&lt;/code&gt; using &lt;code&gt;Dry::Struct&lt;/code&gt;. The &lt;code&gt;CreatePost&lt;/code&gt; use case takes a request object, processes the business logic, and returns a response object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'dry/struct'&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'dry/validation'&lt;/span&gt;

&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Blog&lt;/span&gt;
  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;UseCases&lt;/span&gt;
    &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Posts&lt;/span&gt;
      &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PostRequest&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Dry&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Validation&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Contract&lt;/span&gt;
        &lt;span class="n"&gt;params&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
          &lt;span class="n"&gt;required&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:title&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;filled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="n"&gt;required&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:content&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;filled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="n"&gt;required&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:author_id&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;filled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:integer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PostResponse&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Dry&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Struct&lt;/span&gt;
        &lt;span class="n"&gt;attribute&lt;/span&gt; &lt;span class="ss"&gt;:success&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Types&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Bool&lt;/span&gt;
        &lt;span class="n"&gt;attribute&lt;/span&gt; &lt;span class="ss"&gt;:message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Types&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;String&lt;/span&gt;
        &lt;span class="n"&gt;attribute&lt;/span&gt; &lt;span class="ss"&gt;:post_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Types&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;optional&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CreatePost&lt;/span&gt;
        &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="n"&gt;validation_result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;PostRequest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

          &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;validation_result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;success?&lt;/span&gt;
            &lt;span class="c1"&gt;# Business logic to create a new post&lt;/span&gt;
            &lt;span class="c1"&gt;# ...&lt;/span&gt;

            &lt;span class="c1"&gt;# Return a response&lt;/span&gt;
            &lt;span class="no"&gt;PostResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;success: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;message: &lt;/span&gt;&lt;span class="s1"&gt;'Post created successfully'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;post_id: &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="k"&gt;else&lt;/span&gt;
            &lt;span class="c1"&gt;# Return a response with validation errors&lt;/span&gt;
            &lt;span class="no"&gt;PostResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;success: &lt;/span&gt;&lt;span class="kp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;message: &lt;/span&gt;&lt;span class="s1"&gt;'Validation errors'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;post_id: &lt;/span&gt;&lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="k"&gt;end&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# Example usage&lt;/span&gt;
&lt;span class="n"&gt;request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Blog&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;UseCases&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Posts&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;PostRequest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="ss"&gt;title: &lt;/span&gt;&lt;span class="s1"&gt;'Sample Post'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;content: &lt;/span&gt;&lt;span class="s1"&gt;'This is the content of the post.'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;author_id: &lt;/span&gt;&lt;span class="mi"&gt;123&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;use_case&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Blog&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;UseCases&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Posts&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;CreatePost&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;
&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;use_case&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;message&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's see how we can write a test for the &lt;code&gt;CreatePost&lt;/code&gt; use case:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;RSpec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;describe&lt;/span&gt; &lt;span class="no"&gt;Blog&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;UseCases&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Posts&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;CreatePost&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;let&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:use_case&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;described_class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="s1"&gt;'when the request is valid'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;let&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:valid_request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="no"&gt;Blog&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;UseCases&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Posts&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;CreatePostRequest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="ss"&gt;title: &lt;/span&gt;&lt;span class="s1"&gt;'Sample Post'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;content: &lt;/span&gt;&lt;span class="s1"&gt;'This is the content of the post.'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;author_id: &lt;/span&gt;&lt;span class="mi"&gt;123&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s1"&gt;'creates a new post'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;use_case&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;valid_request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;success&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;message&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Post created successfully'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post_id&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;eq&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="c1"&gt;# Replace with your expected post ID&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="s1"&gt;'when the request is invalid'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;let&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:invalid_request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="no"&gt;Blog&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;UseCases&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Posts&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;CreatePostRequest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="ss"&gt;title: &lt;/span&gt;&lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;content: &lt;/span&gt;&lt;span class="s1"&gt;'This is the content of the post.'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;author_id: &lt;/span&gt;&lt;span class="kp"&gt;nil&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s1"&gt;'returns validation errors'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;use_case&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;invalid_request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;success&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;message&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Validation errors'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post_id&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;be_nil&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To explore the full capabilities of the dry-rb ecosystem check the &lt;a href="https://dry-rb.org/"&gt;website&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Benefits of the Request and Response Model
&lt;/h3&gt;

&lt;p&gt;By separating requests and responses, we achieve a clear boundary between external concerns and core business logic and since requests and responses are simple data structures, testing becomes straightforward, and we can easily write unit tests for each use case.&lt;/p&gt;

&lt;p&gt;The Clean Architecture, coupled with the Request and Response model, allows us to change external components or frameworks without affecting the core logic.&lt;/p&gt;

&lt;p&gt;In conclusion, the Request and Response model is a powerful concept within the Clean Architecture that promotes separation of concerns and maintainability.&lt;/p&gt;

&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;p&gt;"Clean Architecture: A Craftsman's Guide to Software Structure and Design" by Robert C. Martin&lt;/p&gt;

</description>
      <category>cleancode</category>
      <category>ruby</category>
    </item>
    <item>
      <title>Understanding Bounded Contexts in Ruby</title>
      <dc:creator>João Hélio</dc:creator>
      <pubDate>Thu, 17 Aug 2023 09:33:28 +0000</pubDate>
      <link>https://dev.to/marleyspoon/understanding-bounded-contexts-in-ruby-13el</link>
      <guid>https://dev.to/marleyspoon/understanding-bounded-contexts-in-ruby-13el</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Bounded contexts have a crucial role in managing complexity, maintaining a clear separation of concerns, and ensuring that different parts of a system can communicate effectively without causing conflicts or confusion. Bounded contexts are a fundamental concept in Domain-Driven Design (DDD) and are particularly relevant when building complex systems. &lt;/p&gt;

&lt;p&gt;In this article, the bounded contexts will be explored using a practical example in Ruby, where we'll demonstrate how to consume and wrap a Plan object between two different contexts: the Plan Management context and the Sales context.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding Bounded Contexts
&lt;/h2&gt;

&lt;p&gt;A bounded context is a conceptual boundary within which a particular domain model is defined and applicable. Different parts of a software system may have different understandings of specific terms, rules, and behaviors. Bounded contexts help avoid ambiguity and conflicts by isolating other models within their own context, making sure they remain consistent and meaningful within that context.&lt;/p&gt;

&lt;p&gt;In our example scenario, imagine a software application for a company that offers subscription plans to its customers. There are two primary bounded contexts: Plan Management and Sales.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Plan Management Context: This context is responsible for creating, updating, and managing subscription plans. It focuses on the administrative aspects of plan creation and modification.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sales Context: This context is responsible for handling customer interactions, including the sale of subscription plans. It deals with pricing, availability, and customer-specific details.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tXiUwXTM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/61f3pausexdgczb90okk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tXiUwXTM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/61f3pausexdgczb90okk.png" alt="Image description" width="800" height="431"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Consuming and Wrapping Plan Objects
&lt;/h2&gt;

&lt;p&gt;Let's dive into the example scenario to understand how bounded contexts work in Ruby. We'll begin by creating a simplified Plan class that holds basic plan information. Then, we'll demonstrate how to consume and wrap a Plan object between the two contexts.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Plan class in the Plan Management context&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;PlanManagement&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Plan&lt;/span&gt;
    &lt;span class="nb"&gt;attr_reader&lt;/span&gt; &lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:price&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="vi"&gt;@id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;
      &lt;span class="vi"&gt;@name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;
      &lt;span class="vi"&gt;@price&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;update_price&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_price&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="vi"&gt;@price&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new_price&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Plan class in the Sales context&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Sales&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Plan&lt;/span&gt;
    &lt;span class="nb"&gt;attr_reader&lt;/span&gt; &lt;span class="ss"&gt;:customer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:plan_dto&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;plan_dto&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="vi"&gt;@customer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;
      &lt;span class="vi"&gt;@plan_dto&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;plan_dto&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;calculate_discount&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;credit&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;plan_dto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;price&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;name&lt;/span&gt;
      &lt;span class="n"&gt;plan_dto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;upcase&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;price&lt;/span&gt;
      &lt;span class="n"&gt;plan_dto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;price&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;credit&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, we have two classes defined in different contexts, the Plan class in the Plan Management context and the Plan in the Sales context. Each class is tailored to its respective context's needs.&lt;/p&gt;

&lt;p&gt;To maintain the separation between the contexts and ensure smooth communication, we need to wrap Plan objects when transitioning between contexts. Let's illustrate how this can be done:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;
&lt;span class="c1"&gt;# Plan Management context&lt;/span&gt;
&lt;span class="n"&gt;plan&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;PlanManagement&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Plan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&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="s2"&gt;"Basic Plan"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;10.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Sales context&lt;/span&gt;
&lt;span class="n"&gt;customer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"John Doe"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;sales_plan&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Sales&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Plan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;plan&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Example usage in the Sales context&lt;/span&gt;
&lt;span class="n"&gt;discount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sales_plan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;calculate_discount&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Customer &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; gets a discount of &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;discount&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;% on the &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;sales_plan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; plan."&lt;/span&gt;

&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Plan details:"&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Name: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;sales_plan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Price: $&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;sales_plan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;price&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, the &lt;code&gt;Sales::Plan&lt;/code&gt; class provides a bridge between the Sales context and the Plan Management context. It wraps the Plan object from the Plan Management context and exposes only the methods relevant to the Sales context, such as calculating discounts based on a customer's profile.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;By defining boundaries around different domain models and using wrapper classes when transitioning between contexts, we can maintain consistency, reduce conflicts, and promote a better understanding of how other parts of the system interact. In our Ruby example, we've demonstrated how bounded contexts can be applied to a Plan object, showcasing the practical benefits of this concept in real-world software development.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Domain-Driven Design: Tackling Complexity in the Heart of Software by Eric Evans This book is often considered the authoritative source on Domain-Driven Design (DDD) and introduces the concept of bounded contexts along with various other DDD principles.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Bounded Context - Martin Fowler's blog is a valuable resource for software design patterns and concepts. His article on bounded contexts provides a comprehensive explanation with examples.&lt;br&gt;
Link: &lt;a href="https://martinfowler.com/bliki/BoundedContext.html"&gt;https://martinfowler.com/bliki/BoundedContext.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

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