<?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: konrad_126</title>
    <description>The latest articles on DEV Community by konrad_126 (@konrad_126).</description>
    <link>https://dev.to/konrad_126</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%2F57700%2F14fd32cd-f123-4186-8b31-74aaf4cab831.png</url>
      <title>DEV Community: konrad_126</title>
      <link>https://dev.to/konrad_126</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/konrad_126"/>
    <language>en</language>
    <item>
      <title>Keep calm and git bisect</title>
      <dc:creator>konrad_126</dc:creator>
      <pubDate>Sun, 20 Dec 2020 14:17:55 +0000</pubDate>
      <link>https://dev.to/konrad_126/keep-calm-and-git-bisect-1ekf</link>
      <guid>https://dev.to/konrad_126/keep-calm-and-git-bisect-1ekf</guid>
      <description>&lt;p&gt;Your app broke, and you have no idea why? Even worse, you don't even know what commit is causing it to fail? Don't worry - it happens.&lt;/p&gt;

&lt;p&gt;It is important to keep calm and track that first commit that is causing the failure, and git can help you out. Let's see how...&lt;/p&gt;

&lt;h1&gt;
  
  
  Finding the (first) bad apple
&lt;/h1&gt;

&lt;p&gt;You start with what you know for sure - the last (present) commit is bad:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1608471667627%2FU6a68V7L8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1608471667627%2FU6a68V7L8.png" alt="sequantial_1.png"&gt;&lt;/a&gt;&lt;br&gt;
Then you checkout to some (potentially distant) commit in the past where you know things worked (you check it). Let's call it the good commit:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1608471679100%2Fq4xpBxBCU.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1608471679100%2Fq4xpBxBCU.png" alt="sequantial_2.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can be sure that the first bad commit is somewhere between that good commit and the present bad commit:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1608471696058%2FMBxvT0UoR.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1608471696058%2FMBxvT0UoR.png" alt="sequantial_3.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To trace it, you can sequentially go through all those in-between commits and check your app at every step.&lt;/p&gt;

&lt;p&gt;This process will work fine if there are a few commits to check, but what if there are tens or hundreds?&lt;/p&gt;

&lt;p&gt;Because git's commit-graph, in this context, is a sorted list, we can speed up the process by using an algorithm called  &lt;a href="https://www.geeksforgeeks.org/binary-search/" rel="noopener noreferrer"&gt;binary search&lt;/a&gt; .&lt;/p&gt;

&lt;h1&gt;
  
  
  Binary search to the rescue!
&lt;/h1&gt;

&lt;p&gt;You start the same way as before - finding some commit in the (distant) past where things were nice and green:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1608471707788%2FsQZZXmBvm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1608471707788%2FsQZZXmBvm.png" alt="binary_1.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, instead of sequentially checking all the in-between commits, you pick the commit in the middle of your list and check your app's behavior at that point:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1608471746763%2F4VrNxlqpR.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1608471746763%2F4VrNxlqpR.png" alt="binary_2.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If everything works you can consider that commit as a good commit:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1608471762079%2FO6ldynj2x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1608471762079%2FO6ldynj2x.png" alt="binary_good_1.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also be sure that all the commits before it are also good so you don't need to check them individually:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1608471773217%2FcCTXIAIAa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1608471773217%2FcCTXIAIAa.png" alt="binary_good_2.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If, on the other hand, the commit in the middle was bad (your app was broken):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1608471785960%2Fu1Dt5m2lM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1608471785960%2Fu1Dt5m2lM.png" alt="binary_bad_1.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then you'd know for sure that all the commits after it are also bad:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1608471797107%2FkMmZtu1Es.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1608471797107%2FkMmZtu1Es.png" alt="binary_bad_2.png"&gt;&lt;/a&gt;&lt;br&gt;
Either way, you end up with a new list of commits to check that's half in size (with a new god/bad commit pair).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1608471808556%2FBnVlulDpd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1608471808556%2FBnVlulDpd.png" alt="binary_second_Step.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You repeat this process until you pinpoint the exact commit where things went sour. &lt;/p&gt;

&lt;p&gt;Using binary search significantly cuts the time needed to trace the first bad commit, but all this manual checking out to commits still takes time and it's not much fun. Luckily, git has a command called ** &lt;a href="https://git-scm.com/docs/git-bisect" rel="noopener noreferrer"&gt;bisect&lt;/a&gt; ** that will do that for you. All you'll need to do is to decide whether a certain commit is good or bad and git will do the rest.&lt;/p&gt;

&lt;h1&gt;
  
  
  Bisect
&lt;/h1&gt;

&lt;p&gt;To start the bisecting process you type:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1608471824178%2F1MZtJhlz-.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1608471824178%2F1MZtJhlz-.png" alt="cali_start.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then you tell git what commit is bad. If you omit the checksum git will assume it's the last commit on your current branch.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1608471859191%2F_eqN1Hg-r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1608471859191%2F_eqN1Hg-r.png" alt="cli_bisect_bad.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After you tell git what is the "good" commit:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1608471871056%2FIEqnWUKTv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1608471871056%2FIEqnWUKTv.png" alt="cli_bisect_good.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;it will display how many steps are left and immediately checkout to that first (middle) commit. Now you can check your app's behavior and tell git if the commit is good or bad:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1608471897082%2Fv7N9FpvRf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1608471897082%2Fv7N9FpvRf.png" alt="cli_bisect_step.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you do, git moves (checks-out) to the next commit and you repeat the process. After a couple of steps (depending on how big your commit list was), you'll reach the final step and git will inform you what the first bad commit is:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1608471910103%2FmJmXnLx0D.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1608471910103%2FmJmXnLx0D.png" alt="cli_bisect_final_step.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Full Automation
&lt;/h1&gt;

&lt;p&gt;Manually checking those commits to decide if they are good or bad is sometimes necessary, maybe it's some legacy app and there's not a lot of tests so you need to manually check your app. If you are lucky and can write a script to check it for you then becomes fully automated.&lt;/p&gt;

&lt;p&gt;The script needs to be outside of source control (maybe a folder "up") and return exit code 0 if the commit is considered good or 1 if it's considered bad.&lt;/p&gt;

&lt;p&gt;You start the bisect as before, by telling git which commit is good and which is bad. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1608471938666%2F6s5HwZvD_.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1608471938666%2F6s5HwZvD_.png" alt="cli_bisect_run_1.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But now you can tell git to run the bisect process and use your script to decide whether some commit is good or bad:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1608472849818%2FwKSBlP3HR.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1608472849818%2FwKSBlP3HR.png" alt="cli_bisect_run_2.png"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Now you know what commit was the one to introduce the failure (bug), hopefully, you'll be able to figure out the why part of the question.&lt;/p&gt;

</description>
      <category>git</category>
      <category>programming</category>
      <category>bisect</category>
      <category>binary</category>
    </item>
    <item>
      <title>Hexagonal Architecture Demystified</title>
      <dc:creator>konrad_126</dc:creator>
      <pubDate>Sun, 14 Jun 2020 08:38:55 +0000</pubDate>
      <link>https://dev.to/konrad_126/hexagonal-architecture-demystified-3ed9</link>
      <guid>https://dev.to/konrad_126/hexagonal-architecture-demystified-3ed9</guid>
      <description>&lt;p&gt;There’s no shortage of lectures and blogposts on “Hexagonal Architecture” these days, but many of them give a much broader view of Hexagonal Architecture than it was originally presented by its author &lt;a href="https://twitter.com/totheralistair" rel="noopener noreferrer"&gt;Alistar Cockburn&lt;/a&gt;. This can make you feel overwhelmed, so let’s re-visit Alistar's original idea and remove some of the confusion.&lt;/p&gt;

&lt;p&gt;We’ll start the same way Alistar &lt;a href="http://wiki.c2.com/?HexagonalArchitecture" rel="noopener noreferrer"&gt;did&lt;/a&gt;, by looking at traditional Layered Architecture first.&lt;/p&gt;

&lt;h1&gt;
  
  
  Layered Architecture
&lt;/h1&gt;

&lt;p&gt;To help ourselves deal with the complexity of software systems we can divide them into separate layers (based on their levels of abstraction). There’s no limit to the number of layers but authors usually suggest three or four. Here we’re going to use the four-layer model from the blue DDD &lt;a href="https://www.goodreads.com/book/show/179133.Domain_Driven_Design?ac=1&amp;amp;from_search=true" rel="noopener noreferrer"&gt;book&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F9aologckmb510qi2gxc4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F9aologckmb510qi2gxc4.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;User Interface Layer&lt;/strong&gt; — Displays some data to end-users and where end-users interact with the system&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Application Layer&lt;/strong&gt; — Orchestrates Domain objects to perform tasks required by the end-users&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Domain Layer&lt;/strong&gt; — Contains all business logic, the Entities, Events and any other object type that contains Business Logic&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Infrastructure Layer&lt;/strong&gt; — Technical capabilities that support the layers above, e.g. persistence or messaging&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Communication between the layers only goes downwards. In a strict approach, a layer can talk only to a layer directly below it, while in the relaxed approach a layer can talk to all layers below it in the layer stack.&lt;/p&gt;

&lt;p&gt;Traditionally, we also refer to the UI layer as the Front End of our application and the Infrastructure layer as the Back End. The “middle” part I chose to call the Core, but you could also call it the Domain, Business logic, or maybe even the Heart of Software if you wish to be more poetic.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fm5eomcl3hys2lq65h1rg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fm5eomcl3hys2lq65h1rg.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  A different view of a system…
&lt;/h1&gt;

&lt;p&gt;In Alistar’s eyes, there is no big difference between the UI (our web client) and the Database. A system is made of only two distinct parts: the inside and the outside. The inside is our Core and the outside is where the UI and Infrastructure live.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8iicagfoab9b0jnr73z0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8iicagfoab9b0jnr73z0.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this new view of a system, the Database and the Web Client are no longer back end and front end. They are both the same - &lt;strong&gt;outside&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fy53xm9jxdglzvb8jx1bg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fy53xm9jxdglzvb8jx1bg.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In order for Core and the outside world to be able to talk to each other, we need a way of transforming data between different formats they use. For example, our web client speaks HTTP while our application speaks PHP. That is why there is another hexagon wrapping our Core.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fe0ucibr2qbtfrn7s5ifv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fe0ucibr2qbtfrn7s5ifv.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this wrapper, the HTTP requests are transformed into some PHP data structure that our Core can understand, and vice versa. The same goes for our database. We need a way of transforming our PHP data structure (probably objects) into a format of our database (probably relational database). We can call this wrapper the transformer wrapper and this is where Ports and Adapters come into the story.&lt;/p&gt;

&lt;h1&gt;
  
  
  Ports and Adapters
&lt;/h1&gt;

&lt;p&gt;Ports live in your core and they define how to talk to the Core. To do so you need to plug an adapter into them that will transform the input from the outside world format to one accepted by the port.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwm7k7pyovebpnxmjgk7r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwm7k7pyovebpnxmjgk7r.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Going back to our application. In the Core, we have some Use Case. Maybe it’s a command if you are using the Command Query Separation approach or it is just a Service class with a public method. In any case, our web client speaks HTTP and our Core speaks PHP so we need to transform HTTP into PHP and vice versa. So we write our adapter that does just that. This is called a Controller.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjowqerrs3hoq45rfrp5v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjowqerrs3hoq45rfrp5v.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we want to provide the outside world with another way of talking to our Core. Maybe with a CLI. All we have to do is to write another adapter that will take the input from the CLI and transform it into that same PHP format our Core can understand.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fc56oh0oyx9l121a9ras8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fc56oh0oyx9l121a9ras8.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice how we didn’t need to touch the code in the Core to support this new method of talking to our system. The Core is blissfully ignorant of the many different ways of talking to our system from the outside world (it only cares about ports).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fa4034k0u4xxpqhpnhci5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fa4034k0u4xxpqhpnhci5.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The system can be described as a &lt;strong&gt;Core surrounded with interfaces to the outside world&lt;/strong&gt;. Alistar chose to visualize the Core as a Hexagon because it was easier to draw than the pentagon, but also because it gives us a nice visual analogy where one edge of the Hexagon represents one reason of talking to the outside world. There is nothing magical about the number six — you can have a shape with n-edges.&lt;/p&gt;

&lt;p&gt;As we already mentioned, the UI and the Infrastructure are no longer back end and front end but simply outside. So, there is a certain symmetry in this view of the system. However, there is a certain asymmetry to it as well. What that means is that we can divide our ports into two groups: &lt;strong&gt;driving&lt;/strong&gt; ports and &lt;strong&gt;driven&lt;/strong&gt; ports.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffq3rv59c29l2fm5xn7ah.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffq3rv59c29l2fm5xn7ah.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ports are divided based on how they communicate with the Core. When it comes to driving ports, they are the ones initiating the communication with the Core (driving the behavior of our application). In the case of driven ports it is the Core that initiates the communication.&lt;/p&gt;

&lt;p&gt;And this is Hexagonal/Ports And Adapters architecture as presented originally by Alistar. He gave no instructions on how you should structure the code in your Core. Many people tend to use some layering (onion) and mix other architectures with Hexagonal. if you wish to explore more on that I recommend this &lt;a href="https://matthiasnoback.nl/2017/08/layers-ports-and-adapters-part-2-layers/" rel="noopener noreferrer"&gt;article&lt;/a&gt; from &lt;a href="https://twitter.com/matthiasnoback" rel="noopener noreferrer"&gt;Mattias Noback&lt;/a&gt; and &lt;a href="https://herbertograca.com/2017/11/16/explicit-architecture-01-ddd-hexagonal-onion-clean-cqrs-how-i-put-it-all-together/" rel="noopener noreferrer"&gt;this&lt;/a&gt; one from &lt;a href="https://twitter.com/hgracahttps://twitter.com/hgraca" rel="noopener noreferrer"&gt;Herberto Graca&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Why?
&lt;/h1&gt;

&lt;p&gt;Using Ports and Adapters will add some complexity to your architecture and design (as any design or architectural pattern will), so let’s review what some of the main benefits of this architecture are.&lt;/p&gt;

&lt;h2&gt;
  
  
  Delay technical decisions
&lt;/h2&gt;

&lt;p&gt;There is a paradox in how we develop software. At the beginning of a project, when your project (domain) knowledge is at a minimum, we make big technical decisions. Our domain knowledge will only grow over time so wouldn’t it be nice if we could delay those technical decisions to some point in the future when we’ll be able to make a more informed decision?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8gliv5oty911054qagnt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8gliv5oty911054qagnt.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With Ports and Adapters, we can do just that. Say you’re starting a new project and you are not sure what kind of database you should use. You can write your repository adapters in plain PHP that will serialize your entities and save them to a text file. Sure, this solution is not production-ready, but it will allow you to model your domain and to test it, and once you are much more confident about the domain you can pick your database and write real adapters for it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Swap technologies
&lt;/h2&gt;

&lt;p&gt;What about changing your mind? Maybe you realized your choice was wrong, or there is simply a new better technology you want to use.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqes7cshyylyh2c67qe34.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqes7cshyylyh2c67qe34.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Switching between technologies is simply a matter of writing new adapters for those technologies. This, of course, can be hard work but it consists of writing new code, which is always cleaner than modifying the existing one (and why the &lt;a href="https://en.wikipedia.org/wiki/Open%E2%80%93closed_principle" rel="noopener noreferrer"&gt;Open-Closed Principle&lt;/a&gt; is such a good thing).&lt;/p&gt;

&lt;h2&gt;
  
  
  Testability
&lt;/h2&gt;

&lt;p&gt;When it comes to testing, Ports and Adapters architecture enables us to test our application in isolation from external dependencies. &lt;/p&gt;

&lt;p&gt;On the driving side, we can swap our real adapters with testing adapters (our test suite), so when testing business rules in the Core, we don’t need to talk to it through the UI, we can plug in our test suit directly to the Core.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fb1xuhak6rx4dq8dc5chw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fb1xuhak6rx4dq8dc5chw.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the driven side we can swap the driven adapters with testing adapter implementations:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8wto2wg031ogsupo0sei.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8wto2wg031ogsupo0sei.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Don’t get me wrong. You should still write some integration tests to check if your real-infrastructure adapters work, but you don’t need to test that integration every time you’re testing some business rule in your Core.&lt;/p&gt;

&lt;h2&gt;
  
  
  Focus on the core
&lt;/h2&gt;

&lt;p&gt;We mentioned earlier that our core is blissfully unaware of the outside world — the adapters. The only thing our core cares about is the ports that it provides to the outside world. This enables you to not be influenced by technology decisions while developing your Core, so it can be truly domain-driven instead of technology (framework) driven. Now, having you Core entirely free of any technology influence leakage is maybe a bit idealistic, but still, this architecture gives you a high level of decoupling between your domain and business logic and the technologies you use.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fzg9hxb4drus6q1p011dm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fzg9hxb4drus6q1p011dm.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  When
&lt;/h1&gt;

&lt;p&gt;So when should you go for using Ports and Adapters architecture? Well, as always, it depends. It does add some complexity to your design so you need to decide does it pay off. If the benefits it brings are important to you then I’d say go for it.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>learning</category>
      <category>php</category>
      <category>programming</category>
    </item>
    <item>
      <title>Fun Driven Development with PHPSpec</title>
      <dc:creator>konrad_126</dc:creator>
      <pubDate>Fri, 05 Jun 2020 17:39:15 +0000</pubDate>
      <link>https://dev.to/konrad_126/fun-driven-development-with-phpspec-28gf</link>
      <guid>https://dev.to/konrad_126/fun-driven-development-with-phpspec-28gf</guid>
      <description>&lt;p&gt;The first time I saw the abbreviation BDD I thought it was a miss-print of TDD (Test Driven Development), but it’s not. It stands for &lt;em&gt;Behaviour Driven Development&lt;/em&gt; and it is a technique derived from TDD. The difference between the two is a bit nuanced and best felt when you start using some BDD tools. One such tool is &lt;a href="http://www.phpspec.net/en/stable/" rel="noopener noreferrer"&gt;PHPSpec&lt;/a&gt;&lt;span&gt;. It will help you write better code and have fun in the process. Sounds good? Let’s give it a try!&lt;/span&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  There is a dog
&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://www.instagram.com/doggosdoingthings/?hl=hr" rel="noopener noreferrer"&gt;Dogs&lt;/a&gt; are fun so let's build a Dog game:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwkz0n5rngwdw6lz3oll5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwkz0n5rngwdw6lz3oll5.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In PHPSpec you start by creating the specification first. It will describe the Dog class we are going to build:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxtu6zoigcfckz32vj60s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxtu6zoigcfckz32vj60s.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;PHPSpec generates the specification file for us:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;spec\App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Dog&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;PhpSpec\ObjectBehavior&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Prophecy\Argument&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DogSpec&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;ObjectBehavior&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;it_is_initializable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;shouldHaveType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Dog&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It doesn't say (describe) much at the moment - just that the class Dog should be initializable.&lt;/p&gt;

&lt;p&gt;Let's run PHPSPec to see what happens.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fi1wf6vwb30yreqhchxom.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fi1wf6vwb30yreqhchxom.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Whoa, that's a lot of pink! What's up with that? Well, this is how PHPSPec indicates that the code is broken (doesn't even run), which is different than it running but returning wrong results. It is also asking us to fix it by creating the missing Dog class for us. So we comply and we get this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Dog&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After creating the Dog class, it runs again and now we have our first spec passing giving us that green light all devs love so much.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fudmp99wnu00n43uzreg4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fudmp99wnu00n43uzreg4.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Dogs make sounds
&lt;/h2&gt;

&lt;p&gt;As all dog owners will tell you, dogs bark, so let's add this behavior to our doggo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdr3ilyoqgoe6alqn18ed.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdr3ilyoqgoe6alqn18ed.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We describe the desired behaviour in the spec class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="c1"&gt;# spec/App&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DogSpec&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;ObjectBehavior&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;

    &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;it_should_make_a_sound&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;makeSound&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;shouldBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Vuf Vuf'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;I know. This looks a bit wired. We are calling the &lt;code&gt;makeSound&lt;/code&gt; method but there is no such method in our spec class. And there won't be. The &lt;code&gt;$this&lt;/code&gt; keyword in a spec class doesn't refer to the spec class itself, but to the class the spec is describing. In this case, &lt;code&gt;DogSpec&lt;/code&gt; described the &lt;code&gt;Dog&lt;/code&gt; class, so PHPSpec will try to call the &lt;code&gt;makeSound&lt;/code&gt; method on the &lt;code&gt;Dog&lt;/code&gt; class. (There is always one spec class per class).&lt;/p&gt;

&lt;p&gt;Another wired thing is the &lt;code&gt;shouldBe&lt;/code&gt; method chained to the &lt;code&gt;makeSound&lt;/code&gt; method. This is what is called a &lt;strong&gt;matcher&lt;/strong&gt; in PHPSpec and it's equivalent to PHPUnit's assertions (and there's a bunch of them). In this case, it will take the output of the &lt;code&gt;makeSound&lt;/code&gt; method and check if it matches &lt;code&gt;Vuf Vuf&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now that we've straightened that out, we can run &lt;span&gt;PHPSpec&lt;/span&gt; again:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fp1w1wc3cv7jxj7etsulr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fp1w1wc3cv7jxj7etsulr.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since we don't have the &lt;code&gt;makeSound()&lt;/code&gt; method on our Dog class yet, there's that purple color again and there's PHPSpec again being nice and helpful offering to create the method for us.&lt;/p&gt;

&lt;p&gt;After creating the method it runs again and now we finally have some red color meaning the code works but not as expected.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fizejzc10robu9f0dlt4b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fizejzc10robu9f0dlt4b.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Time to write some code and get us back to green!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="c1"&gt;# src/App&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Dog&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;makeSound&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s1"&gt;'Vuf Vuf'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Stubs
&lt;/h1&gt;

&lt;p&gt;Our object often time collaborate with other objects by asking them questions (and doing something with the answer). If we go back to our pet game, dogs are usually very happy to great people:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdr3ilyoqgoe6alqn18ed.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdr3ilyoqgoe6alqn18ed.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To describe this in our specification we'll need a &lt;strong&gt;&lt;span&gt;stub&lt;/span&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="c1"&gt;# spec/App&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DogSpec&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;ObjectBehavior&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;

    &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;it_can_greet_a_person&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Person&lt;/span&gt; &lt;span class="nv"&gt;$person&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$person&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;willReturn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Mike'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$person&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;shouldBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Hello Mike, Vuf Vuf'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Looking at this, you may be wondering where is some &lt;code&gt;createTestDouble()&lt;/code&gt; method call? In PHPSpec you just inject classes/objects you need and PHPSpec will create test doubles out of them (using prophecy framework) so you can immediately configure them. Here, we are stating the person's class &lt;code&gt;name()&lt;/code&gt; method will return &lt;code&gt;Mike&lt;/code&gt; when called.&lt;/p&gt;

&lt;p&gt;By now you can assume when we run PHPSpec it will offer to create the actual &lt;code&gt;Person&lt;/code&gt; class for us, right?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F2mgfvb97ywy93im73d3v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F2mgfvb97ywy93im73d3v.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But wait. It says "Would you like me to generate an &lt;strong&gt;&lt;span&gt;interface&lt;/span&gt;&lt;/strong&gt;". Why not a class? Hm, now that I think about it, dogs also like to greet other dogs not just humans, so maybe there is an abstraction here that we missed. Let's introduce an interface called &lt;code&gt;Named&lt;/code&gt; and make our &lt;code&gt;Dog&lt;/code&gt; class is dependent on an interface instead of a concrete class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="c1"&gt;# spec/App&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DogSpec&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;ObjectBehavior&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;

    &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;it_can_greet_a_person&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Named&lt;/span&gt; &lt;span class="nv"&gt;$named&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$named&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;willReturn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Mike'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$named&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;shouldBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Hello Mike, Vuf Vuf'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now our &lt;span&gt;Dog&lt;/span&gt; can greet any class that implements the &lt;code&gt;Named&lt;/code&gt; interface. This design will make it easy to expand the list of earthlings our doggos can greet - just implement the &lt;code&gt;Named&lt;/code&gt; interface. Thnx PHPSpec!&lt;/p&gt;

&lt;p&gt;We can let PHPSpec make that interface and the greet method for us now&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F83xnnkemp0xiwjw6iqdn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F83xnnkemp0xiwjw6iqdn.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And now we can implement our greet method to get us back to green again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="c1"&gt;# src/App&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Dog&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;makeSound&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="s1"&gt;'Vuf Vuf'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Named&lt;/span&gt; &lt;span class="nv"&gt;$named&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="s1"&gt;'Hello '&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;$named&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;'Vuf Vuf'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Mocks and Spies
&lt;/h1&gt;

&lt;p&gt;Let's say for business reason, every time a Dog greets someone we want to our application to log that information.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F7hrp8huy1js4jz9z8n2a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F7hrp8huy1js4jz9z8n2a.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this case, our object is going to issue commands to other objects, so we need a mock or spy. First, we are going to state that &lt;code&gt;Dog&lt;/code&gt; will be constructed with a &lt;code&gt;Logger&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="c1"&gt;# spec/App&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DogSpec&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;ObjectBehavior&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;let&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Logger&lt;/span&gt; &lt;span class="nv"&gt;$logger&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;beConstructedWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$logger&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can describe the interaction with a &lt;code&gt;Logger&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="c1"&gt;# spec/App&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DogSpec&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;ObjectBehavior&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="c1"&gt;/// ...&lt;/span&gt;
    &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;it_logs_the_greeting&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Named&lt;/span&gt; &lt;span class="nv"&gt;$named&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Logger&lt;/span&gt; &lt;span class="nv"&gt;$logger&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$named&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;willReturn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Marry'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nv"&gt;$logger&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Hello Marry, Vuf Vuf'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;shouldBeCalled&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$named&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are setting an expectation that the log method will be called with &lt;code&gt;Hello Mike, Vuf Vuf&lt;/code&gt; once we execute our code. This is a &lt;strong&gt;mock&lt;/strong&gt;. If we wish to use a &lt;strong&gt;spy&lt;/strong&gt; we would describe it as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="c1"&gt;# spec/App&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DogSpec&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;ObjectBehavior&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="c1"&gt;/// ...&lt;/span&gt;
    &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;it_logs_the_greeting&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Named&lt;/span&gt; &lt;span class="nv"&gt;$named&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Logger&lt;/span&gt; &lt;span class="nv"&gt;$logger&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$named&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;willReturn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Mike'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$named&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nv"&gt;$logger&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Hello Mike, Vuf Vuf'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;shouldHaveBeCalled&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As always, PHPSpec will help us by creating some methods or us:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fp1w1wc3cv7jxj7etsulr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fp1w1wc3cv7jxj7etsulr.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then it's up to us to add some code to satisfy the spec:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="c1"&gt;# src/App&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Dog&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="c1"&gt;// ...&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Named&lt;/span&gt; &lt;span class="nv"&gt;$named&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$greeting&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Hello '&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;$named&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;', Vuf Vuf'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$greeting&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$greeting&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;span&gt;As you see, in PHPSpec we &lt;/span&gt;&lt;strong&gt;&lt;span&gt;describe&lt;/span&gt;&lt;/strong&gt;&lt;span&gt; our object behaviors using a very descriptive syntax. There is always one spec per object/class which is why PHPSpec can only be used for testing at the unit layer/level. If you want to have some higher-level test you'll need to use some other tool. Maybe another BDD tool as &lt;/span&gt;&lt;a href="https://docs.behat.org/en/latest/" rel="noopener noreferrer"&gt;&lt;span&gt;Behat&lt;/span&gt;&lt;/a&gt;&lt;span&gt; (don't get me started on how cool Behat is)? Another thing you probably don't want to do is introduce PHPSpec in a legacy codebase (with bad design). It will be painful and authors of PHPSpec never intended it to be used that way. But if you are starting a greenfield project, why not give PHPSpec a try. Hope you'll find is as fun as I do.&lt;/span&gt;&lt;/p&gt;

</description>
      <category>php</category>
      <category>programming</category>
      <category>testing</category>
      <category>tdd</category>
    </item>
    <item>
      <title>Pointers and tips: dispelling the magic of git merge</title>
      <dc:creator>konrad_126</dc:creator>
      <pubDate>Sun, 31 May 2020 09:52:03 +0000</pubDate>
      <link>https://dev.to/konrad_126/pointers-and-tips-dispelling-the-magic-of-git-merge-2hja</link>
      <guid>https://dev.to/konrad_126/pointers-and-tips-dispelling-the-magic-of-git-merge-2hja</guid>
      <description>&lt;p&gt;&lt;em&gt;Creating branches in git is blazingly fast and having a bunch of them is pretty cheap. This means we get to merge them quite often. But how is a branch represented internally and what does it mean to merge them? Understanding how this works internally will help you understand why merge conflicts occur. Let’s dispel the magic.&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Branches as pointers
&lt;/h1&gt;

&lt;p&gt;If we visualize git’s commit history, each commit is represented as a node on a graph. Each commit has a connection to its parent; we can only travel from a commit to its parent(s) when traversing the graph:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F48oo5d29oyidekc9gsak.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F48oo5d29oyidekc9gsak.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We know in reality git uses those random-looking strings as commit identifiers (checksum headers) so let’s use them too:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fb60nmbkly2bf0egdyy43.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fb60nmbkly2bf0egdyy43.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It’s very intuitive to think of a branch as a list of commits, but a branch in git is just a pointer (reference) to a commit:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fre988fi4q1p0mq6t4ndn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fre988fi4q1p0mq6t4ndn.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The commit that the branch references is the last commit on that branch, so we also call it the &lt;strong&gt;tip&lt;/strong&gt; of the branch.&lt;/p&gt;

&lt;p&gt;We know that when we use git log command, git shows a list of all commits on the branch, not just a single commit, so how does this work?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fayjn86kd95cjsanzy2an.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fayjn86kd95cjsanzy2an.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Well, if and when git needs the full list of commits that a branch contains (in this example &lt;code&gt;master&lt;/code&gt;), it will generate it by traversing the commit-graph starting from the tip of the branch:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fcoxt3toxp8ie6rnp11wx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fcoxt3toxp8ie6rnp11wx.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can still think of branches as lists of commits, but git doesn’t need to keep this full list stored somewhere all the time. It only needs to keep track of the tips of the branches and simply generate the full list when it’s needed&lt;/p&gt;

&lt;h1&gt;
  
  
  Everything is in the commit
&lt;/h1&gt;

&lt;p&gt;We can think of commits as points in time in the history of our project. Every one of these points represents the changes made to the project at that point. In git, every commit also includes the full state of your project at the point of the commit.&lt;/p&gt;

&lt;p&gt;This means when you checkout to a specific branch git doesn’t need to traverse its full list of commits (applying changes from each commit) to recreate the state of your project (to match that branch). It only needs to look at the tip of the branch.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://medium.com/hackernoon/https-medium-com-zspajich-understanding-git-data-model-95eb16cc99f5" rel="noopener noreferrer"&gt;reality&lt;/a&gt; is a bit more complex but you can think of it as every commit containing a list of all the files in your project with the version identifier of the file. In this simple example we have only three files in our project and have committed the initial version of them in our first commit:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0cc19kf8ap1rbi0xdf3p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0cc19kf8ap1rbi0xdf3p.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If we change the &lt;code&gt;kernel.php&lt;/code&gt; file and commit those changes, the next commit will still contain the same list of files, but the version identifier for &lt;code&gt;kernel.php&lt;/code&gt; will be updated.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0a9z1wxvr5yy23txuiwr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0a9z1wxvr5yy23txuiwr.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Git uses these version identifiers to quickly search its &lt;strong&gt;data storage&lt;/strong&gt; for the object containing the content of that exact version of the file. Different version identifiers for the same file mean the content of the file has changed.&lt;/p&gt;

&lt;p&gt;Now that we know how git branches are represented at a low-level, let’s see what it means to merge them.&lt;/p&gt;

&lt;h1&gt;
  
  
  Merge
&lt;/h1&gt;

&lt;p&gt;Going back to our example, suppose our shiny new feature is done and we want to merge it to the &lt;code&gt;master&lt;/code&gt; branch. In other words, we want the changes we did on the &lt;code&gt;feature&lt;/code&gt; branch to be present on the &lt;code&gt;master&lt;/code&gt; branch as well.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fkqvire8133xn4jg3gc0g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fkqvire8133xn4jg3gc0g.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If we traverse the commit-graph starting from the tip of the &lt;code&gt;master&lt;/code&gt; branch, we can see that those two commits from the &lt;code&gt;feature&lt;/code&gt; branch are not accessible from that tip. This, in turn, means the changes we did on those commits are also not present on the &lt;code&gt;master&lt;/code&gt; branch.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F51ww09gxo4hlbpb2c326.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F51ww09gxo4hlbpb2c326.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The result we want to achieve by the merge is to make those commits accessible from the tip of the &lt;code&gt;master&lt;/code&gt; branch.&lt;/p&gt;

&lt;p&gt;The first step in the merge is to find the merge base commit. This is the commit after which our branches diverged. Git finds it by going to the tips of both &lt;code&gt;feature&lt;/code&gt; and &lt;code&gt;master&lt;/code&gt; branches and traversing the commit-graph until it finds the first commit that is accessible from the tips of both branches:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Faj9px6s3jfhuyyjgq3do.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Faj9px6s3jfhuyyjgq3do.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once it has located the merge &lt;strong&gt;base&lt;/strong&gt;, git will start building the new &lt;strong&gt;merge commit&lt;/strong&gt;. This merge commit, once it’s done, will have an interesting property — it will have two parents.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjk3216m7esycyevwbw6z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjk3216m7esycyevwbw6z.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The first parent will be the current tip of the &lt;code&gt;master&lt;/code&gt; branch and the second the current tip of the &lt;code&gt;feature&lt;/code&gt; branch. Because of this property, the new merge commit will have access to all the commits from the &lt;code&gt;master&lt;/code&gt; branch but also to those two new &lt;code&gt;feature&lt;/code&gt; branch commits as well.&lt;/p&gt;

&lt;p&gt;To construct that new merge commit git needs to decide what versions of our files go into it. To do so, git will compare information from the merge base and the tips of &lt;code&gt;master&lt;/code&gt; and &lt;code&gt;feature&lt;/code&gt; branches:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fk0bfyxmdjbbwpjs7jres.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fk0bfyxmdjbbwpjs7jres.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The first file in the commit’s list is &lt;code&gt;app.php&lt;/code&gt;. Git compares the file version identifiers in the merge base commit (&lt;code&gt;539&lt;/code&gt;) with the ones in the tips of &lt;code&gt;master&lt;/code&gt; and &lt;code&gt;feature&lt;/code&gt;. The version identifier on the &lt;code&gt;master&lt;/code&gt; branch (&lt;code&gt;df5&lt;/code&gt;) is different than in the merge base (&lt;code&gt;24e&lt;/code&gt;) while the tip of the &lt;code&gt;feature&lt;/code&gt; branch has the same identifier (&lt;code&gt;24e&lt;/code&gt;) as the merge base. This means we have only changed the &lt;code&gt;app.php&lt;/code&gt; on the &lt;code&gt;master&lt;/code&gt; branch so this is the version git will put in the new merge commit.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fo97odmdfr8z561twr7bq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fo97odmdfr8z561twr7bq.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The next file in the list is &lt;code&gt;kernel.php&lt;/code&gt;. The situation is a bit simpler now since we didn’t change this file on either of our branches. Git knows this because the version identifier is the same in all 3 places (&lt;code&gt;ea3&lt;/code&gt;) so git will take the version from the base commit and put it into the merge commit.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Flbv2kmcklgk2k43ir8iz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Flbv2kmcklgk2k43ir8iz.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, when looking at the last file on the list (&lt;code&gt;README.md&lt;/code&gt;), git sees we changed it on the &lt;code&gt;feature&lt;/code&gt; branch only so it’s again smart enough to realize that it can take that version (changes) and put it into the new merge commit.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0upzykbxp71ni7aq4pxz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0upzykbxp71ni7aq4pxz.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the merge commit is constructed the only step left is to update the &lt;code&gt;master&lt;/code&gt; branch pointer to point to the new merge commit, which is now the new tip of the &lt;code&gt;master&lt;/code&gt; branch.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fab8bg2hgfnpp90r6alof.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fab8bg2hgfnpp90r6alof.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From this new tip, those commits made on the &lt;code&gt;feature&lt;/code&gt; branch are now accessible so the changes we did on those commits are also present on the &lt;code&gt;master&lt;/code&gt; branch.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6quoh02gask4uowu1r3c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6quoh02gask4uowu1r3c.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  What about conflicts?
&lt;/h1&gt;

&lt;p&gt;Git can be smart enough to do the merge automatically as long as we didn’t change the same file on both branches. If that is the case, we have a conflict and git needs our help.&lt;/p&gt;

&lt;p&gt;Consider the scenario from before with a minor difference. This time when git is trying to construct the new merge commit it finds we have changed the &lt;code&gt;README.md&lt;/code&gt; file on both of our branches.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fs34n6iwesjvjvfm2kdru.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fs34n6iwesjvjvfm2kdru.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Git cannot read our minds and know which of these file versions (changes) is more important to us, so it will stop the automatic merge process and ask for help.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F7vj1rq4xrx3zwtfnlwn1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F7vj1rq4xrx3zwtfnlwn1.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The message git gives us is to fix the conflict in the &lt;code&gt;README.md&lt;/code&gt; file and then manually create the merge commit by using the commit command. So, let’s fix that conflict.&lt;/p&gt;

&lt;p&gt;If you open the &lt;code&gt;README.md&lt;/code&gt; file you will see git has added textual markers to it to indicate the conflict.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fst15zn2yum3uzb5mdmmp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fst15zn2yum3uzb5mdmmp.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The content between the &lt;code&gt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; HEAD&lt;/code&gt; and &lt;code&gt;=======&lt;/code&gt;is how this line of the &lt;code&gt;README.md&lt;/code&gt; file looks on the &lt;code&gt;master&lt;/code&gt; branch while the content between the &lt;code&gt;=======&lt;/code&gt; and &lt;code&gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt; feature&lt;/code&gt; is how it looks on the &lt;code&gt;feature&lt;/code&gt; branch. To resolve the conflict you simply need to make the file look as you want it. In this case, we want the &lt;code&gt;Hello Mars&lt;/code&gt; text so we would delete the markers and the &lt;code&gt;Hello Earth&lt;/code&gt; line:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1ptutyx1vdfquiybb9sq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1ptutyx1vdfquiybb9sq.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we need to type &lt;code&gt;git add README.md&lt;/code&gt; to let git know we have resolved the conflict and git commit to actually make the new merge commit. Git will give it the automatic Merge branch ‘feature’ commit message but you can also change it to whatever you want.&lt;/p&gt;

&lt;p&gt;People usually use a GUI tool, such as SourceTree or the one built into your IDE, to resolve conflicts because manually inspecting the files and making sense of those textual markers git gives can become cumbersome.&lt;/p&gt;

&lt;h1&gt;
  
  
  Fast Forward
&lt;/h1&gt;

&lt;p&gt;Because branches in git are just pointers to commits, merging can become quite a trivial operation at times. Consider this example:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3v3hzd8uz4iuh7kf71mi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3v3hzd8uz4iuh7kf71mi.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We have created a &lt;code&gt;feature&lt;/code&gt; branch and made some commits on it, but in the meanwhile, we didn’t do any changes (commits) on the &lt;code&gt;master&lt;/code&gt; branch. We can say that the tip of the &lt;code&gt;feature&lt;/code&gt; branch is ahead of the tip of the &lt;code&gt;master&lt;/code&gt; branch (by two commits). This becomes even more clear if we slightly modify our visualization:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqlrauxrybushouzsw05t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqlrauxrybushouzsw05t.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As we showed, to merge the &lt;code&gt;feature&lt;/code&gt; branch into &lt;code&gt;master&lt;/code&gt; means to make those two commits from the &lt;code&gt;feature&lt;/code&gt; branch accessible from the tip of the &lt;code&gt;master&lt;/code&gt; branch. To do so git can simply move the tip of the &lt;code&gt;master&lt;/code&gt; branch &lt;strong&gt;forward&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fedoqno75egkm6fvj2w7v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fedoqno75egkm6fvj2w7v.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The only caveat here is that git will not create that special merge commit, so by looking at the history log of the &lt;code&gt;master&lt;/code&gt; branch, you won’t be able to tell it was merged with the &lt;code&gt;feature&lt;/code&gt; branch at some point. If you do need this information, you can pass the &lt;code&gt;— no-ff&lt;/code&gt; flag to the merge command and it will always create the merge commit.&lt;/p&gt;




&lt;p&gt;To answer our questions from the beginning, branches in git are just &lt;strong&gt;pointers&lt;/strong&gt; to commits (tips), and merging branches is all about making commits &lt;strong&gt;accessible&lt;/strong&gt; from the tips of branches. I hope with this understanding of the way that git works you see through the magic. Now you will be better suited to tackle any problems you have with branching. So merge often, have fewer conflicts, and live long and prosper!&lt;/p&gt;

</description>
      <category>git</category>
      <category>merge</category>
      <category>beginners</category>
    </item>
    <item>
      <title>It’s contextual</title>
      <dc:creator>konrad_126</dc:creator>
      <pubDate>Thu, 28 May 2020 12:41:55 +0000</pubDate>
      <link>https://dev.to/konrad_126/it-s-contextual-33n5</link>
      <guid>https://dev.to/konrad_126/it-s-contextual-33n5</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;“There is nothing either good or bad, but thinking makes it so”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A timeless comment on the human condition by Shakespeare’s &lt;a href="https://www.goodreads.com/quotes/21959-there-is-nothing-either-good-or-bad-but-thinking-makes"&gt;Hamlet&lt;/a&gt;. It came to my mind as I was attending &lt;a href="https://www.meetup.com/GOTO-Nights-Berlin/events/269764988/"&gt;GOTO Online Bookclub&lt;/a&gt; featuring &lt;a href="https://twitter.com/KevlinHenney"&gt;Kevlin Hanney&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The topic of the day was Udi Dahan’s &lt;a href="https://97-things-every-x-should-know.gitbooks.io/97-things-every-programmer-should-know/content/en/thing_07/"&gt;Beware the share&lt;/a&gt; essay from the 97 things every programmer should know book. In it, Udi shares a story of his first job. Coming fresh from college, eager to prove himself, he looked for every opportunity to improve the codebase by pulling out shared code into libraries, only to find out during code review, that other developers were not too happy about it. On the contrary — reuse was frowned upon!&lt;/p&gt;

&lt;p&gt;Kevlin opened the session by pointing out how Udi’s essay stands in contrast to another essay from the same book — &lt;a href="https://97-things-every-x-should-know.gitbooks.io/97-things-every-programmer-should-know/content/en/thing_30/"&gt;Don’t repeat yourself&lt;/a&gt; by Steve Smith, which is all about the dangers of duplicate code (logic).&lt;br&gt;
So who is right, Udi or Steve? They both are.&lt;/p&gt;

&lt;h2&gt;
  
  
  The duality of life
&lt;/h2&gt;

&lt;p&gt;This kind of duality is not unique to software development. We come across it often in life, but it can still confuse or even scare people. We tend to seek easy, one-size-fits-all, solutions and if both Udi and Steve are right then how do we choose whose advice to follow?&lt;/p&gt;

&lt;p&gt;Later in his essay, Udi states he came to realize he missed the critical part when blindly applying his eliminate code duplication rule — &lt;strong&gt;context&lt;/strong&gt;. It is the context that matters and creating those shared libraries also came at a cost (increasing the dependencies between code that is using those libraries).&lt;/p&gt;

&lt;p&gt;Kevlin continued on this, generalizing it to all software design patterns, principles, guidelines… Their usability and benefits are dependent on the particular context you are applying them in. And &lt;em&gt;“context is a function of time”&lt;/em&gt;, so you need to be ready to re-asses your decisions as time goes by. Decisions that were perfectly reasonable at the time you made them, can become wrong with the passage of time (change of context).&lt;/p&gt;

&lt;h2&gt;
  
  
  What to do?
&lt;/h2&gt;

&lt;p&gt;Hamlet is right but accepting this fact doesn’t mean we should be paralyzed by our lack of total understanding. We should act to the best of abilities given the current context (knowledge). But we should also understand how highly contextual all our decisions are and be ready to re-asses them as the context changes. Design patterns, “rules” and guidelines are there to help us but we should not lose sight of the context in which they are to be applied.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Visualizing technical debt with Quality Views</title>
      <dc:creator>konrad_126</dc:creator>
      <pubDate>Fri, 15 May 2020 13:25:00 +0000</pubDate>
      <link>https://dev.to/konrad_126/visualizing-technical-debt-with-quality-views-59e7</link>
      <guid>https://dev.to/konrad_126/visualizing-technical-debt-with-quality-views-59e7</guid>
      <description>&lt;p&gt;In his &lt;a href="https://www.joelonsoftware.com/2002/02/13/the-iceberg-secret-revealed/" rel="noopener noreferrer"&gt;The Iceberg Secret, Revealed&lt;/a&gt; blog post, &lt;a href="https://twitter.com/spolsky" rel="noopener noreferrer"&gt;Joel Spolsky&lt;/a&gt; compares software with icebergs:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You know how an iceberg is 90% underwater? Well, most software is like that too — there’s a pretty user interface that takes about 10% of the work, and then 90% of the programming work is under the covers&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8p81ps1cr081g3i2n85h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8p81ps1cr081g3i2n85h.png" alt="Image of an iceberg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Later in his text, he lets us in on a little secret:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;People who aren’t programmers do not understand this.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And what's even harder for people who are not programmers to understand is how bad the "underwater" part can be (especially if the visible part looks fine). It can be hard to grasp, it can have fixes that are software development versions of duck taping a bike tire, it can be poorly or non documented...&lt;/p&gt;

&lt;p&gt;You know what I'm talking about. &lt;strong&gt;Technical Debt&lt;/strong&gt;. Just hearing the word makes your spine shiver. And communicating this to non-programmers can be very hard because&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;for a component that appears to be working, a non-programmer will assume the technical debt is minimal, or nonexistent.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;During his &lt;em&gt;Dealing with legacy code&lt;/em&gt; talk at the &lt;em&gt;Software Craftsmanship&lt;/em&gt; meetup in Berlin, &lt;a href="https://twitter.com/mfeathers" rel="noopener noreferrer"&gt;Michal Feathers&lt;/a&gt; briefly mentioned a technique of displaying technical depth visually. I didn't catch the name of the technique so I got him to write me a not after the talk:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fp0rad0sr4kdx0mktwtwj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fp0rad0sr4kdx0mktwtwj.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It took some deciphering but I managed to get to the source. It was &lt;a href="https://twitter.com/breckcs?lang=hr" rel="noopener noreferrer"&gt;Colin Breck&lt;/a&gt;, an engineer/team lead at Tesla.&lt;/p&gt;

&lt;p&gt;Inspired by a few different sources (including Michael Feathers talk on &lt;a href="https://www.youtube.com/watch?v=odJ8esf2h6E" rel="noopener noreferrer"&gt;Conway’s Law&lt;/a&gt;) he developed a&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;way to represent complex systems, or systems that are not customer-facing—like infrastructure platforms—to people who are non-technical, or not intimately familiar with the software.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The main information this representation conveys is the internal quality of the system components. Hence the name, &lt;strong&gt;&lt;span&gt;Quality Views&lt;/span&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The idea is rather simple. First, you represent your system with an architecture graph.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F5w802kk6tkvpyn0fnm1x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F5w802kk6tkvpyn0fnm1x.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The size of the elements represents the "relative size of the servers in terms of memory, cores, and IO capacity". For example, legacy load balancer servers are smaller than the "new" ones. Dashed lines represent system boundaries and the arrows show the flow of data (the thicker the arrow the bigger the flow). So, a nice graph rich in information but nothing new. I'm sure you've drawn a graph or two similar to this one.&lt;/p&gt;

&lt;p&gt;The next thing that Colin does is he adds "information related to software quality and how the system is evolving" to this graph.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fd41ngyhfi30obi8hfpo3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fd41ngyhfi30obi8hfpo3.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The way he does that is rather simple. The quality is color-coded. So, in this case, the closer to red the worse the quality.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F194e9tsd8duc7zm18qbx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F194e9tsd8duc7zm18qbx.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To evaluate the quality of each component Colin developed a set of criteria, with each criterion contributing to the overall quality grade of a component. His criteria are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Code&lt;/li&gt;
&lt;li&gt;  Tests&lt;/li&gt;
&lt;li&gt;  Deployment&lt;/li&gt;
&lt;li&gt;  Monitoring&lt;/li&gt;
&lt;li&gt;  Alerting&lt;/li&gt;
&lt;li&gt;  Security&lt;/li&gt;
&lt;li&gt;  High-Availability&lt;/li&gt;
&lt;li&gt;  Scalability&lt;/li&gt;
&lt;li&gt;  Risks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And for each, there is a set of questions who serve as a checklist for each grade. Now, this is a set of criteria he developed for his use case, you can (and probably should) develop your own set of criteria. Also, you can introduce weights to these criteria because not all of them may be of the same importance to you.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fc5wu9it2xtmrlh7yk648.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fc5wu9it2xtmrlh7yk648.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you have your criteria set, you get a nice visual representation of Technical Debt that everyone, including non-technical people, can understand. Now, when planing a new feature, your manager can know how risky it is given the quality of components it requires work on. Also, this graph highlights the things you are not working on. And the risk of having a lot of (or relying on) low-quality components becomes harder to ignore since it's constantly present in this visual display.&lt;/p&gt;

&lt;p&gt;Another thing, that can be a side effect of using Quality Views, is that it can also motivate your team. Internal code/infrastructure improvements often don't have a direct tangible effect on the application (the visible part of the iceberg) and using a quality view will give your developers (as well as PMs) just that - a tangible visual representation of the improvements done.&lt;/p&gt;

&lt;p&gt;If you wish to explore Quality View more deeply I suggest you watch the presentation &lt;a href="https://www.infoq.com/presentations/quality-views-technical-debt/" rel="noopener noreferrer"&gt;Using Quality Views to Tackle Tech Debt @Tesla&lt;/a&gt; Colin gave at QCon London, as well as reading his two blog posts on the subject: &lt;a href="https://blog.colinbreck.com/using-quality-views-to-communicate-software-quality-and-evolution/" rel="noopener noreferrer"&gt;Using Quality Views to Communicate Software Quality and Evolution&lt;/a&gt; and &lt;a href="https://blog.colinbreck.com/reflections-on-using-quality-views/" rel="noopener noreferrer"&gt;Reflections on Using Quality Views&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;&lt;code&gt;*&lt;/code&gt; images are taken from &lt;a href="https://www.infoq.com/presentations/quality-views-technical-debt/" rel="noopener noreferrer"&gt;https://www.infoq.com/presentations/quality-views-technical-debt/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>codequality</category>
      <category>learning</category>
    </item>
    <item>
      <title>Get, set... STOP!</title>
      <dc:creator>konrad_126</dc:creator>
      <pubDate>Tue, 12 May 2020 14:56:36 +0000</pubDate>
      <link>https://dev.to/konrad_126/get-set-stop-2210</link>
      <guid>https://dev.to/konrad_126/get-set-stop-2210</guid>
      <description>&lt;p&gt;&lt;em&gt;What if I told you &lt;a href="https://matrix.fandom.com/wiki/Morpheus"&gt;Morpheus&lt;/a&gt; never said: “What if I told you?” I know you saw that meme a thousand times but have you actually heard him say it in the movie? You didn’t, because it didn’t happen. Darth Vader also never said “Luke, I am your father” and Captain Kirk never said, “Beam me up, Scotty”. People keep repeating these “quotes” so we assume they are true.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Cargo Cult
&lt;/h2&gt;

&lt;p&gt;This phenomenon is not limited to spoken word — it afflicts human behaviors also. Since software is developed by humans (for now), we come across it in software development. It’s called cargo cult programming and &lt;a href="https://en.wikipedia.org/wiki/Cargo_cult_programming"&gt;Wikipedia&lt;/a&gt; defines it as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Ritual inclusion of code or program structures that serve no real purpose.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;One practice that is widespread among developers is the creation of getters and setters. They always come together and we create them as soon as the entity is created. This is so deeply engrained in our workflow that nowadays IDEs offer to automatically generate these getters and setters for us.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--a1Xl-xVR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/a8dl2v9j7s387bkdm6z9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--a1Xl-xVR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/a8dl2v9j7s387bkdm6z9.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But is there a reason for doing this or is it just a ritual we have accepted without stopping to wonder why?&lt;/p&gt;

&lt;h2&gt;
  
  
  Set the lights to off
&lt;/h2&gt;

&lt;p&gt;Let’s look at the &lt;em&gt;setters&lt;/em&gt; first. By setters I mean methods like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;setName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$name&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This method clearly changes the name of the object in question. In the real world, we call this renaming. I have never heard someone say that a person has &lt;em&gt;“set its name to another name”&lt;/em&gt;. Even if you ask the developer who wrote the method chances are they will tell you that it renames the object. So, here’s an interesting proposition for you: if renaming is what the method does, call it &lt;em&gt;rename&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;rename&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$name&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now our method name describes precisely what our method does and we used a domain-specific word for it. The (domain) concept of renaming a user is reflected in our code. This gives developers and non-developers a common (&lt;a href="https://martinfowler.com/bliki/UbiquitousLanguage.html"&gt;ubiquitous&lt;/a&gt;) language when discussing the project.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GeLLzTce--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/hkya50e8w785mf8hqmwo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GeLLzTce--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/hkya50e8w785mf8hqmwo.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s look at another example. Say we have a &lt;code&gt;Subscription&lt;/code&gt; class with the following setter method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;setActive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nv"&gt;$active&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;active&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$active&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;As with the previous example, this method doesn’t clearly reflect the domain concept which is activating and deactivating a subscription. So we split it into:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;activate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;active&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;deactivate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;active&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Again we have expressed these concepts explicitly in our code; furthermore, there is another benefit gained by this refactoring. Having a setter method allowed the outside world to set the internal state of the &lt;code&gt;Subscription&lt;/code&gt; object, whereas now, the &lt;code&gt;Subscription&lt;/code&gt; object is responsible for setting its own internal state. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ghBXWwUC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/c8cwld3zrpa6lp7xkv4o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ghBXWwUC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/c8cwld3zrpa6lp7xkv4o.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Anemic vs. Rich
&lt;/h2&gt;

&lt;p&gt;By having myriad setter methods on your entity, you end up with what’s called the anemic domain model.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt; 
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;setName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
    &lt;span class="c1"&gt;//...&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;setBirthDate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;DateTime&lt;/span&gt; &lt;span class="nv"&gt;$date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
    &lt;span class="c1"&gt;//...&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;setAddress&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Address&lt;/span&gt; &lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
    &lt;span class="c1"&gt;//...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Your &lt;code&gt;User&lt;/code&gt; entity is more of a data structure than an object. Data structures expose their data and have little or no behavior while objects protect their data and expose behaviors.&lt;/p&gt;

&lt;p&gt;To have a richer domain model, we refactor this to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;DateTime&lt;/span&gt; &lt;span class="nv"&gt;$birthDate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Address&lt;/span&gt; &lt;span class="nv"&gt;$address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$birthDate&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;address&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$address&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;rename&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
    &lt;span class="c1"&gt;//...&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;updateAddress&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Address&lt;/span&gt; &lt;span class="nv"&gt;$address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
    &lt;span class="c1"&gt;//...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now our User class is protecting its internal state (invariants) and exposing only behaviors to the outside world.&lt;/p&gt;

&lt;h2&gt;
  
  
  “Get me your name”
&lt;/h2&gt;

&lt;p&gt;Now, to the getters. From my experience, this is harder for people to get (pun intended), and, to be clear, by getters I mean methods like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getName&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Name&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This method returns the &lt;em&gt;name&lt;/em&gt; of the object in question. Many developers would say this is clear from its name. The get + Name tells us it returns the Name. Actually, the “get” prefix guarantees nothing. In actuality, it is the return type of the method that guarantees this method returns a Name.&lt;/p&gt;

&lt;p&gt;If you ditch the &lt;em&gt;get&lt;/em&gt; prefix in the method name then you lose no information in the process:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Name&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;If you can remove a word without losing any information, then that word is just noise.&lt;/p&gt;

&lt;p&gt;But this is how we talk, right? Not really. Recall from memory a situation where you need to reveal some personal information about yourself such as being in a bank. When the bank clerks ask you for your address, do they say “Get me your address” or “Get me your name”? They don’t. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--z3Fox_je--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/g1kmkb11l5lxb11wlnaw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--z3Fox_je--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/g1kmkb11l5lxb11wlnaw.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In fact, when we use the word get in real life it usually isn’t a question but an imperative that has some implied side effect. Say you want a beer so you tell your friend “Hey, get me a beer from the fridge”. The side effect of him getting you a beer is that the freezer will have one less beer afterward. This will happen every time you call him to get you a beer. I’ll admit, it would be nice if beer fridges would follow our programming conventions of “getters” not changing the internal state of the object, but they don’t.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xk6wJjoi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ra33n2tfjoawf6pzbzgy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xk6wJjoi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ra33n2tfjoawf6pzbzgy.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Naming things in software development is hard and we want to be as precise as possible when doing it. What if I told you get and set are among the most &lt;a href="https://www.youtube.com/watch?v=ZsHMHukIlJY&amp;amp;t=39m22s"&gt;Ambiguous&lt;/a&gt; words in the English language. Check google and see how long the list of their possible meanings is.&lt;/p&gt;

&lt;p&gt;Maybe they aren’t the best candidates when you’re aiming for precision. &lt;/p&gt;

</description>
      <category>php</category>
      <category>programming</category>
      <category>beginners</category>
      <category>codequality</category>
    </item>
    <item>
      <title>Makefiles for automation and better dev-UI</title>
      <dc:creator>konrad_126</dc:creator>
      <pubDate>Sun, 10 May 2020 13:48:50 +0000</pubDate>
      <link>https://dev.to/konrad_126/makefiles-for-automation-and-better-dev-ui-47k8</link>
      <guid>https://dev.to/konrad_126/makefiles-for-automation-and-better-dev-ui-47k8</guid>
      <description>&lt;p&gt;&lt;em&gt;As our projects grow in complexity, the list of tools they require also grows, and remembering how to use all of them (with their different syntaxes) can become cumbersome. On top of that, some tasks require multiple steps and tools to be run sequentially. We can create our own aliases and scripts for multi-step tasks, but the downside is remembering all those aliases and scripts.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Wouldn't it be nice if we could have a single CLI entry point to our project that would give us a way to list and run all the tools or tasks it contains? Something consistent across all projects, no matter the technology? Something like this?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--plIIb5hf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/36bgomv1bhhirtpoweht.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--plIIb5hf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/36bgomv1bhhirtpoweht.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Well, turns out we can have this with the help of &lt;a href="https://www.gnu.org/software/make/"&gt;make&lt;/a&gt;. Make is a tool primarily used for automation of code compilation but it can be used for all sorts of automation as we'll see. So let's see it in action.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building your makefile
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;make&lt;/code&gt; executes a makefile that contains a list of make targets. So let’s start with something simple. Here is a very basic structure of a makefile target:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name: 
    task
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It consists of a target name and a task associated with it.&lt;/p&gt;

&lt;p&gt;Let’s write a real make target we can use to run our unit tests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;unit-tests:
    vendor/bin/phpspec
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;If we would run this target with &lt;code&gt;make unit-tests&lt;/code&gt; it would run our phpspec tests (same as if we typed &lt;code&gt;vendor/bin/phpspec&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Suppose we have another target for our functional tests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;functional-tests:
    vendor/bin/behat
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now we can use &lt;code&gt;make functional-tests&lt;/code&gt; to run our functional tests.&lt;/p&gt;

&lt;p&gt;But what if we want to run all our tests? Well, make targets can have a list of dependencies, targets that need to be run before it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name: dependency dependency
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In our case, we can create a new target and list our test suite targets as its dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tests: unit-test functional-test
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now, when we type: &lt;code&gt;make tests&lt;/code&gt; that will run our &lt;code&gt;unit-test&lt;/code&gt; and &lt;code&gt;functional-test&lt;/code&gt; targets.&lt;/p&gt;

&lt;p&gt;And what about those multiple steps tasks? Well, make targets can have more than one task associated with it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name:
    task
    task
    task
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;So let’s create a make target to set up our (simple) project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;build-project:
    docker-compose up -d
    docker-compose exec app-comp composer install
    docker-compose exec app-php php artisan migrate
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Advantages of using good makefiles
&lt;/h2&gt;

&lt;p&gt;A good makefile provides us with some extra advantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;we have a list of aliases for all the tools/tasks we use on a project that is shared between developers (and can be shared across projects also)&lt;/li&gt;
&lt;li&gt;we have a single CLI entry point for our app so no more scouring documentation to find the name/syntax of some tool&lt;/li&gt;
&lt;li&gt;developers don’t need to know the syntax of all tools used on a project— e.g. if you are a backend developer and setting up your project locally requires the usage of some frontend tools, having that wrapped into a make target would be helpful&lt;/li&gt;
&lt;li&gt;multi-step tasks are automated and require a single command to be run&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For clarity, using makefile targets doesn’t mean we never touch the underlying tools. We can still use those, especially when we need to run them with some specific configuration. Using make simply gives you a fast way to run them in standard configuration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrap up
&lt;/h2&gt;

&lt;p&gt;Now, in the beginning, I promised a nice Command Line Interface that will give us a list of all make targets that we can run. Well, this doesn’t come with makefiles out of the box, but with the help of a designated help target, makefile comments, and some bash magic we will have it working in no time.&lt;/p&gt;

&lt;p&gt;First, we add comments to our make targets:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tests: test-unit test-functional ## Run all tests on the project
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;As you guessed, comments are prefixed with &lt;code&gt;##&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Next, we create a special help target that will render a list of our targets with comments as descriptions. There are different ways to achieve this, and you can look for some of them here. I will use the one from user &lt;a href="https://gist.github.com/prwhite/8168133#gistcomment-1420062"&gt;muhmi&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;help: ## This help dialog.
    @IFS=$$'\n' ; \
    help_lines=(`fgrep -h "##" $(MAKEFILE_LIST) | fgrep -v fgrep | sed -e 's/\\$$//' | sed -e 's/##/:/'`); \
    printf "%-30s %s\n" "target" "help" ; \
    printf "%-30s %s\n" "------" "----" ; \
    for help_line in $${help_lines[@]}; do \
        IFS=$$':' ; \
        help_split=($$help_line) ; \
        help_command=`echo $${help_split[0]} | sed -e 's/^ *//' -e 's/ *$$//'` ; \
        help_info=`echo $${help_split[2]} | sed -e 's/^ *//' -e 's/ *$$//'` ; \
        printf '\033[36m'; \
        printf "%-30s %s" $$help_command ; \
        printf '\033[0m'; \
        printf "%s\n" $$help_info; \
    donev
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;As you see, there is some bash wizardry here that I won’t pretend to understand fully, but it gets the job done and if you’re a bash wizard yourself you can make your own cool help target.&lt;/p&gt;

&lt;p&gt;We also need to declare this &lt;code&gt;help&lt;/code&gt; target as a default target so it would be run by default (if we run make without specifying any target’s name).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.DEFAULT_GOAL := help
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Finally, we need to add a special line to bypass some traditional behavior of make. Since make is used for compiling files, if there was a file named “tests” in the folder our command wouldn’t run. This is avoided by using declaring the command as &lt;a href="https://www.gnu.org/software/make/manual/make.pdf"&gt;phony&lt;/a&gt;. “A phony target is one that is not really the name of a file.” By adding the .PHONY line and declaring all of our commands, this conflict will never occur.&lt;/p&gt;

&lt;p&gt;Now our makefile is ready so let’s see how it looks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.DEFAULT_GOAL := help
.PHONY: help build-project unit-tests functional-tests tests start stop
help: ## This help dialog.
    @echo "Hello to the AwesomeProject\n"
    @IFS=$$'\n' ; \
    help_lines=(`fgrep -h "##" $(MAKEFILE_LIST) | fgrep -v fgrep | sed -e 's/\\$$//' | sed -e 's/##/:/'`); \
    printf "%-30s %s\n" "target" "help" ; \
    printf "%-30s %s\n" "------" "----" ; \
    for help_line in $${help_lines[@]}; do \
        IFS=$$':' ; \
        help_split=($$help_line) ; \
        help_command=`echo $${help_split[0]} | sed -e 's/^ *//' -e 's/ *$$//'` ; \
        help_info=`echo $${help_split[2]} | sed -e 's/^ *//' -e 's/ *$$//'` ; \
        printf '\033[36m'; \
        printf "%-30s %s" $$help_command ; \
        printf '\033[0m'; \
        printf "%s\n" $$help_info; \
    done
build-project: ## Build our project
    docker-compose up -d
    docker-compose exec app-comp composer install
    docker-compose exec app-php php artisan migrate
start: ## Start project containers
    docker-compose up -d
stop: ## Stop project containers
    docker-compose down
unit-tests: ## Run unit tests
    vendor/bin/phpspec
functional-tests: ## Run functional tests
    vendor/bin/behat
tests: unit-test functional-test ## Run all tests.DEFAULT_GOAL := help

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



&lt;p&gt;If we would run make in a folder containing the makefile we just built, we would get our nice list of targets with their descriptions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Hello to the AwesomeProject
target                         help
------                         ----
help                           This help dialog.
build-project                  Build our project
start                          Start project containers
stop                           Start project containers
unit-tests                     Run unit tests
functional-tests               Run functional tests
tests                          Run all tests
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;






&lt;p&gt;So what are you waiting for? Go supercharge your project with make. It is an easy way to create a consistent command interface so that ramp up time on projects is kept to a minimum.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>programming</category>
      <category>productivity</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>What we talk about when we talk about testing </title>
      <dc:creator>konrad_126</dc:creator>
      <pubDate>Mon, 27 Apr 2020 19:52:03 +0000</pubDate>
      <link>https://dev.to/konrad_126/what-we-talk-about-when-we-talk-about-testing-5aao</link>
      <guid>https://dev.to/konrad_126/what-we-talk-about-when-we-talk-about-testing-5aao</guid>
      <description>&lt;p&gt;&lt;em&gt;Imagine if airplane companies never tested their airplanes. They just ship them when they’re done. Would you feel safe boarding a plane like that?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Fortunately, airplanes are not built like that. Flying is statistically the safest way of transportation and there are strict regulations and tests airplanes must abide by.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7G-WPUWe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/87ms1d319bknhxv5nky0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7G-WPUWe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/87ms1d319bknhxv5nky0.png" alt="airplane"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Most people would agree to release a product without testing it is a crazy idea, whether you’re building airplanes, cars, or bicycles. We expect a product must satisfy a strict set of tests before being released to the public. If a company releases a product that turns out to be faulty, it is subject to public ridicule. The first question that comes to mind is &lt;strong&gt;“Did they even test their product?”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What about software? For some reason, many people still think it is ok to build software without testing it&lt;/p&gt;

&lt;h2&gt;
  
  
  Someone will test it
&lt;/h2&gt;

&lt;p&gt;When people talk about testing, what they usually talk about is &lt;strong&gt;automated tests&lt;/strong&gt;, but let’s make one thing clear — &lt;strong&gt;every&lt;/strong&gt; software program gets tested. Eventually, someone will run it and verify it’s output. If you are shipping software without testing it, you are letting your customers test it. As we saw with our airplane analogy, this is not a good idea, and hopefully, this is not what you are doing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CQfqZ8xG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9jzabjla8w28oprkky0c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CQfqZ8xG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9jzabjla8w28oprkky0c.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So you do test your software, but you just do it &lt;strong&gt;manually&lt;/strong&gt;. You write the code for your feature and run your application. Then you go through a set of use cases or workflows to check if the application behaves as expected for each of them. Once it does, you ship it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--psXQhGUB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ttmuibzwm3jpbsdviov3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--psXQhGUB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ttmuibzwm3jpbsdviov3.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So what’s wrong with that? Why would you switch to automated tests?&lt;/p&gt;

&lt;h2&gt;
  
  
  Why automated testing?
&lt;/h2&gt;

&lt;p&gt;Tell me if this sounds familiar. You write your feature and start checking if your application works as expected. But it doesn’t. There’s a bug so you fix it. You check again but find another bug so you fix it. After going through several (many) of these iterations everything finally works and you ship your code. As you are getting ready for lunch your error reporting tool goes haywire. Turns out, when doing your last round of workflow check-ups you skipped one and missed a bug.&lt;/p&gt;

&lt;p&gt;Manual testing is &lt;strong&gt;repetitive&lt;/strong&gt; work and the problem with us humans is that we tend to forget things. Luckily, there are these things called computers that are very good at repetitive tasks. Why not use them to test our application? Once we give the computer our list of workflows to check, it will never forget to go through any of them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PsV6llep--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/41irxx6zsctrjn1gta79.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PsV6llep--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/41irxx6zsctrjn1gta79.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Another problem with manual testing is it takes time. The more workflows you have to check the more time it will take. In a fairly complex software system, the number of possible paths that an application flow can take grows fast, and testing them manually quickly becomes impractical or simply impossible. So you resort to testing only some of them. Computers are much faster at processing information than humans so they solve this issue too, allowing us to test our applications at dramatically greater speeds. The initial effort of writing extra code (an automated test) quickly pays off since the tests run before every push to a branch, deploy, or commit.&lt;/p&gt;

&lt;h2&gt;
  
  
  How?
&lt;/h2&gt;

&lt;p&gt;If you do decide to start writing automated tests, you may get overwhelmed with all the different terminology and jargon used. In its essence automated software testing is simple — you write a program to test your program. So if your program is a calculator that does addition, you write another program that sends some input to your calculator. For example, we send numbers 2 and 3 and check if the output of the calculator matches our expectations (it should be 5). In reality, we are writing more complicated things than simple calculators but most of the time you will be testing if your program gives the expected output for a given input.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2VkSs8DH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/w2jo7b8va6qs0m8eir7q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2VkSs8DH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/w2jo7b8va6qs0m8eir7q.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Other things you will often want to test are object/service collaboration and side effects. For example, you may want to know if your user registration service “told” the mailer service to send a welcoming email to the new user or if the user object was persisted in your data storage.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keeping it efficient
&lt;/h2&gt;

&lt;p&gt;As we pointed earlier, computers are much faster than humans, allowing us to test our applications with much greater speed, but as the number of tests rises, running (and maintaining) your tests can start to take time. This is why you want your test suite to follow a so-called &lt;a href="https://martinfowler.com/bliki/TestPyramid.html"&gt;Testing pyramid pattern&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The base of your pyramid is the low-level unit tests. Unit tests target single units in isolation (unit usually meaning a single class or path). As you go higher up the pyramid, your tests start to involve bigger “chunks” of your applications (components and modules) and with the highest level of tests booting up your whole application and testing it as a black box. The higher up the pyramid you go, the tests become slower and more brittle (making them harder to maintain) which is why you want a pyramid shape instead of a &lt;a href="https://watirmelon.blog/testing-pyramids/"&gt;cone&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NSeUudsh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/yko9k5ncoei355813fi2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NSeUudsh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/yko9k5ncoei355813fi2.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you think about our airplane manufacturer analogy again, I don’t suppose they build the whole airplane and fly it just to check if the doors on the toilet work? This can be tested in isolation, as well as many other (more crucial) parts of the airplane like motors. Once they test each unit they can start assembling them into components and modules, testing them along the way, and finally ending up with test flights that test the airplane as a whole.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tests first?
&lt;/h2&gt;

&lt;p&gt;What if I told you that you should not only write tests but you should write the test first before you write the actual working code? This is what the practice of &lt;strong&gt;Test-Driven Development&lt;/strong&gt; (&lt;a href="https://en.wikipedia.org/wiki/Test-driven_development"&gt;TDD&lt;/a&gt;) is about. You write your test code and then the working code that will satisfy that test. This often seems like a counter-intuitive idea to many people, especially if they are not writing tests at all. After all, how can you test something that you haven’t built yet?&lt;/p&gt;

&lt;p&gt;It is useful to think of your test code in terms of &lt;strong&gt;specification&lt;/strong&gt;. Having a specification that defines how a certain part of the software should behave is a much more intuitive idea, and in a way, your test is just that — a specification of how certain parts of your software should behave. If you think of it this way then writing tests (specifications) before writing the actual software code makes much more sense. After all, how can you write software if you didn’t specify how it should behave?&lt;/p&gt;

&lt;h2&gt;
  
  
  Do I need it?
&lt;/h2&gt;

&lt;p&gt;Learning how to write good automated tests will take some time and effort, so do you really need it? I mean, it’s not like you’re building airplanes, right?&lt;/p&gt;

&lt;p&gt;Let me rephrase the question from the introduction. Would you board an airplane whose &lt;strong&gt;software&lt;/strong&gt; (that it heavily relies on to fly) is not tested?&lt;/p&gt;

&lt;p&gt;Maybe your web application failing won’t have the same consequences as airplane software failing, but as a &lt;strong&gt;professional&lt;/strong&gt;, you vouch for the correctness and reliability of your software. While I am not claiming automated tests will make your software error-free, they are the best tool we have to raise the confidence in the correctness of our software. Unless constant failing is a requirement of your software, you need to write tests, because testing is too important to be left to humans.&lt;/p&gt;

</description>
      <category>codenewbie</category>
      <category>beginners</category>
      <category>testing</category>
      <category>programming</category>
    </item>
    <item>
      <title>Never talk to strangers</title>
      <dc:creator>konrad_126</dc:creator>
      <pubDate>Sun, 26 Apr 2020 18:30:49 +0000</pubDate>
      <link>https://dev.to/konrad_126/never-talk-to-strangers-o47</link>
      <guid>https://dev.to/konrad_126/never-talk-to-strangers-o47</guid>
      <description>&lt;p&gt;&lt;em&gt;Talking to strangers in 1930s Moscow was not a smart thing to do. Mikhail Alexandrovich Berlioz (chairman of the management committee of one of the biggest Moscow literary clubs — MASSOLIT) and his young companion, poet Ivan Nikolayich Poniryov (who wrote under the pseudonym of Bezdomny) knew that all too well. Yet, this is exactly what they did at the sunset hour of one warm spring day at the Patriarch’s Ponds when a suspicious-looking stranger approached them.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dSGWQxYx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9h9eoug6px6n1f7vk36q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dSGWQxYx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9h9eoug6px6n1f7vk36q.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
The stranger turned out to be the Devil himself and if you wish to know more about what awaits Berlioz, Bezdomni, and the citizens of Moscow when the Devil and his entourage come for a visit, go read &lt;a href="https://en.wikipedia.org/wiki/Mikhail_Bulgakov"&gt;Mikhail Bulgakov's&lt;/a&gt; masterpiece &lt;a href="https://www.goodreads.com/book/show/117833.The_Master_and_Margarita"&gt;Master and Margarita&lt;/a&gt;. Since this is a blog on software development, you may be wondering: what does this have to do with software development?&lt;/p&gt;

&lt;p&gt;Well, talking to strangers can be dangerous when it comes to software development, too. And it is expressed by an Object-Oriented design guideline called &lt;a href="http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.84.6924&amp;amp;rep=rep1&amp;amp;type=pdf"&gt;The Law of Demeter&lt;/a&gt;. It says that a "module should not know about the innards of the objects it manipulates". [1]&lt;/p&gt;

&lt;p&gt;The formal definition of the Law of Demeter states that when writing a method in a class, our methods should only call:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;other methods of the class&lt;/li&gt;
&lt;li&gt;methods on an object that was created in our method&lt;/li&gt;
&lt;li&gt;methods on an object that was passed as an argument to our method&lt;/li&gt;
&lt;li&gt;methods on an object that is a class property
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TheClass&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;OtherClass&lt;/span&gt; &lt;span class="nv"&gt;$instanceVariableObject&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;otherMethodOfTheClass&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;demeter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PassedInClass&lt;/span&gt; &lt;span class="nv"&gt;$argument&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// other methods of the class&lt;/span&gt;
        &lt;span class="c1"&gt;// this is okay&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;otherMethod&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="c1"&gt;// methods of an object we created&lt;/span&gt;
        &lt;span class="c1"&gt;// this is okay&lt;/span&gt;
        &lt;span class="nv"&gt;$object&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;ClassC&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nv"&gt;$object&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;someMethod&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="c1"&gt;// methods on an object passed in&lt;/span&gt;
        &lt;span class="c1"&gt;// this is okay&lt;/span&gt;
        &lt;span class="nv"&gt;$argument&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;someMethod&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="c1"&gt;// methods of a class property&lt;/span&gt;
        &lt;span class="c1"&gt;// this is okay&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;instanceVariableObject&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;someMethod&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;But, our method should not invoke methods on objects that are returned by any of these allowed method calls. In other words, objects should only talk to their friends, never strangers. And in this context, friends of friends are considered strangers.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VDUi57Q---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ob9dzzyogv81rbvxfz3o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VDUi57Q---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ob9dzzyogv81rbvxfz3o.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is a typical Law of Demeter violation example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$blog&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;comments&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$comment&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Chained method calls can be a good indicator of this, but even if we “unchain” the methods, a violation persists.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$commentCollection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$blog&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;comments&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nv"&gt;$commentCollection&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$comment&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Our calling code knows about the &lt;code&gt;Blog&lt;/code&gt; object. This is its friend. The &lt;code&gt;Blog&lt;/code&gt; object knows about the &lt;code&gt;CommentCollection&lt;/code&gt; object. That is its friend. But to our calling code, &lt;code&gt;CommentCollection&lt;/code&gt; is a stranger and we should not be talking to strangers. In more technical terms, our calling code is aware of the internal structure of the &lt;code&gt;Blog&lt;/code&gt; class, so if this internal structure changes we would have to update our code. This is more coupling than we need.&lt;/p&gt;

&lt;p&gt;What we can do instead is have a method on the &lt;code&gt;Blog&lt;/code&gt; itself:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$blob&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;addComment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$comment&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Our calling code only needs to know how to call this &lt;code&gt;addComment&lt;/code&gt; method on a &lt;code&gt;Blog&lt;/code&gt; object. It doesn’t need to know how a &lt;code&gt;Blog&lt;/code&gt; object will add that comment internally, and if we change the way that a &lt;code&gt;Blog&lt;/code&gt; keeps its comments internally, our calling code won’t need to be updated. Thus, we have reduced the coupling of our code. And that is good since higher coupling increases the chances that any (small) change we make will break something else. So we want less coupling.&lt;/p&gt;

&lt;p&gt;The downside of obeying the Law of Demeter is that you may end up with a lot of delegate methods that act like wrappers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;addComment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Comment&lt;/span&gt; &lt;span class="nv"&gt;$comment&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;commentCollection&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$comment&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Some would argue it could also be an indicator of problems in your design, especially if you have these methods nested across objects.&lt;/p&gt;

&lt;p&gt;In any case, although talking to strangers in software development may not be as dangerous as in Soviet Russia (and you won’t end up like poor old Berlioz), &lt;strong&gt;The Law of Demeter&lt;/strong&gt; is still a useful design principle to know and to apply when possible.&lt;br&gt;
&lt;/p&gt;
&lt;blockquote class="ltag__twitter-tweet"&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--7gnTmAXm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/79787739/mf-tg-sq_normal.jpg" alt="Martin Fowler profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Martin Fowler
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        @martinfowler
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mL-RlVCA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-95c212266bf9a35c02dd777b6d438dfbc5a6a4c1e82708c3ab617b069928387a.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      &lt;a href="https://twitter.com/jeremydmiller"&gt;@jeremydmiller&lt;/a&gt; I'd prefer it to be called the Occasionally Useful Suggestion of Demeter.
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      15:37 PM - 29 Apr 2009
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1649793241" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-reply-action.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1649793241" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-retweet-action.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      15
      &lt;a href="https://twitter.com/intent/like?tweet_id=1649793241" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-like-action.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
      16
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;


&lt;p&gt;[1] –  Robert C. Martin – Clean Code&lt;/p&gt;

</description>
      <category>development</category>
      <category>architecture</category>
      <category>cedequality</category>
      <category>begginers</category>
    </item>
    <item>
      <title>Understanding Git - Data Model</title>
      <dc:creator>konrad_126</dc:creator>
      <pubDate>Thu, 23 Apr 2020 16:27:11 +0000</pubDate>
      <link>https://dev.to/konrad_126/understanding-git-data-model-7dd</link>
      <guid>https://dev.to/konrad_126/understanding-git-data-model-7dd</guid>
      <description>&lt;p&gt;As software developers, we use a lot of tools. Many of them come with an intuitive User Interface which abstracts the internal complexity of the domain they are operating on. This allows us to &lt;em&gt;go fast&lt;/em&gt; and learn those tools by using them. &lt;/p&gt;

&lt;p&gt;For better or worse, git is &lt;strong&gt;not&lt;/strong&gt; one of those tools. The abstraction git's User Interface gives you is very leaky so to become better with git you must spend (some) time learning how it works internally.&lt;/p&gt;

&lt;p&gt;In this &lt;strong&gt;Understanding Git&lt;/strong&gt; series, we will cover git’s internals (we will not go into git’s source code don’t worry) and the first thing on that list is git’s heart and soul — the &lt;strong&gt;data model.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  It's all about .git
&lt;/h2&gt;

&lt;p&gt;We'll start by initializing a git repository:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Git tells us it has created a &lt;code&gt;.git&lt;/code&gt; directory in our project’s directory so let’s take a quick peek into it:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ tree .git/

.git/
├── HEAD
├── config
├── description
├── hooks
│   ├── applypatch-msg.sample
│   ├── commit-msg.sample
│   ├── post-update.sample
│   ├── pre-applypatch.sample
│   ├── pre-commit.sample
│   ├── pre-push.sample
│   ├── pre-rebase.sample
│   ├── pre-receive.sample
│   ├── prepare-commit-msg.sample
│   └── update.sample
├── info
│   └── exclude
├── objects
│   ├── info
│   └── pack
└── refs
    ├── heads
    └── tags8 directories, 14 files
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Some of these files and directories may sound familiar (particularly &lt;code&gt;HEAD&lt;/code&gt;) but for now, focus on the &lt;code&gt;.git/objects&lt;/code&gt; directory. Right now it's empty, but we will change that in a moment.&lt;/p&gt;

&lt;p&gt;Let’s add an &lt;code&gt;index.php&lt;/code&gt; file&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;touch index.php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;fill it with some content&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php
echo "Hello World";
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;and a &lt;code&gt;README.md&lt;/code&gt; file&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;touch README.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;with some content as well:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Description
This is my hello world project
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now let’s stage and commit them:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git add .
git commit -m "Initial Commit"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;OK, nothing special here, adding and committing — we’ve all “been there, done that”.&lt;/p&gt;

&lt;p&gt;If we look back at the &lt;code&gt;.git&lt;/code&gt; directory we can see that the &lt;code&gt;.git/objects&lt;/code&gt; directory now contains some files and subdirectories (bear in mind they will have different names on your computer!):&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;├── objects
│   ├── 5d
│   │   └── 92c127156d3d86b70ae41c73973434bf4bf341
│   ├── a6
│   │   └── dbf05551541dc86b7a49212b62cfe1e9bb14f2
│   ├── cf
│   │   └── 59e02c3d2a2413e2da9e535d3c116af1077906
│   ├── f8
│   │   └── 9e64bdfcc08a8b371ee76a74775cfe096655ce
│   ├── info
│   └── pack
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Every object in git has a so-called &lt;strong&gt;checksum&lt;/strong&gt; header (the unique identifier of an object) and the first two characters of that checksum are used as a directory name while the rest is used as a file (object) name. Let's look at what these objects are.&lt;/p&gt;

&lt;h2&gt;
  
  
  Blobs, trees, and ...
&lt;/h2&gt;

&lt;p&gt;The first kind of object that git creates when we commit some file(s) are &lt;strong&gt;blob&lt;/strong&gt; objects. Git uses them to represent the content of files. In our case there is two of them, one for each file we committed:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0q8zg8yz2m0bxf3jn2y4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0q8zg8yz2m0bxf3jn2y4.png" alt="Two blog objects"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;They contain the full content of our files, so you can think of them as snapshots of our files (at the time of the commit). To generate the checksum header git takes the content of an object, feeds it to a hashing function and the output is the checksum header. This is why it also serves as a unique identifier of an object.&lt;/p&gt;

&lt;p&gt;The next kind of object git creates are &lt;strong&gt;tree&lt;/strong&gt; objects. They are used to represent the project's folder structure and in our simple example, git needs only one tree object. It contains a list of all files in our project with pointers to their blob objects:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fykf3h1z8u7qchez4chkz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fykf3h1z8u7qchez4chkz.png" alt="Two blogs and one Tree object"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lastly, git creates a commit object. It contains some metadata data (author, time..) and a pointer to its tree object:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fnsuut2x7gc2ztwa51r0z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fnsuut2x7gc2ztwa51r0z.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Content of our &lt;code&gt;.git/objects&lt;/code&gt; directory it should make more sense now:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;├── objects
│   ├── 5d
│   │   └── 92c127156d3d86b70ae41c73973434bf4bf341
│   ├── a6
│   │   └── dbf05551541dc86b7a49212b62cfe1e9bb14f2
│   ├── cf
│   │   └── 59e02c3d2a2413e2da9e535d3c116af1077906
│   ├── f8
│   │   └── 9e64bdfcc08a8b371ee76a74775cfe096655ce
│   ├── info
│   └── pack
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Using &lt;code&gt;git log&lt;/code&gt; we can see our commit history:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;commit a6dbf05551541dc86b7a49212b62cfe1e9bb14f2 
Author: zspajich &amp;lt;zspajich@gmail.com&amp;gt;
Date:   Tue Jan 23 13:31:43 2018 +0100Initial Commit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;By knowing the naming convention we mentioned earlier we can locate this commit object in &lt;code&gt;.git/object&lt;/code&gt; :&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;├── objects
│   ├── a6
│   │   └── dbf05551541dc86b7a49212b62cfe1e9bb14f2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;To display its content we can’t simply use the &lt;code&gt;cat&lt;/code&gt; command since these are not plain text files but git has a &lt;code&gt;cat-file&lt;/code&gt; command we can use instead:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git cat-file commit a6dbf05551541dc86b7a49212b62cfe1e9bb14f2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now we see the content of the commit object:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tree f89e64bdfcc08a8b371ee76a74775cfe096655ce
author zspajich &amp;lt;zspajich@gmail.com&amp;gt; 1516710703 +0100
committer zspajich &amp;lt;zspajich@gmail.com&amp;gt; 1516710703 +0100Initial Commit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;First line is the pointer to a tree object and to examine it’s content we can use &lt;code&gt;git ls-tree&lt;/code&gt; command:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git ls-tree f89e64bdfcc08a8b371ee76a74775cfe096655ce
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;As expected it does contain a list of our files with pointers to blob objects:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;100644 blob cf59e02c3d2a2413e2da9e535d3c116af1077906 README.md
100644 blob 5d92c127156d3d86b70ae41c73973434bf4bf341 index.php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Let's look into the blob object representing  &lt;code&gt;index.php&lt;/code&gt; using the &lt;code&gt;cat-file&lt;/code&gt; command:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git cat-file blob 5d92c127156d3d86b70ae41c73973434bf4bf341
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Sure enough, it has the same content as  our &lt;code&gt;index.php&lt;/code&gt; file:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?
echo "Hello World!"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;There you go. Now you know what happens when committing files.&lt;/p&gt;

&lt;p&gt;Let's see what happens if we now edit (add some code magic) and commit our &lt;code&gt;index.php&lt;/code&gt; file:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fzae2tb5txqxeppzd6dih.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fzae2tb5txqxeppzd6dih.png" alt="one new blob object"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Git creates another blob object (a new snapshot) to represent the new content of &lt;code&gt;index.php&lt;/code&gt;.  As for &lt;code&gt;README.md&lt;/code&gt;, since it didn't change, git can reuse the existing blog for it (we'll see it in a moment).&lt;/p&gt;

&lt;p&gt;When creating the tree **object, git updates the pointer for  &lt;code&gt;index.php&lt;/code&gt;  to its new blob while the &lt;code&gt;README.md&lt;/code&gt; pointer stays the same:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fbtnzyyz461sa1fln6qpa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fbtnzyyz461sa1fln6qpa.png" alt="tree object having an updated pointer for index.php"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As before, the commit object has a pointer to the tree object but also a pointer to its parent &lt;em&gt;commit&lt;/em&gt; object because every commit except the first one has at least one parent:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fh5oekg3fzr8ky5xfhzpp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fh5oekg3fzr8ky5xfhzpp.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that we know how git handles file adding and editing, the only thing remaining is file deletion. What if we delete our &lt;code&gt;index.php&lt;/code&gt; file?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fb5hoa01slkgyzvhat1q9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fb5hoa01slkgyzvhat1q9.png" alt="index.php file omitted from tree object"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It’s rather simple — git deletes the file entry (filename with a pointer to its blob object) from the tree object. In other words, our commit’s tree object no longer has a pointer to a blob object representing &lt;code&gt;index.php&lt;/code&gt; (but that blob object is still there in &lt;code&gt;.git/objects&lt;/code&gt;)&lt;/p&gt;

&lt;h2&gt;
  
  
  Nested folders
&lt;/h2&gt;

&lt;p&gt;In our real-life projects, the folder structure is much more elaborate than in this simple example. As said, tree objects represent the folder structure of your project, and the same way folders can be nested tree objects can also be nested (point to other tree objects). For example:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fzgeff05a9fuze57hvu2n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fzgeff05a9fuze57hvu2n.png" alt="nested tree objects"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here, our project base folder has one &lt;code&gt;README.md&lt;/code&gt; file and one sub-directory &lt;code&gt;app&lt;/code&gt;  which has two files ( &lt;code&gt;app.php&lt;/code&gt; and &lt;code&gt;app_dev.php&lt;/code&gt;).&lt;/p&gt;




&lt;p&gt;So there you have it - git's data model. Blob objects represent the content of files, tree objects represent the folder structure of the project, while commit objects contain metadata and have pointers to their parents. &lt;/p&gt;

&lt;p&gt;In the next post, we'll take a look at branching - what branches are and why having a bunch of them is very cheap in git.&lt;/p&gt;

</description>
      <category>git</category>
      <category>begginers</category>
    </item>
    <item>
      <title>git reset --explain</title>
      <dc:creator>konrad_126</dc:creator>
      <pubDate>Tue, 08 Jan 2019 20:32:09 +0000</pubDate>
      <link>https://dev.to/konrad_126/git-reset---explain-49bl</link>
      <guid>https://dev.to/konrad_126/git-reset---explain-49bl</guid>
      <description>&lt;p&gt;&lt;em&gt;Reset is probably one of the least understood git commands with the addition of having a bad reputation for being dangerous. There is a valid reason for both of these claims: yes, the reset command is a bit harder to understand and in some cases, it can be dangerous. But, it is not all that hard. So in this post, I will give my best to present you with a clear and distilled tutorial to the reset command. To make it short and not too overwhelming I have abstracted the non-essential details and simplified some things, but if you want to know more on git's internal workings you can also check my &lt;a href="https://medium.com/hackernoon/https-medium-com-zspajich-understanding-git-data-model-95eb16cc99f5" rel="noopener noreferrer"&gt;Understanding Git&lt;/a&gt; series for more details of some stuff presented here.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Git Trees
&lt;/h2&gt;

&lt;p&gt;Before we dive into the &lt;code&gt;reset&lt;/code&gt; command we need to take a look at what is called the trees of git: Working Directory, Staging Area and the Repository.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiz3z7nlw0a7crj7m9iqd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiz3z7nlw0a7crj7m9iqd.png" alt="git thress" width="800" height="65"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can think of them as areas where changes can reside from git's point of view:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Working Directory - your project files on your filesystem&lt;/li&gt;
&lt;li&gt;Staging Area - a preview of the next commit&lt;/li&gt;
&lt;li&gt;Repository - datastore where git keeps all (past) commits.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;reset&lt;/code&gt; command operates on these threes/areas, but first, let's take a look how do &lt;code&gt;add&lt;/code&gt; and &lt;code&gt;commit&lt;/code&gt; command that we use daily, affect these areas.&lt;/p&gt;




&lt;p&gt;Say we have a web app and we do some refactoring on our &lt;code&gt;index.php&lt;/code&gt; file. Changes that we make are reflected in the Working Directory:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftnkhbpkjtia6grbzyz3i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftnkhbpkjtia6grbzyz3i.png" alt="workflow-1" width="800" height="185"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can confirm this by running &lt;code&gt;git status&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Changes not staged for commit:
  (use "git add &amp;lt;file&amp;gt;..." to update what will be committed)
  (use "git checkout -- &amp;lt;file&amp;gt;..." to discard changes in working directory)
modified:   index.php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we move those changes to the Staging Area by using the &lt;code&gt;add&lt;/code&gt; command:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6v9pagdw3rw92j43rnj3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6v9pagdw3rw92j43rnj3.png" alt="workflow-2" width="800" height="185"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And running the &lt;code&gt;status&lt;/code&gt; command now will tell us:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Changes to be committed:
  (use "git reset HEAD &amp;lt;file&amp;gt;..." to unstage)
modified:   index.php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because the &lt;code&gt;status&lt;/code&gt; command sees that we have the same version of &lt;code&gt;index.php&lt;/code&gt; file both in Working Directory and in the Staging Area, but not in Repository.&lt;/p&gt;

&lt;p&gt;To add it there, we use the &lt;code&gt;commit&lt;/code&gt; command:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj4ai6xwptvd389qn9ox0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj4ai6xwptvd389qn9ox0.png" alt="workflow-3" width="800" height="185"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And now the Working Directory, Staging Area and Repository all contain the same version of &lt;code&gt;index.php&lt;/code&gt;, and running &lt;code&gt;git status&lt;/code&gt; will tell us that there is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nothing to commit, working tree clean
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, the way the &lt;code&gt;status&lt;/code&gt; command works is that it compares file versions in Working Directory, Staging Area and Repository and if there are different than there are files to be staged/committed.&lt;/p&gt;




&lt;p&gt;Let's say we now refactor the &lt;code&gt;index.php&lt;/code&gt; file some more and do the whole add/commit cycle again.&lt;br&gt;
Now our Working Directory, Staging Area and the Repository all contain the new second version of our &lt;code&gt;index.php&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fffihylmmnaexxen22vtf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fffihylmmnaexxen22vtf.png" alt="workflow-4" width="800" height="185"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But what about the first version? If you remember, we did say that the Repository keeps all previous commits, so the first version of &lt;code&gt;index.php&lt;/code&gt; file is still there:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhl88nab8y213fh4wpihp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhl88nab8y213fh4wpihp.png" alt="workflow-5" width="800" height="204"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To keep track which version of our &lt;code&gt;index.php&lt;/code&gt; file is the current one, Repository has a special pointer called &lt;code&gt;HEAD&lt;/code&gt; that points to the current version (and the &lt;code&gt;status&lt;/code&gt; command only looks at the current version that &lt;code&gt;HEAD&lt;/code&gt; is pointing to when comparing it to the Staging Area's version).&lt;/p&gt;



&lt;p&gt;And now that we have that covered we can finally go to our &lt;code&gt;reset&lt;/code&gt; command and see how it works by manipulating the content of these areas.&lt;/p&gt;
&lt;h2&gt;
  
  
  reset --soft
&lt;/h2&gt;

&lt;p&gt;This first mode of &lt;code&gt;reset&lt;/code&gt; command will only do one thing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;move the &lt;code&gt;HEAD&lt;/code&gt; pointer.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In our case, we will move it to the previous commit (the first version of &lt;code&gt;index.php&lt;/code&gt;) by doing: &lt;code&gt;git reset --soft HEAD~1&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe30p4wkvd2t5t39nwokr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe30p4wkvd2t5t39nwokr.png" alt="reset-soft-1" width="800" height="204"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The trees of git now look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flte0m6m8bbgucn718muz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flte0m6m8bbgucn718muz.png" alt="reset-soft-2" width="800" height="203"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And if we would to run &lt;code&gt;git status&lt;/code&gt; we would see a familiar message:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Changes to be committed:
  (use "git reset HEAD &amp;lt;file&amp;gt;..." to unstage)
modified:   index.php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, running &lt;code&gt;git reset --soft HEAD~1&lt;/code&gt; has basically undone our last commit, but the changes contained in that commit are not lost - they are in our Staging Area and Working Directory.&lt;/p&gt;

&lt;h2&gt;
  
  
  reset - mixed
&lt;/h2&gt;

&lt;p&gt;The second mode of the &lt;code&gt;reset&lt;/code&gt; command will do two things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;move the &lt;code&gt;HEAD&lt;/code&gt; pointer&lt;/li&gt;
&lt;li&gt;update the Staging Area (with the content that the &lt;code&gt;HEAD&lt;/code&gt; is pointing to)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, the first step is the same as with the &lt;code&gt;--soft&lt;/code&gt; mode. The second step takes the  content that &lt;code&gt;HEAD&lt;/code&gt; points to (in this case, it is version one of the &lt;code&gt;index.php&lt;/code&gt; file) and puts it into the Staging Area.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flte0m6m8bbgucn718muz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flte0m6m8bbgucn718muz.png" alt="reset-mixed-1" width="800" height="203"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, after running &lt;code&gt;git reset --mixed HEAD~1&lt;/code&gt; our areas look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs9st3nfexwpgoko35bzl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs9st3nfexwpgoko35bzl.png" alt="reset-mixed-2" width="800" height="203"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And if we would to run &lt;code&gt;git status&lt;/code&gt; now we would again see a familiar message:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Changes not staged for commit:
  (use "git add &amp;lt;file&amp;gt;..." to update what will be committed)
  (use "git checkout -- &amp;lt;file&amp;gt;..." to discard changes in working directory)
modified:   index.php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, running &lt;code&gt;git reset - mixed HEAD~1&lt;/code&gt; has undone our last commit, but this time the changes from that commit are (only) in our Working Directory.&lt;/p&gt;

&lt;h2&gt;
  
  
  reset --hard
&lt;/h2&gt;

&lt;p&gt;And now for the notorious hard mode. Running &lt;code&gt;reset -- hard&lt;/code&gt; will do three things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;move the &lt;code&gt;HEAD&lt;/code&gt; pointer&lt;/li&gt;
&lt;li&gt;update the Staging Area (with the content that the &lt;code&gt;HEAD&lt;/code&gt; is pointing to)&lt;/li&gt;
&lt;li&gt;update the Working Directory to match the Staging Area&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, the first two steps are the same as with &lt;code&gt;--mixed&lt;/code&gt;.The third makes the Working Directory look like the Staging Area (that was already filled with what &lt;code&gt;HEAD&lt;/code&gt; is pointing to).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj115rbl9ka2xmmzmgx8u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj115rbl9ka2xmmzmgx8u.png" alt="reset-hard-1" width="800" height="204"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, after running &lt;code&gt;git reset --hard HEAD~1&lt;/code&gt; our areas look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkd5mpfoary6e9a8soze2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkd5mpfoary6e9a8soze2.png" alt="reset-hard-2" width="800" height="203"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And running &lt;code&gt;git status&lt;/code&gt; will give us:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nothing to commit, working tree clean
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, running &lt;code&gt;git reset - hard HEAD~1&lt;/code&gt; has undone our last commit and the changes contained in that commit are now neither in our Working Directory or the Staging Area. But they are not completely lost. Git doesn't delete commits from Repository (actually, it does sometimes, but rarely), so this means our commit with the second version is still in the Repository, only it is a bit harder to find (you can track it by looking at something called &lt;em&gt;reflog&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;So, what is then with this reputation of reset being &lt;strong&gt;dangerous&lt;/strong&gt;? Well, there is one case where some changes could be permanently lost. Consider a scenario where after the second commit you make some more changes to your &lt;code&gt;index.php&lt;/code&gt; file, but you don't stage and commit them:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbp4o6u3b2hpda4yfnuv7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbp4o6u3b2hpda4yfnuv7.png" alt="reset-hard-3" width="800" height="206"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And now you run &lt;code&gt;git reset --hard HEAD~1&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs7lu5yhd5mup0c95t7ts.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs7lu5yhd5mup0c95t7ts.png" alt="reset-hard-4" width="800" height="206"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since the &lt;code&gt;reset&lt;/code&gt; command will overwrite the content of your Working Directory to match the Staging Area (that is made to match &lt;code&gt;HEAD&lt;/code&gt;) and you never staged and committed your changes (there is no commit with those changes in the repository), all those changes will now be lost in time... Like tears in the rain.&lt;/p&gt;

&lt;p&gt;The danger of hard reset lies in the fact that it is not Working Directory safe - meaning it won't give you any warning if you have file changes in your Working Directory that will be overwritten (and lost) if you run it. So be (extra) careful with a hard reset.&lt;/p&gt;




&lt;p&gt;And there you have it: the &lt;code&gt;reset&lt;/code&gt; command. I hope I did a good job explaining it and that you'll agree it is not that hard after all. And, yes it can be dangerous but only if used with &lt;code&gt;--hard&lt;/code&gt; option. &lt;/p&gt;

&lt;p&gt;As said in the beginning if you would like to know more on the inner workings of git, you can check my &lt;a href="https://hackernoon.com/https-medium-com-zspajich-understanding-git-data-model-95eb16cc99f5" rel="noopener noreferrer"&gt;Understanding Git&lt;/a&gt; series, and if you want a more in-depth explanation on the &lt;code&gt;reset&lt;/code&gt; command you can check the &lt;a href="https://git-scm.com/book/en/v2/Git-Tools-Reset-Demystified" rel="noopener noreferrer"&gt;Reset Demystified&lt;/a&gt; chapter from git pro book.&lt;/p&gt;

&lt;h3&gt;
  
  
  Appendix:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;In the examples, we used we used &lt;code&gt;HEAD~1&lt;/code&gt; as an argument for the &lt;code&gt;reset&lt;/code&gt; command. As you probably already know every commit in git has a unique identifier called a checksum, and we can use it as an argument for the &lt;code&gt;reset&lt;/code&gt; command too&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F74pp807kjl7q0pjrkmhc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F74pp807kjl7q0pjrkmhc.png" alt="checksums" width="800" height="186"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To make examples simpler we only had one file that we edited and committed, in reality, we often commit multiple files, so a specific commit holds different versions of multiple files.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl5tl0x9t6922dmty2279.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl5tl0x9t6922dmty2279.png" alt="commits" width="800" height="214"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The special &lt;code&gt;HEAD&lt;/code&gt; pointer usually doesn't point directly to a commit (as shown in examples for simplicity) but to a branch pointer that then points to a specific commit&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2xzay0uch8dn94ifg1s9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2xzay0uch8dn94ifg1s9.png" alt="pointer" width="800" height="208"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>git</category>
      <category>reset</category>
    </item>
  </channel>
</rss>
