<?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: Rafal Stozek</title>
    <description>The latest articles on DEV Community by Rafal Stozek (@ralphcone).</description>
    <link>https://dev.to/ralphcone</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%2F109757%2F3319a885-cc98-4ca2-a2c8-839e7be42242.jpg</url>
      <title>DEV Community: Rafal Stozek</title>
      <link>https://dev.to/ralphcone</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ralphcone"/>
    <language>en</language>
    <item>
      <title>Locality of behavior</title>
      <dc:creator>Rafal Stozek</dc:creator>
      <pubDate>Wed, 25 Jan 2023 13:02:10 +0000</pubDate>
      <link>https://dev.to/ralphcone/new-hot-trend-locality-of-behavior-1g9k</link>
      <guid>https://dev.to/ralphcone/new-hot-trend-locality-of-behavior-1g9k</guid>
      <description>&lt;p&gt;There is a new trend gaining traction lately which is called &lt;em&gt;“Locality of Behaviour principle”&lt;/em&gt;. It is a &lt;strong&gt;great new name&lt;/strong&gt; for an old concept - cohesion. It’s growing lately around &lt;a href="https://htmx.org"&gt;HTMX&lt;/a&gt; and &lt;a href="https://tailwindcss.com"&gt;TailwindCSS&lt;/a&gt; communities, but it’s an useful concept in general.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;⚠️ Let me begin with a warning first:&lt;/strong&gt; I don’t believe in “principles” when it comes to software engineering. I think of everything as techniques that - when used &lt;strong&gt;correctly&lt;/strong&gt; and &lt;strong&gt;in the right context&lt;/strong&gt; - make the software better &lt;strong&gt;in some aspect&lt;/strong&gt; (eg. easier to understand). But when used without understanding or overused - they make it worse. There are no silver bullets and &lt;em&gt;Locality of Behaviour&lt;/em&gt; isn’t one either.&lt;/p&gt;

&lt;p&gt;Here’s what it is about:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The behaviour of a unit of code should be as obvious as possible by looking only at that unit of code. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This points back to a quote from a &lt;a href="https://www.dreamsongs.com/Files/PatternsOfSoftware.pdf"&gt;book by Richard P. Gabriel&lt;/a&gt; which states that:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The primary feature for easy maintenance is &lt;em&gt;locality&lt;/em&gt;:&lt;br&gt;
Locality is that characteristic of source code that enables a programmer to understand that source by looking at only a small portion of it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Ease of understanding
&lt;/h2&gt;

&lt;p&gt;LoB (Locality of Behaviour) is mostly concerned with ease of understanding. It’s much easier to understand code which lives together and can be easily and quickly tracked than code where you need to jump around the whole codebase to piece the logic together.&lt;/p&gt;

&lt;p&gt;It’s easy to imagine: let’s say that you are working on a backend app - not an API one, but a Multi-Page Application, server-side rendered. Now, to implement a new functionality you need to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;modify model a bit&lt;/li&gt;
&lt;li&gt;change how controller works&lt;/li&gt;
&lt;li&gt;update a form class&lt;/li&gt;
&lt;li&gt;change the template&lt;/li&gt;
&lt;li&gt;modify styles a bit&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Which one will be easier to update:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Part of the software, where are components you need to modify are in one small folder.&lt;/li&gt;
&lt;li&gt;Part of the software, where are components are scattered across different parts of the source code.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I think the answer here is pretty obvious, but I’ll leave it to you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Co-location
&lt;/h2&gt;

&lt;p&gt;The idea here is code co-location basically. &lt;a href="https://kentcdodds.com/blog/colocation"&gt;It has been written about before&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you have a system where code related to the same behaviour is scattered - try to bring it closer together - it will make it easier to understand and modify. This in order will increase your productivity, reduce frustrations and improve your joy of work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The goal is that&lt;/strong&gt; if you need to understand or modify some behaviour in the system, you will find most, if not all of the functionality easily, in single place and will be able to understand them quickly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example: Vue.js
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://vuejs.org"&gt;Vue&lt;/a&gt; is one of the most popular frontend libraries for creating Single Page Applications. It has something called &lt;a href="https://vuejs.org/guide/scaling-up/sfc.html"&gt;single file components&lt;/a&gt;, which bring together styles, javascript and templates. Let’s take a look at one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
export default &lt;span class="si"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;data&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="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;show&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;list&lt;/span&gt;&lt;span class="p"&gt;:&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;2&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="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;template&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"show = !show"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Toggle List&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"list.push(list.length + 1)"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Push Number&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"list.pop()"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Pop Number&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"list.reverse()"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Reverse List&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt; &lt;span class="na"&gt;v-if&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"show &amp;amp;&amp;amp; list.length"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt; &lt;span class="na"&gt;v-for&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"item of list"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="na"&gt;v-else-if&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"list.length"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;List is not empty, but hidden.&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="na"&gt;v-else&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;List is empty.&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;template&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;style&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  ul &lt;span class="si"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;padding&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="si"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;style&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now - you have everything to understand this particular component in a single place. It doesn't mean that placing styles, templates and code is the only way to do &lt;code&gt;LoB&lt;/code&gt; in SPAs. With React people usually place these in separate files, but in a single folder named after a component.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example: HTMX
&lt;/h2&gt;

&lt;p&gt;If I’m not mistaken the term “Locality of Behaviour” was coined by creator of &lt;a href="http://htmx.org"&gt;HTMX&lt;/a&gt;, Carson Gross. In HTMX it refers to the fact that it allows you to embed behaviour in HTML, in a clean and easy to understand (once you understand HTMX) way. It’s not a hammer that you can use to deal with everything, but it makes a large amount of interactions easy to do without any fancy frameworks or writing specialized JS code.&lt;/p&gt;

&lt;p&gt;Here’s an example of a “click to edit” functionality:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;hx-target=&lt;/span&gt;&lt;span class="s"&gt;"this"&lt;/span&gt; &lt;span class="na"&gt;hx-swap=&lt;/span&gt;&lt;span class="s"&gt;"outerHTML"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&amp;lt;label&amp;gt;&lt;/span&gt;First Name&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;: Joe&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&amp;lt;label&amp;gt;&lt;/span&gt;Last Name&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;: Blow&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&amp;lt;label&amp;gt;&lt;/span&gt;Email&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;: joe@blow.com&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
        &lt;span class="c"&gt;&amp;lt;!-- when button gets clicked - we'll load edit form and swap it with the outer div --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;hx-get=&lt;/span&gt;&lt;span class="s"&gt;"/contact/1/edit"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"btn btn-primary"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    Click To Edit
    &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;See how all of the behaviour is local, and we don’t have to look through files for &lt;code&gt;document.querySelector('.some-magic-class').addEventListener(...)&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://htmx.org/examples/"&gt;See more examples with interactive demos here.&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Not just frontend
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;LoB&lt;/code&gt;/co-location comes from frontend world, but it applies to backend as well.&lt;/p&gt;

&lt;p&gt;We not always may keep logic in one file, but we can always place related things together. A structure for a hypothetical Python app could look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.
├── thing_module/
│   ├── new_thing.py
│   │   ├── NewThingForm
│   │   ├── NewThingView
│   ├── templates/
│   │   └── new_thing.html
|   └── scss/
|   |   └── new_thing.scss
├── another_module/

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

&lt;/div&gt;



&lt;p&gt;Keeping things all together makes things easy to find and modify.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tensions and interactions
&lt;/h2&gt;

&lt;p&gt;For some reason in software development we tend to present techniques (which some call “principles”) as absolute - as if they stand on their own and have no interactions whatsoever.&lt;/p&gt;

&lt;p&gt;Well, things don’t work that way. So let’s take a look at how it interacts with different techniques and aspects of software development.&lt;/p&gt;

&lt;h3&gt;
  
  
  Separation of Concerns (SoC)
&lt;/h3&gt;

&lt;p&gt;Separation of Concerns is an old technique where we separate computer system into distinct sections, where each addresses separate concerns. Most of the time this means that we have separate “layers”. Some of examples include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://en.wikipedia.org/wiki/Internet_protocol_suite"&gt;IP Stack&lt;/a&gt; which is layered, uses different protocols at different layers, each taking care of a separate concern&lt;/li&gt;
&lt;li&gt;HTML (or templates), CSS and JavaScript in Web development dealing with different aspects of displaying a web page or an application&lt;/li&gt;
&lt;li&gt;Models, views and controllers in MVC paradigm when working with many backend frameworks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, when React first came out - there was a huge pushback from the community because it violates the Separation of Concerns. We started putting together HTML (templates or views) and JavaScript code (controllers).&lt;/p&gt;

&lt;p&gt;Not only that - after React got more popular - we started to place CSS in components as well (&lt;a href="https://en.wikipedia.org/wiki/CSS-in-JS"&gt;CSS-in-JS&lt;/a&gt; like &lt;a href="https://styled-components.com"&gt;this&lt;/a&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;styled-components&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// Create a component that renders a &amp;lt;p&amp;gt; element with blue text&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;BlueText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="s2"&gt;`
  color: blue;
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;BlueText&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;My blue text&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;BlueText&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, there is some tension between the two. But mostly only if you treat everything as a principle, not a technique. Thinking of it as a principle means that it’s non-negotiable and it’s always right to follow it, while technique is something you apply where it makes sense and improves things.&lt;/p&gt;

&lt;p&gt;The recipe for success here is rather simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;when your components / code is pretty simple - it’s usually better to be able to see everything at once&lt;/li&gt;
&lt;li&gt;but as the code - for a particular component / code unit grows more complex, at some point it is very useful to be able to understand business logic in isolation, without it being tangled with other concerns like templating or styling&lt;/li&gt;
&lt;li&gt;so start with something simple and when it grows more hard to understand, start separating those concerns in a way that make it easier to understand&lt;/li&gt;
&lt;li&gt;but when you separate these concerns to separate files - keep them close together so it’s still easy to understand whole thing - by looking at a single, small folder instead of now having to jump around 3-10 different places&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The key here is using the practice that makes sense in given case, not religiously doing the same thing everywhere.&lt;/p&gt;

&lt;h3&gt;
  
  
  High Cohesion &amp;amp; Low Coupling
&lt;/h3&gt;

&lt;p&gt;These two concepts are key to creating maintainable codebases. Most of so called principles are just reiterations and reinventions of these (and few more) concepts.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cohesion is basically a measure of how code put in the same code unit is related.&lt;/li&gt;
&lt;li&gt;Coupling is a measure of “how much other code will I have to change if I change X”.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The idea here is &lt;strong&gt;that&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;if&lt;/strong&gt; we put things that belong together (high cohesion) in a code unit / module&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;and&lt;/strong&gt; then ensure that changes inside of that module have low impact on the outside of a module (low coupling)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;then&lt;/strong&gt; our code will be:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;easy to understand&lt;/strong&gt; (you just look at a single place)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;and easy to modify&lt;/strong&gt; (modifications of a module do not trigger cascade of changes)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Locality of Behaviour means that you put things which work together - together. Behaviour of a given piece of software is nicely enclosed in a single place, making it cohesive. It works to increase cohesion of your system, and by extension helps with low coupling.&lt;/p&gt;

&lt;h3&gt;
  
  
  DRY and cross-cutting concerns
&lt;/h3&gt;

&lt;p&gt;Here’s the thing: &lt;a href="https://dev.to/ralphcone/please-do-repeat-yourself-dry-is-dead-1jbg"&gt;repeating yourself can sometimes be beneficial&lt;/a&gt;. But it doesn’t mean that you can let repetition run rampant in your system, otherwise you’ll end up with incohesive, unmaintainable ball of mud.&lt;/p&gt;

&lt;p&gt;I’m not sure where the idea that &lt;code&gt;LoB&lt;/code&gt; somehow collides with DRY comes from, but I have two guesses:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Too much of DRY. Basically if someone obsesses over DRY-ing one-liners.&lt;/li&gt;
&lt;li&gt;Unaddressed cross-cutting concerns.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The first point is pretty simple. People sometimes obsess over DRY too much, trying to remove each small repetition, usually falling into the traps of &lt;a href="https://sandimetz.com/blog/2016/1/20/the-wrong-abstraction"&gt;false abstractions&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The other one is unaddressed cross-cutting concerns. Think of things like authentication, where instead of calling &lt;code&gt;ensure_has_permission(X)&lt;/code&gt; you manually load user and check permissions.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;LoB&lt;/code&gt; doesn’t mean that you can understand whole piece of software without any prior knowledge. You need to learn cross-cutting concerns and how they work in the system. You need to learn the framework you are working with. In case of &lt;code&gt;HTMX&lt;/code&gt; you need to understand HTMX, HTML and general web development to some extent before you can claim that “I can understand this piece by just looking at it”.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;While the term was coined in &lt;code&gt;HTMX&lt;/code&gt; environment, which is frontend - &lt;code&gt;LoB&lt;/code&gt; is a great way to think about any codebase. Asking yourself questions like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;how much places do I have to go to and check in order to understand this piece?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;is a good way of better understanding maintainability of your code.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Please do repeat yourself (DRY is dead)</title>
      <dc:creator>Rafal Stozek</dc:creator>
      <pubDate>Mon, 24 Oct 2022 20:09:53 +0000</pubDate>
      <link>https://dev.to/ralphcone/please-do-repeat-yourself-dry-is-dead-1jbg</link>
      <guid>https://dev.to/ralphcone/please-do-repeat-yourself-dry-is-dead-1jbg</guid>
      <description>&lt;p&gt;First of all, let me apologize for the clickbait-y title, but we need to talk about &lt;em&gt;Don’t Repeat Yourself&lt;/em&gt; (&lt;em&gt;DRY&lt;/em&gt;) principle.&lt;/p&gt;

&lt;h2&gt;
  
  
  Story 1
&lt;/h2&gt;

&lt;p&gt;Few years ago we were asked to help with further development of an existing platform in the blockchain industry. It was a product directed to traders and helped them automate tax fillings. And it was the biggest copy&amp;amp;paste-based project I have seen in my life.&lt;/p&gt;

&lt;p&gt;It was written in PHP. If you know PHP then you know that each &lt;code&gt;.php&lt;/code&gt; file acts as an entry point to your code - and from there you usually import (include) utilities, libraries which are common to your project. That is if you don’t use a framework. This one didn’t.&lt;/p&gt;

&lt;p&gt;This project was created from the ground up by its founder who learned programming while creating and maintaining this product.&lt;/p&gt;

&lt;p&gt;They didn’t have much programming knowledge beforehand and didn’t know all of these good practices and fancy rules that we have. So each &lt;code&gt;.php&lt;/code&gt; file was a copy of a previous one with modifications needed for given route/view. Tons of repeated code.&lt;/p&gt;

&lt;p&gt;And here’s what’s really important: &lt;strong&gt;at this point the product already made millions of dollars.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let that sink in. No amount of copied code, repetition and what we would call “bad quality code” stopped the product from being successful.&lt;/p&gt;

&lt;p&gt;What’s more is that we were able to pretty quickly identify repeated code and introduce the right abstractions because we already knew different use cases from the duplicated code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But please be aware that I'm not advocating this kind of development. It's an EXTREME example showing that you don't need to be a perfectionist.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Story 2
&lt;/h2&gt;

&lt;p&gt;I’ve known developers who lived to not repeat themselves. I think that at some point they went from “in general it’s better not to have too much repetition” to “if you repeat any code then you will burn in hell”. This is one of these stories.&lt;/p&gt;

&lt;p&gt;We were working in a company which had multiple related products. And something that one of the developers did blew my mind. They were working on a new application and decided that they could use a two-line function from the previous project (3 line if you count the function’s definition).&lt;/p&gt;

&lt;p&gt;The choice here was simple - just copy these 3 lines of code into the new project. But as a lot of developers think - including this one - “repetition is root of all software evil”. So they &lt;strong&gt;spend two days setting up a common library (including deployment process etc) just so they won’t duplicate 3 lines of code&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Now ask yourself how does that benefit the project and how it gets us closer to delivering on our objectives.&lt;/p&gt;

&lt;h2&gt;
  
  
  The source of all evil
&lt;/h2&gt;

&lt;p&gt;By simply googling “Don’t repeat yourself” I learned that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Repetition is the root of all software evil&lt;/li&gt;
&lt;li&gt;Duplication is waste&lt;/li&gt;
&lt;li&gt;If you do it then you don’t understand how to apply abstractions&lt;/li&gt;
&lt;li&gt;It decreases quality of code&lt;/li&gt;
&lt;li&gt;It should all be eliminated&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It does sound like bad idea, right? But at this point it &lt;strong&gt;sounds like we vilify it&lt;/strong&gt;. It sounds like if you do it then you are a bad developer! Like there isn’t any scenario where you should do it. &lt;strong&gt;But ya’ll use StackOverflow, don’t you?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Did you at any time ask yourself a simple question - is it really &lt;strong&gt;THAT&lt;/strong&gt; bad that I copy and paste a little bit of code? &lt;strong&gt;Does it have any benefits?&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Only a Sith deals in absolutes
&lt;/h2&gt;

&lt;p&gt;Here’s the thing - every rule in software development makes sense at most 80% of the time. Each was coined in some specific context - for which it made sense. But that context got lost in translation and some people began to &lt;strong&gt;follow the rule religiously instead of treating it as a rule of thumb&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This is our fault. We make those principles &lt;strong&gt;sound so absolute&lt;/strong&gt;. Don’t repeat yourself means don’t repeat yourself. Then it’s passed from one person to another, copied over blogs, books over and over until it becomes the truth and all context and all the nuance is lost.&lt;/p&gt;

&lt;p&gt;So here’s an alternative that I think some of you should try:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Try not to repeat yourself too much. But sometimes you can. Because sometimes it may make sense.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It’s not as catchy phrase though.&lt;/p&gt;

&lt;h2&gt;
  
  
  Please repeat yourself
&lt;/h2&gt;

&lt;p&gt;This rant is already getting too lengthy for my taste, so let’s get to the point. There are numerous cases where repeating yourself is not only &lt;strong&gt;not an anti-pattern but it’s actually a tool&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I love repeating myself. Especially when I’m writing tests. I copy tests all over the place and change what’s needed for the given test. This results in a lot of duplication. When I’m done I simply go through these tests and see what’s the best way to reduce (not completely eliminate) repetition and what can be extracted into separate abstractions.&lt;/p&gt;

&lt;p&gt;I could spend a lot of time upfront to figure out how do I want to set up the tests, what helpers do I need, then redoing everything because it turns out that 2 of 25 tests need a little bit different setup. But why would I do this if I can just see where the code takes me? Why not see what’s actually needed instead of doing all this guesswork?&lt;/p&gt;

&lt;p&gt;This is not just for tests, but tests are where this is most obvious and I would encourage you to start there.&lt;/p&gt;

&lt;p&gt;The overuse of &lt;strong&gt;DRY (Don’t Repeat Yourself)&lt;/strong&gt; is an anti-pattern in itself. Overzealous duplication removal leads to bad abstractions because developer &lt;strong&gt;is creating imaginary abstractions instead of uncovering real ones&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Repeating yourself is basically giving yourself the time and space to come up with the right abstractions&lt;/strong&gt; instead of engaging in guesswork and clairvoyance. We don’t know what the future code will be. We don’t understand all the use cases at first or ways in which our code will be used. If we introduce abstractions too soon then in best case we end up rewriting everything.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Repeating yourself is a great tool to uncover abstractions.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What other people say
&lt;/h2&gt;

&lt;p&gt;As you may guessed I’m not the first person to notice this. There are two great articles about this topic:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://kentcdodds.com/blog/aha-programming"&gt;AHA Programming&lt;/a&gt; by Kent C. Dodds&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://sandimetz.com/blog/2016/1/20/the-wrong-abstraction"&gt;The Wrong Abstraction&lt;/a&gt; by Sandi Metz&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You should definitely read them as they extend this article nicely and will give you more understanding on when to use duplication. Here’s a few excerpts:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“duplication is far cheaper than the wrong abstraction”&lt;/p&gt;

&lt;p&gt;”prefer duplication over the wrong abstraction”&lt;/p&gt;

&lt;p&gt;— Sandi Metz, “The Wrong Abstraction”&lt;/p&gt;

&lt;p&gt;“Avoid Hasty Abstractions”&lt;/p&gt;

&lt;p&gt;”Optimize for change first”&lt;/p&gt;

&lt;p&gt;”&lt;strong&gt;the big takeaway&lt;/strong&gt; about AHA Programming is that you shouldn't be dogmatic about when you start writing abstractions but instead write the abstraction when it feels right and don't be afraid to duplicate code until you get there.”&lt;/p&gt;

&lt;p&gt;— Kent C. Dodds, “AHA Programming”&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;I want to be clear that I’m not inviting you to make a mess. I am pointing out that some level of temporary duplication is healthy. First story is supposed to show you that despite what you may think - the success of a product does not depend on that but instead it depends on business development.&lt;/p&gt;

&lt;p&gt;So copy code and modify it when necessary to give yourself space so you can uncover real abstractions instead of imaginary ones. Of course - that’s not the only method to uncover better abstractions. Talking to stakeholders and understanding business better is another way that we will discuss in the future. But it’s not a situation where you need to pick one over the other but rather complementary methods.&lt;/p&gt;

&lt;p&gt;There is a lot of rules of thumb in software development - or “good practices”. Usually they work when you understand context and apply them sensibly. Sadly there is a lot of dogma in software industry, it’s driven by hype and emotions and rarely by pragmatism. So remember that these “good practices” are not “all or nothing” but more of a “try to do this more than the other thing and you’ll be good”.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>beginners</category>
      <category>codenewbie</category>
    </item>
  </channel>
</rss>
