<?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: Emmanuel Valverde Ramos</title>
    <description>The latest articles on DEV Community by Emmanuel Valverde Ramos (@evrtrabajo).</description>
    <link>https://dev.to/evrtrabajo</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%2F22375%2F37bef1fa-0b1f-45fc-aa6a-0e3d0537d041.jpg</url>
      <title>DEV Community: Emmanuel Valverde Ramos</title>
      <link>https://dev.to/evrtrabajo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/evrtrabajo"/>
    <language>en</language>
    <item>
      <title>🇬🇧 My Profession before my Job</title>
      <dc:creator>Emmanuel Valverde Ramos</dc:creator>
      <pubDate>Fri, 07 Feb 2025 17:31:16 +0000</pubDate>
      <link>https://dev.to/evrtrabajo/my-profession-before-my-job-2e7f</link>
      <guid>https://dev.to/evrtrabajo/my-profession-before-my-job-2e7f</guid>
      <description>

&lt;blockquote&gt;
&lt;p&gt;Today I publish a article that is not mine, but is too good to not share with others.&lt;/p&gt;

&lt;p&gt;Is a shame that some times the companies didn’t care engough to build safe spaces where we can express ourselves. Today I give voice to someone that rather remain anonymous.  &lt;/p&gt;

&lt;p&gt;Original in Spanish &lt;a href="https://open.substack.com/pub/emmanuelvalverderamos/p/antes-mi-profesion-que-mi-trabajo" rel="noopener noreferrer"&gt;https://open.substack.com/pub/emmanuelvalverderamos/p/antes-mi-profesion-que-mi-trabajo&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffn3f3w2nvbay6aqk3lcj.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffn3f3w2nvbay6aqk3lcj.webp" alt="_Giuseppe Arcimboldi, THE WINTER 1563_" width="750" height="983"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;&lt;br&gt;
&lt;em&gt;Giuseppe Arcimboldi, THE WINTER 1563&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I love my profession. I love being a software engineer and I love software. Not only software, though, I deeply enjoy everything that comes with it. I enjoy understanding the people I work with and thinking about our relations. I like who I am when I code. It stimulates me in a way that nothing else can. I love to learn. I am very happy and grateful to have found my calling.&lt;/p&gt;

&lt;p&gt;For a long time, software has been the glue holding me together. It was the pillar upon which my self-perception was being supported. Coding made me feel good about what I was doing. Software has also been a priority in my life: I’ve made decisions based on maximising such a positive feeling. Some of them came with unpleasant consequences and some led to outcomes entirely different from what I expected. I don’t regret any of them, although I’ve learned from them and today I probably would choose differently.&lt;/p&gt;

&lt;p&gt;Recently I was flattered when someone asked me to join an interesting project as a founder and technical lead. To my surprise, I instantly knew I would say no. I even allowed my dreamier side to sweeten my thoughts with the fantasy of success. To be honest, I just realised that probably I wouldn’t start a project from scratch again. Been there, done that. I’m simply no longer interested.&lt;/p&gt;

&lt;p&gt;For quite a few years now, I’ve been able to choose my work. I am aware of the privilege that this is and I feel grateful every day.&lt;br&gt;&lt;br&gt;
So far, my career navigation strategy has always been expansive: Which is the next challenge? Which project will take me to the next level?&lt;/p&gt;

&lt;p&gt;I had never questioned whether this way of thinking made sense—I just assumed it was what I had to do. And it worked well for me. Until it didn’t.&lt;/p&gt;

&lt;p&gt;I ended up at a company where human relationships were different from what I’d encountered before. I found far more politics than I could handle—or wanted to. Most of the strategies I had honed over the years weren’t even applicable. In short, it was an unfamiliar environment, and more than a little reluctant to change.&lt;/p&gt;

&lt;p&gt;For the first time, I experienced irrelevance firsthand. The bare minimum expectation for performance. The possibility of staying quiet, doing the work, and getting paid. Overpaid. Getting way too much money to create garbage. I realised I no longer thought about work in my leisure time nor wanted to do so. In short: the mediocre peace, a watered-down wine, the profitable nap.&lt;/p&gt;

&lt;p&gt;Actually, it wasn’t quite like that. I had to crash into a wall, break my head open, and wake up from a coma dazed in the same place. I was the same but it felt entirely different.&lt;/p&gt;

&lt;p&gt;It comes without saying, I wanted to change my environment in my own way. Like many times I did before, not caring much about the evidence. Ego? The very one.&lt;/p&gt;

&lt;p&gt;You can’t change people nor groups of people. You can support change, even lead it, but you can’t impose it. Trying to do so is, at best, naïve but mostly futile.&lt;/p&gt;

&lt;p&gt;Needless to say, the journey was emotionally painful and professionally counterproductive. My mental health suffered, and, to put it bluntly, I was shown the exit door.&lt;/p&gt;

&lt;p&gt;It wasn’t a pleasant time, but it was the best thing that could have happened. As I hit rock bottom in my grieving process, a quote from Rafa Muñoz came to my rescue:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;"I’ve decided to stop talking about the bad things and start talking about the good ones, because holding onto anger only hurts me and not the person who caused it."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A lifesaver, let me tell you. Like a third-act movie scene, I woke up in my own body, but everything was different: remote work, good pay, flexible hours, minimal expectations, maximum comfort. Jackpot!&lt;/p&gt;

&lt;p&gt;The bottom of my pit was actually a wormhole to another universe where my job and my profession were distinct things. Who would’ve thought?&lt;/p&gt;

&lt;p&gt;At work, I’m like a plant. I just exist. I only need a little water and sunlight. Plants don’t argue—they photosynthesize monitor light into money by the end of the month. My work ends in the late afternoon; my profession begins after that.&lt;/p&gt;

&lt;p&gt;Books, katas, conferences, podcasts... Black and white turns to color, and sap becomes blood again. From then on, I become the version of myself I enjoy the most. I don’t need to be paid for that.&lt;/p&gt;

&lt;p&gt;Perhaps someday my job and my profession will converge again—I truly hope they do—but for now, I’ve freed myself from that need. I’ve found balance on the other side of the local maximum I once thought was absolute. An unstable balance, perhaps, but one that is necessary and sufficient. For now.&lt;/p&gt;

</description>
      <category>cultura</category>
    </item>
    <item>
      <title>🇪🇸 Antes mi profesión que mi trabajo</title>
      <dc:creator>Emmanuel Valverde Ramos</dc:creator>
      <pubDate>Fri, 07 Feb 2025 17:30:59 +0000</pubDate>
      <link>https://dev.to/evrtrabajo/antes-mi-profesion-que-mi-trabajo-1mbe</link>
      <guid>https://dev.to/evrtrabajo/antes-mi-profesion-que-mi-trabajo-1mbe</guid>
      <description>

&lt;blockquote&gt;
&lt;p&gt;Hoy publico un articulo que no es mio, pero me parecia demasiado bueno para no compartirlo.&lt;/p&gt;

&lt;p&gt;Es una pena que a veces no tengamos los espacios seguro en nuestras organizaciones para poder compartir lo que pensamos, hoy le doy voz a una persona que ha preferido permanecer anonima.  &lt;/p&gt;

&lt;p&gt;Versión traducida al inglés: &lt;a href="https://open.substack.com/pub/emmanuelvalverderamos/p/my-profession-before-my-job" rel="noopener noreferrer"&gt;https://open.substack.com/pub/emmanuelvalverderamos/p/my-profession-before-my-job&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3kyf71uh1hui7xz66mi1.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3kyf71uh1hui7xz66mi1.webp" alt="_Giuseppe Arcimboldi, THE WINTER 1563_" width="750" height="983"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;&lt;br&gt;
&lt;em&gt;Giuseppe Arcimboldi, THE WINTER 1563&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Me encanta mi profesión. Me encanta el software. Pero no solo el software, ojo, también todo lo que hay a su alrededor: Me encanta dar forma y formar parte de equipos, me encanta entender a las personas con las que trabajo y examinar nuestras relaciones. Me gusta quién soy cuando programo y me estimula de una manera que ninguna otra cosa consigue. Me encanta aprender. Estoy muy feliz por haber encontrado mi vocación.&lt;/p&gt;

&lt;p&gt;Durante mucho tiempo, esto del software ha sido uno de los pilares que sustentaban mi autopercepción y que me hacían sentir bien con lo que hacía. Ha sido algo prioritario en mi vida: he tomado decisiones basadas en maximizar este sentimiento positivo. Algunas de ellas con consecuencias desagradables y algunas con resultado totalmente distinto al esperado. No me arrepiento de ninguna aunque he aprendido de ellas y hoy elegiría distinto.  &lt;/p&gt;

&lt;p&gt;Hace poco me halagaron pidiéndome formar parte como fundador y brazo técnico de un proyecto interesante y, para mi sorpresa, tuve clarísimo que diría que no desde el principio. Incluso dejé a mi parte más soñadora darse un paseo por la fantasía del éxito. Te digo más, he tenido claro que probablemente jamás vuelva a pasar por la montaña rusa de arrancar un proyecto desde cero. Been there and done that. Simplemente ya no me interesa.&lt;/p&gt;

&lt;p&gt;Hace bastantes años que elijo mi trabajo, eso es un privilegio que hay que apreciar cada día un poco. Mis criterios de elección siempre han sido expansivos: ¿Cuál es el siguiente reto? ¿Qué proyecto me hará llegar al siguiente nivel?&lt;br&gt;&lt;br&gt;
Ni siquiera me había planteado nunca si esta manera de pensar tenía sentido. Lo asumí como lo que había que hacer. Además me había funcionado bien. Hasta que dejó de hacerlo.&lt;br&gt;&lt;br&gt;
Aterricé en una empresa donde las relaciones humanas eran distintas a las que me había encontrado hasta ahora. Encontré mucha más política de la que sé (o quiero) manejar. La mayoría de las estrategias que me han servido y que he pulido durante años ni siquiera eran implementables. En pocas palabras, un contexto desconocido y más que un poquito reacio al cambio.  &lt;/p&gt;

&lt;p&gt;Por primera vez viví en primera persona la irrelevancia. La mínima expectativa de rendimiento en lo que hago. La posibilidad de callar, hacer y poner la mano. El cobrar por hacer basura. La sorpresa de no pensar en trabajo fuera del horario laboral y la pereza al forzarme a hacerlo. En pocas palabras: la paz mediocre, el vino aguado, la siesta rentable.  &lt;/p&gt;

&lt;p&gt;En realidad no fue así. Tuve que chocarme con un muro hasta partirme el cráneo y despertar aturdido en el mismo lugar, pero que entonces fue otro.&lt;/p&gt;

&lt;p&gt;Obviamente quise cambiar mi contexto. A mi manera. Como lo había hecho antes. Sin prestar demasiada atención a la evidencia. Para ego, el que te dije, Diego. No se puede cambiar a las personas. Tampoco a los grupos de personas. Se puede apoyar el cambio, incluso liderarlo, pero no imponerlo. Intentarlo es, cuanto menos, ingenuo, además de inútil.&lt;br&gt;&lt;br&gt;
Ni que decir tiene que el camino fue doloroso en lo emocional y contraproducente en lo profesional. Mi salud mental se resintió y, dicho pronto y mal, me enseñaron la puerta.&lt;br&gt;&lt;br&gt;
No fue bueno, pero fue lo mejor. Mi proceso de duelo tocó fondo y una cita de Rafa Muñoz acudió a mi rescate:  &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Quiero dejar de hablar de las cosas malas y empezar a hablar de las buenas porque reconcentrar la mala hostia sólo me hace daño a mí y no lo sufre quien me la genera.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Mano de santo, hoyga. Como en una secuencia del tercer acto de una película mala, desperté en mi propio cuerpo pero todo era diferente: trabajo remoto, bien remunerado, horario flexible, mínima expectativa, máximo confort. Jackpot!&lt;/p&gt;

&lt;p&gt;El fondo de mi pozo era, en realidad, un agujero de gusano a otro universo donde mi trabajo y mi profesión eran cosas distintas, ¿Quién lo hubiera dicho?&lt;/p&gt;

&lt;p&gt;En mi trabajo soy una planta. Me limito a existir. Sólo necesito un poquito de agua y sol. Las plantas no discuten, fotosintetizan luz de monitor en dinero a final de mes. Mi trabajo acaba a media tarde, mi profesión empieza a partir de entonces.&lt;/p&gt;

&lt;p&gt;Libros, katas, conferencias, podcasts… El blanco y negro se torna en color y la savia en sangre de nuevo. Soy, a partir de entonces, la versión de mí que más disfruto. No necesito que me paguen por ello.&lt;/p&gt;

&lt;p&gt;Quizás algún día, mi trabajo y mi profesión vuelvan a converger, espero que lo hagan, de verdad, pero, de momento, me he liberado de esa necesidad. He encontrado equilibrio al otro lado del máximo local que había entendido como absoluto. Equilibrio inestable, quizá, pero necesario y suficiente. Por ahora.&lt;/p&gt;

</description>
      <category>cultura</category>
    </item>
    <item>
      <title>Unlock the Secrets of Software Testing: State-Based, Output-Based, and Communication-Based verifications</title>
      <dc:creator>Emmanuel Valverde Ramos</dc:creator>
      <pubDate>Tue, 04 Feb 2025 08:00:52 +0000</pubDate>
      <link>https://dev.to/evrtrabajo/unlock-the-secrets-of-software-testing-state-based-output-based-and-communication-based-20j5</link>
      <guid>https://dev.to/evrtrabajo/unlock-the-secrets-of-software-testing-state-based-output-based-and-communication-based-20j5</guid>
      <description>&lt;h3&gt;
  
  
  Who is this article for?
&lt;/h3&gt;

&lt;p&gt;This article is designed for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Beginners exploring the world of automated testing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Individuals starting with Test-Driven Development (TDD) want to understand what makes a good test.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What this article won't cover
&lt;/h3&gt;

&lt;p&gt;While this article provides a strong foundation, it won't cover:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;TDD processes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Strategies like the Test Pyramid.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Types of tests (e.g., unit vs. integration).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Test doubles such as mocks, stubs, or spies.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead, we'll focus on the characteristics that define a great automated test.&lt;/p&gt;

&lt;h3&gt;
  
  
  Introduction to testing types of verifications
&lt;/h3&gt;

&lt;p&gt;In software testing, it's crucial to understand different verification styles to ensure code quality, robustness, and maintainability. This section focuses on three distinct styles of assertions: &lt;strong&gt;State-Based&lt;/strong&gt; , &lt;strong&gt;Output-Based&lt;/strong&gt; , and &lt;strong&gt;Communication-Based&lt;/strong&gt;. These approaches are based on concepts from Vladimir Khorikov's book &lt;em&gt;Unit Testing Principles, Practices, and Patterns&lt;/em&gt;, and are further explored in Emily Bache's article on test design styles. Each style offers a unique way to test your system, varying based on system behavior, dependency interactions, and verification requirements.&lt;/p&gt;

&lt;h3&gt;
  
  
  The SUT and its behavior
&lt;/h3&gt;

&lt;p&gt;The fundamental connection between these test types: &lt;strong&gt;State-Based&lt;/strong&gt; , &lt;strong&gt;Output-Based&lt;/strong&gt; , and &lt;strong&gt;Communication-Based&lt;/strong&gt; —centers on the System Under Test (SUT) and its behavior. The appropriate testing approach depends on what's being tested (whether a class, component, or microservice) and what needs verification (state changes, outputs, or interactions).&lt;/p&gt;

&lt;p&gt;This framework simplifies test categorization by focusing on how the SUT behaves in different scenarios. From unit tests checking object states to integration tests verifying module communication, or contract tests confirming service interactions—each test ensures the SUT behaves as intended.&lt;/p&gt;

&lt;p&gt;In conclusion, effective testing goes beyond mere categorization or naming conventions. What matters most is the type of verification performed, the expected behavior of the SUT, and the long-term costs of test maintenance.&lt;/p&gt;

&lt;h3&gt;
  
  
  State-Based verification
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2bxe5fthw0q4exb1rcsf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2bxe5fthw0q4exb1rcsf.png" alt="State-Based verification" width="800" height="350"&gt;&lt;/a&gt;&lt;/p&gt;





&lt;p&gt;&lt;strong&gt;State-based tests&lt;/strong&gt; verify the final state of a system after an operation is completed. These tests check whether the state of the system under test (SUT) or its collaborators has changed as expected after acting. The state can refer to the SUT itself, its dependencies, or external dependencies like databases or file systems.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt; : This testing style is ideal for validating system state changes after specific interactions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt; : Consider a payment processing class. After calling the payment method, a state-based test would verify that the customer's balance has decreased by the correct amount.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Test
void add_given_product_to_the_order() {
  // Arrange
  Product product = new Product("Free Guy");
  Order sut = new Order();

  // Act
  sut.add(product);

  // Assert
  assertThat(sut.products())
      .hasSize(1)
      .containsExactly(product);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;State-based tests excel at verifying persistent changes, especially when code has side effects that need tracking—such as database writes or object state modifications.&lt;/p&gt;

&lt;h3&gt;
  
  
  Output-Based verification
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj1csqkvfx0x1gvzq0cyo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj1csqkvfx0x1gvzq0cyo.png" alt="Output-Based verification" width="800" height="362"&gt;&lt;/a&gt;&lt;/p&gt;





&lt;p&gt;&lt;strong&gt;Output-based tests&lt;/strong&gt; focus on providing input to the system under test (SUT) and verifying its output. These tests work with pure functions—those that produce no side effects and return only a value to the caller.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt; : These tests are ideal for functional units where the output depends solely on the input.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt; : Consider a function that adds two numbers. An output-based test would feed different number pairs into the function and verify that each sum matches the expected result.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Test
void discount_of_two_products_should_be_two_percent() {
  // Arrange
  Product product1 = new Product("Kaamelott");
  Product product2 = new Product("Free Guy");

  // Act
  double discount = PriceEngine.calculateDiscount(product1, product2);

  // Assert
  assertThat(discount).isEqualTo(0.02);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since output-based tests treat the system as a black box, they are effective at testing business rules and pure logic in a clean, straightforward manner.&lt;/p&gt;

&lt;h3&gt;
  
  
  Communication-Based verification
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fejn9ucds7d47czg81pa0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fejn9ucds7d47czg81pa0.png" alt="Communication-Based verification" width="800" height="301"&gt;&lt;/a&gt;&lt;/p&gt;





&lt;p&gt;&lt;strong&gt;Communication-based tests&lt;/strong&gt; verify how a system interacts with its collaborators by checking that the system under test makes the correct method calls to its dependencies. These dependencies are typically replaced with test doubles—mocks, stubs, or spies.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt; : Communication-based tests focus on verifying interactions rather than final states or outputs. They shine when testing systems with complex dependencies or when an operation's correctness depends on specific calls to collaborators.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt; : Consider a class that sends emails for new user registrations. Rather than testing if an email was actually sent (which would require an external service), you would use a mock email sender to verify that it received the correct parameters.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Test
void greet_a_user_should_send_an_email_to_it() {
  // Arrange
  String email = "john.doe@email.com";
  EmailGateway emailGatewaySpy = mock(EmailGateway.class);
  Controller sut = new Controller(emailGatewaySpy);

  // Act
  sut.greetUser(email);

  // Assert
  verify(emailGatewaySpy, times(1)).sendGreetingsEmail(email);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Communication-based tests are particularly useful for validating how the SUT works—ensuring that methods interact correctly with their dependencies. These tests can serve as a bridge between unit tests and integration tests when verifying communication flows.&lt;/p&gt;

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

&lt;p&gt;These three testing approaches offer distinct perspectives for verifying software correctness.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;State-based tests&lt;/strong&gt; verify state changes after an action, making them perfect for scenarios involving persistent side effects.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Output-based tests&lt;/strong&gt; excel at pure logic verification, ensuring functions produce consistent, predictable results from given inputs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Communication-based tests&lt;/strong&gt; examine how objects interact, ensuring different system components collaborate effectively.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each approach has its strengths and limitations. Choosing the right one depends on your system's specific behavior. Used together, they create a robust strategy for maintaining software quality, reliability, and adaptability to change.&lt;/p&gt;

&lt;p&gt;Thanks for reading Crafting software! This post is public so feel free to share it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://emmanuelvalverderamos.substack.com/p/unlock-the-secrets-of-software-testing?utm_source=substack&amp;amp;utm_medium=email&amp;amp;utm_content=share&amp;amp;action=share" rel="noopener noreferrer"&gt;Share&lt;/a&gt;&lt;/p&gt;

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

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Fowler, Martin. &lt;em&gt;Mocks Aren't Stubs&lt;/em&gt;. &lt;a href="https://martinfowler.com/articles/mocksArentStubs.html" rel="noopener noreferrer"&gt;https://martinfowler.com/articles/mocksArentStubs.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Khorikov, Vladimir. &lt;em&gt;Unit Testing Principles, Practices, and Patterns&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Bache, Emily. "Styles of Unit Tests. &lt;a href="https://sammancoaching.org/learning_hours/test_design/styles_of_unit_tests.html" rel="noopener noreferrer"&gt;https://sammancoaching.org/learning_hours/test_design/styles_of_unit_tests.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Thirion, Yoan. &lt;em&gt;Some of the graphic references in the article&lt;/em&gt;. &lt;a href="https://yoan-thirion.gitbook.io/knowledge-base/xtrem-reading/my-book-infographics" rel="noopener noreferrer"&gt;https://yoan-thirion.gitbook.io/knowledge-base/xtrem-reading/my-book-infographics&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://emmanuelvalverderamos.substack.com/survey/1553661?token=" rel="noopener noreferrer"&gt;Start Survey&lt;/a&gt;&lt;/p&gt;

</description>
      <category>testing</category>
      <category>tdd</category>
    </item>
    <item>
      <title>How to write a test?</title>
      <dc:creator>Emmanuel Valverde Ramos</dc:creator>
      <pubDate>Tue, 28 Jan 2025 08:00:48 +0000</pubDate>
      <link>https://dev.to/evrtrabajo/how-to-write-a-test-5eo7</link>
      <guid>https://dev.to/evrtrabajo/how-to-write-a-test-5eo7</guid>
      <description>&lt;h3&gt;
  
  
  Who is this article for?
&lt;/h3&gt;

&lt;p&gt;This article is designed for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Beginners exploring the world of automated testing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Individuals starting with Test-Driven Development (TDD) want to understand what makes a good test.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What this article won't cover
&lt;/h3&gt;

&lt;p&gt;While this article provides a strong foundation, it won't cover:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;TDD processes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Strategies like the Test Pyramid.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Types of tests (e.g., unit vs. integration).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Test doubles such as mocks, stubs, or spies.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead, we'll focus on the characteristics that define a great automated test.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introdución
&lt;/h2&gt;

&lt;p&gt;This article provides an introductory guide to writing tests. We'll explore the 4 phases of a test and the 3 test components, examining how they work together. To get the most from this guide, you should be familiar with the concept of Subject Under Test. Having experience with a testing framework will also help you grasp these concepts better.&lt;/p&gt;




&lt;p&gt;Crafting software is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.&lt;/p&gt;




&lt;h2&gt;
  
  
  Las 4 fases de un test
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fozccuntxb5ag0krbzb9x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fozccuntxb5ag0krbzb9x.png" alt="4 phases of a test" width="800" height="903"&gt;&lt;/a&gt;&lt;/p&gt;





&lt;h3&gt;
  
  
  &lt;strong&gt;Setup&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;This phase prepares all necessary conditions for the test. Here, you create objects, set initial states, configure dependencies, and get the test environment ready.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Examples&lt;/strong&gt; :&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Testing frameworks provide two key setup concepts to make your tests more readable: &lt;code&gt;BeforeEach&lt;/code&gt; and &lt;code&gt;BeforeAll&lt;/code&gt;. With &lt;code&gt;BeforeEach&lt;/code&gt;, any functionality defined in that method runs before each test. With &lt;code&gt;BeforeAll&lt;/code&gt;, the defined functionality runs once before the first test begins and doesn't run again until the next test suite execution.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exercise
&lt;/h3&gt;

&lt;p&gt;This phase executes the behavior being tested. You interact with the system under test (SUT) by calling the method or function you want to validate.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Examples&lt;/strong&gt; :&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Verify
&lt;/h3&gt;

&lt;p&gt;In this phase, you check if the output or behavior of the system under test matches what you expect. This is where you use assertions to verify correctness.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Use assertions to confirm that the returned value matches the expected output.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Verify interactions with test doubles when indirect outputs are involved.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This phase relates directly to verification types, which will be covered in another post.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Teardown&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;This phase restores the test environment to its original state by cleaning up resources. This prevents tests from interfering with each other when they share state or resources.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Examples&lt;/strong&gt; :&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most testing frameworks provide similar functionality for teardown as they do for setup. Methods like &lt;code&gt;AfterEach&lt;/code&gt; and &lt;code&gt;AfterAll&lt;/code&gt; work like their setup counterparts but execute after tests are complete.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 3 parts of a test - Arrange, Act, Assert or Given, When, Then
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Arrange-Act-Assert is a simple concept, and probably only adds marginal value. But it costs nothing to practice, and it gets us that much closer to being a community willing to agree on some standards. What I also like about memorable acronyms like AAA is that they provide a consistent way to communicate simple ideas, which often don't have concise and consistent names.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://agileotter.blogspot.com/" rel="noopener noreferrer"&gt;Tim Ottinger&lt;/a&gt; &amp;amp; &lt;a href="http://langrsoft.com/" rel="noopener noreferrer"&gt;Jeff Langr&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;The &lt;strong&gt;Arrange-Act-Assert (AAA)&lt;/strong&gt; pattern is a widely used method for writing clear, systematic unit tests. It divides each test into three distinct phases:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Arrange:&lt;/strong&gt; Set up the initial test conditions by creating objects, configuring dependencies, and preparing the test environment. This establishes the context for testing the desired behavior.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Act:&lt;/strong&gt; Execute the functionality you want to test by calling methods or functions of the System Under Test (SUT) using the prepared data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Assert:&lt;/strong&gt; Verify the results by comparing the actual output with expected outcomes to confirm the SUT behaves correctly.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This pattern makes tests easier to understand and maintain by separating responsibilities. Each test focuses on a specific behavior, which improves precision and effectiveness.&lt;/p&gt;

&lt;p&gt;The AAA pattern mirrors the &lt;strong&gt;Given-When-Then&lt;/strong&gt; approach used in Behavior-Driven Development (BDD), where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Given:&lt;/strong&gt; Sets up the initial context or preconditions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;When:&lt;/strong&gt; Describes the action or event being executed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Then:&lt;/strong&gt; Specifies the expected outcome or postcondition.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both approaches create tests that are easy to read and understand for developers, which is for me one of the most important points, because like the test desiderata mentions readability is one of the important attributes that a good test should have.&lt;/p&gt;

&lt;p&gt;These 3 parts of a test have a direct and important relationship with the first three phases of the test phases we discussed earlier. The Arrange part corresponds to the Setup phase, where we prepare our test environment. The Act part aligns with the Exercise phase, where we execute the behavior we want to test. Finally, the Assert part matches the Verify phase, where we confirm our expectations. This structured approach helps create clear, maintainable tests that are easy to understand and modify. If we examine this relationship in more detail, it would look something like this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4u7w0z59d1g5ul20tp3j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4u7w0z59d1g5ul20tp3j.png" alt="The 3 parts of a test" width="800" height="278"&gt;&lt;/a&gt;&lt;/p&gt;





&lt;p&gt;Let’s see a small example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class TemperatureConverterShould {

  @Test
  void converts_the_temperature_given_in_celsius_to_fahrenheit() {
    // Arrange
    TemperatureConverter converter = new TemperatureConverter();
    double inCelsius = 25.0;

    // Act
    double inFahrenheit = converter.celsiusToFahrenheit(inCelsius);

    // Assert
    assertEquals(77.0, inFahrenheit, 0.001); // Allowing a small delta for floating-point precision
  }
}

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Test focus on the Behavior
&lt;/h2&gt;

&lt;p&gt;To create a good test is really important to identify the behavior you are trying to test, and identify the best way of testing it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;Understanding the phases of a test is crucial—it reveals how tests work behind the scenes and provides valuable insights into your current testing phase and requirements during development.&lt;/p&gt;

&lt;p&gt;Similarly, using the Arrange-Act-Assert or Given-When-Then patterns helps separate responsibilities in tests and guides our thinking about assertions. This is why many TDD practitioners start with assertions: they shape how the test will be structured and what needs to be verified.&lt;/p&gt;

&lt;p&gt;Focus always on the behaviour to test, and identify the best way to do it.&lt;/p&gt;

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

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Ottinger, Tim. Langr, Jeff. Agile in a Flash - Arrange-Act-Assert. &lt;a href="https://agileinaflash.blogspot.com/2009/03/arrange-act-assert.html" rel="noopener noreferrer"&gt;https://agileinaflash.blogspot.com/2009/03/arrange-act-assert.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://youtu.be/8KB5aF6QXe8" rel="noopener noreferrer"&gt;Bache, Emily. 3 Parts of a TEST | Guided Learning Hour&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Bache, Emily. 3 Parts of a TEST &lt;a href="https://sammancoaching.org/learning_hours/test_design/three_parts_of_a_test.html" rel="noopener noreferrer"&gt;https://sammancoaching.org/learning_hours/test_design/three_parts_of_a_test.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Meszaros, Gerard. Four-Phase Test. &lt;a href="http://xunitpatterns.com/Four%20Phase%20Test.html#:~:text=How%20It%20Works,result%20verification%20and%20fixture%20teardown." rel="noopener noreferrer"&gt;http://xunitpatterns.com/Four%20Phase%20Test.html#:~:text=How%20It%20Works,result%20verification%20and%20fixture%20teardown.&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>testing</category>
      <category>tdd</category>
    </item>
    <item>
      <title>SOLID in PHP</title>
      <dc:creator>Emmanuel Valverde Ramos</dc:creator>
      <pubDate>Fri, 25 Sep 2020 07:29:36 +0000</pubDate>
      <link>https://dev.to/evrtrabajo/solid-in-php-d8e</link>
      <guid>https://dev.to/evrtrabajo/solid-in-php-d8e</guid>
      <description>&lt;h1&gt;
  
  
  What is SOLID? 🙄
&lt;/h1&gt;

&lt;p&gt;It is a set of principles to have good software design practices compiled by &lt;a href="https://blog.cleancoder.com/" rel="noopener noreferrer"&gt;Uncle Bob&lt;/a&gt;. &lt;/p&gt;

&lt;h1&gt;
  
  
  Why should I use them?
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Software design principles or conventions.&lt;/li&gt;
&lt;li&gt;Widely accepted in the industry.&lt;/li&gt;
&lt;li&gt;Help make code more maintainable and tolerant to changes.&lt;/li&gt;
&lt;li&gt;Applicable in terms of class design (micro-design), and also at the software architecture level.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;If you don't use SOLID, you probably code STUPID¹ without knowing it&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;¹: &lt;strong&gt;STUPID stands for&lt;/strong&gt;: Singleton, Tight Coupling, Untestability, Premature Optimization, Indescriptive Naming, Duplication&lt;/p&gt;

&lt;h1&gt;
  
  
  What does SOLID stands for
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/SOLID" rel="noopener noreferrer"&gt;SOLID&lt;/a&gt; is an acronym that stands for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;S&lt;/em&gt;&lt;/strong&gt;ingle responsibility principle&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;O&lt;/em&gt;&lt;/strong&gt;pen/closed principle&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;L&lt;/em&gt;&lt;/strong&gt;iskov substitution principle&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;I&lt;/em&gt;&lt;/strong&gt;nterface segregation principle&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;D&lt;/em&gt;&lt;/strong&gt;ependency inversion principle&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  What do we do
&lt;/h1&gt;

&lt;h1&gt;
  
  
  S - Single Responsibility Principle(SRP)
&lt;/h1&gt;

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

&lt;blockquote&gt;
&lt;p&gt;💡 A class should only have one reason to change, which means it should only have one responsibility.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;How to accomplish

&lt;ul&gt;
&lt;li&gt;Small classes with limited objectives&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Purpose or gain:

&lt;ul&gt;
&lt;li&gt;High cohesion and robustness&lt;/li&gt;
&lt;li&gt;Allow class composition (inject collaborators)&lt;/li&gt;
&lt;li&gt;Avoid code duplication&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Example
&lt;/h2&gt;

&lt;p&gt;Let's imagine we have a class that represents a text document, said document has a title and content. This document must be able to be exported to HTML and PDF.&lt;/p&gt;

&lt;h3&gt;
  
  
  Violation of the SRP 👎
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ Code coupled with more than one responsibility&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Document&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$title&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$content&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$title&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;$content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$title&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;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$content&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;getTitle&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;title&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;getContent&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;content&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;exportHtml&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"DOCUMENT EXPORTED TO HTML"&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="kc"&gt;PHP_EOL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Title: "&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getTitle&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="kc"&gt;PHP_EOL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Content: "&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getContent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="kc"&gt;PHP_EOL&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="kc"&gt;PHP_EOL&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;exportPdf&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"DOCUMENT EXPORTED TO PDF"&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="kc"&gt;PHP_EOL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Title: "&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getTitle&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="kc"&gt;PHP_EOL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Content: "&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getContent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="kc"&gt;PHP_EOL&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="kc"&gt;PHP_EOL&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 you may see  the methods or functions that we expose as APIs for other programmers to use, include the &lt;code&gt;getTitle()&lt;/code&gt; and the &lt;code&gt;getContent()&lt;/code&gt; but these methods are being used within the behavior of the same class.&lt;/p&gt;

&lt;p&gt;This breaks the &lt;a href="https://martinfowler.com/bliki/TellDontAsk.html#:~:text=Tell%2DDon't%2DAsk,an%20object%20what%20to%20do." rel="noopener noreferrer"&gt;Tell-Don't-Ask principle&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💬 Tell-Don't-Ask is a principle that helps people remember that object-orientation is about bundling data with the functions that operate on that data. It reminds us that rather than asking an object for data and acting on that data, we should instead tell an object what to do.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Finally, we also see that the class that must represent a document not only has the responsibility of representing it, but also of exporting it in different formats.&lt;/p&gt;

&lt;h3&gt;
  
  
  Following the SRP Principle 👍
&lt;/h3&gt;

&lt;p&gt;Once we have identified that the &lt;code&gt;Document&lt;/code&gt; class should not have anything other than the representation of a "document", the next thing we have to establish is the API through which we want to communicate with the export.&lt;/p&gt;

&lt;p&gt;For the export we will need to create an &lt;code&gt;interface&lt;/code&gt; that receives a document.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;ExportableDocumentInterface&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;export&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Document&lt;/span&gt; &lt;span class="nv"&gt;$document&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The next thing we have to do is extract the logic that does not belong to the 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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HtmlExportableDocument&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;ExportableDocumentInterface&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;export&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Document&lt;/span&gt; &lt;span class="nv"&gt;$document&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"DOCUMENT EXPORTED TO HTML"&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="kc"&gt;PHP_EOL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Title: "&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;$document&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getTitle&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="kc"&gt;PHP_EOL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Content: "&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;$document&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getContent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="kc"&gt;PHP_EOL&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="kc"&gt;PHP_EOL&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PdfExportableDocument&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;ExportableDocumentInterface&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;export&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Document&lt;/span&gt; &lt;span class="nv"&gt;$document&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"DOCUMENT EXPORTED TO PDF"&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="kc"&gt;PHP_EOL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Title: "&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;$document&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getTitle&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="kc"&gt;PHP_EOL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Content: "&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;$document&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getContent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="kc"&gt;PHP_EOL&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="kc"&gt;PHP_EOL&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;Leaving the class implementation something like 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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Document&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$title&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$content&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$title&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;$content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$title&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;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$content&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;getTitle&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;title&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;getContent&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes it easier for both the exports and the documentation class to be better tested.&lt;/p&gt;

&lt;h1&gt;
  
  
  O - Open-Closed Principle(OCP)
&lt;/h1&gt;

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

&lt;blockquote&gt;
&lt;p&gt;💡 Objects or entities should be open for extension, but closed for modification.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;How to accomplish

&lt;ul&gt;
&lt;li&gt;Avoiding depending on specific implementations, making use of abstract classes or interfaces.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Purpose or gain:

&lt;ul&gt;
&lt;li&gt;Makes it easy to add new use cases to our application&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Examples
&lt;/h2&gt;

&lt;p&gt;Let's imagine that we need to implement a login system. Initially to authenticate our user we need a username and a password (Main use case), so far so good, but what happens if we require or from business require that the user authenticate through Twitter or Gmail?&lt;/p&gt;

&lt;p&gt;To begin with, if a situation like this arises, it is important to understand that what is being asked of us is a &lt;strong&gt;new feature&lt;/strong&gt; and not that we modify the current one. And that the case of Twitter would be one use case and that of Gmail another totally different.&lt;/p&gt;

&lt;h3&gt;
  
  
  Third Party API Login - OCP Violation 👎
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LoginService&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;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$user&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;authenticateUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$user&lt;/span&gt; &lt;span class="k"&gt;instanceOf&lt;/span&gt; &lt;span class="nc"&gt;ThirdPartyUser&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;authenticateThirdPartyUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Login with third party API - Following OCP 👍
&lt;/h3&gt;

&lt;p&gt;The first thing we should do is create an interface that complies with what we want to do and that fits the specific use case.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;LoginInterface&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;authenticateUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;UserInterface&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we should decouple the logic that we had already created for our use case and implement it in a class that implements our interface.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserAuthentication&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;LoginInterface&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;authenticateUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;UserInterface&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// TODO: Implement authenticateUser() method.&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ThirdPartyUserAuthentication&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;LoginInterface&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;authenticateUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;UserInterface&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// TODO: Implement authenticateUser() method.&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LoginService&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;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;LoginInterface&lt;/span&gt; &lt;span class="nv"&gt;$loginService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;UserInterface&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$loginService&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;authenticateUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, the &lt;code&gt;LoginService&lt;/code&gt; class is agnostic of which authentication method (via web, via google or twitter, etc).&lt;/p&gt;

&lt;h3&gt;
  
  
  Payments API implemented with a switch - OCP Violation 👎
&lt;/h3&gt;

&lt;p&gt;A very common case is when we have a &lt;code&gt;switch()&lt;/code&gt;, where each case performs a different action and there is the possibility that in the future we will continue adding more cases to the switch. Let's look at the following example.&lt;/p&gt;

&lt;p&gt;Here we have a controller with a &lt;code&gt;pay()&lt;/code&gt; method, which is responsible for receiving the type of payment through the request and, depending on that type, the payment will be processed through one or another method found in the Payment class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;pay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Request&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$payment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Payment&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s1"&gt;'credit'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
            &lt;span class="nv"&gt;$payment&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;payWithCreditCard&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s1"&gt;'paypal'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
            &lt;span class="nv"&gt;$payment&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;payWithPaypal&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
            &lt;span class="c1"&gt;// Exception&lt;/span&gt;
            &lt;span class="k"&gt;break&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PaymentRequest&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;payWithCreditCard&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Logic to pay with a credit card...&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;payWithPaypal&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Logic to pay with paypal...&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 code has 2 big problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We should add one more case for each new payment that we accept or delete a case in the event that we do not accept more payments through PayPal.&lt;/li&gt;
&lt;li&gt;All the methods that process the different types of payments are found in a single class, the Payment class. Therefore, when we add a new payment type or remove one, we should edit the Payment class, and as the &lt;code&gt;Open / Closed principle&lt;/code&gt; says, this is not ideal. Like it is also violating the principle of &lt;code&gt;Single Responsibility&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This violation it's also related to a code smell call &lt;a href="https://wiki.c2.com/?SwitchStatementsSmell" rel="noopener noreferrer"&gt;Switch Statements Smell&lt;/a&gt; if you want to know more about refactors or examples go into &lt;a href="https://refactoring.guru/es/smells/switch-statements" rel="noopener noreferrer"&gt;refactoring guru&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Payments API implemented with a switch - Following OCP 👍
&lt;/h3&gt;

&lt;p&gt;The first thing we could do to try to comply with the OCP is to create an interface with the &lt;code&gt;pay()&lt;/code&gt; method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;PayableInterface&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;pay&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 will proceed to create the classes that should implement these interfaces.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CreditCardPayment&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;PayableInterface&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;pay&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Logic to pay with a credit card...&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PaypalPayment&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;PayableInterface&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;pay&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Logic to pay with paypal...&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The next step would be to refactor our &lt;code&gt;pay()&lt;/code&gt; method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;pay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Request&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$paymentFactory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PaymentFactory&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nv"&gt;$payment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$paymentFactory&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$payment&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;pay&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;blockquote&gt;
&lt;p&gt;👁 As you can see, we have replaced the switch with a factory.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PaymentFactory&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;initialize&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;$type&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;PayableInterface&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s1"&gt;'credit'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CreditCardPayment&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s1"&gt;'paypal'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PayPalPayment&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;\Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Payment method not supported"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Benefits of the Open / Closed Principle
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Extend the functionalities of the system, without touching the core of the system.&lt;/li&gt;
&lt;li&gt;We prevent breaking parts of the system by adding new functionalities.&lt;/li&gt;
&lt;li&gt;Ease of testing.&lt;/li&gt;
&lt;li&gt;Separation of the different logics.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🎨 Design patterns that we can find useful for OCP
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://refactoring.guru/design-patterns/factory-method/php/example" rel="noopener noreferrer"&gt;Factory&lt;/a&gt; - &lt;a href="https://youtu.be/EcFVTgRHJLM" rel="noopener noreferrer"&gt;Video&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://refactoring.guru/design-patterns/adapter" rel="noopener noreferrer"&gt;Adapter&lt;/a&gt; - &lt;a href="https://youtu.be/v-GiuMmsXj4" rel="noopener noreferrer"&gt;Video&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  L - Liskov Substitution Principle(LSP)
&lt;/h1&gt;

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

&lt;p&gt;This principle was introduced by the guru and the first woman in America to earn a Ph.D. in Computer Science, Barbara Liskov. And it is a very interesting principle.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;According to Wikipedia. Liskov's Substitution Principle says that each class that inherits from another can be used as its parent without having to know the differences between them.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Concepts:

&lt;ul&gt;
&lt;li&gt;If &lt;strong&gt;S&lt;/strong&gt; is a subtype of &lt;strong&gt;T&lt;/strong&gt;, instances of &lt;strong&gt;T&lt;/strong&gt; should be substitutable for instances of S without altering the program properties, That is, by having a hierarchy it means that we are establishing a contract in the father, so ensuring that this contract is maintained in the child will allow us to replace the father and the application will continue to work perfectly.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;How to accomplish:

&lt;ul&gt;
&lt;li&gt; The behavior of the sub-classes must respect the contract established in the super-class.&lt;/li&gt;
&lt;li&gt; Maintain functional &lt;a href="https://en.wikipedia.org/wiki/Correctness_(computer_science)" rel="noopener noreferrer"&gt;correctness&lt;/a&gt; to be able to apply OCP.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;There are 3 important points that we have to keep in mind in order not to violate the &lt;strong&gt;Liskov&lt;/strong&gt; principle:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Not to strengthen the pre-conditions and not to weaken the post-conditions of the parent class (&lt;a href="https://en.wikipedia.org/wiki/Defensive_programming" rel="noopener noreferrer"&gt;defensive programming&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;The invariants set in the base class must be kept in the subclasses.&lt;/li&gt;
&lt;li&gt;Cannot be a method in the subclass that goes against a behavior of the base class. This is called &lt;strong&gt;Historical Constraint&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Example
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Shipping calculation
&lt;/h3&gt;

&lt;p&gt;Let's say we have a Shipping class that is going to calculate the shipping cost of a product given its weight and destination.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Shipping&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;calculateShippingCost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$weightOfPackageKg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$destiny&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Pre-condition:&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$weightOfPackageKg&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;\Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Package weight cannot be less than or equal to zero'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// We calculate the shipping cost by&lt;/span&gt;
        &lt;span class="nv"&gt;$shippingCost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;rand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Post-condition&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$shippingCost&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;\Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Shipping price cannot be less than or equal to zero'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$shippingCost&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;h3&gt;
  
  
  Shipping calculation - LSP violation due to behavior change in daughter class 👎
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;WorldWideShipping&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Shipping&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;calculateShippingCost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$weightOfPackageKg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$destiny&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Pre-condition&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$weightOfPackageKg&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;\Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Package weight cannot be less than or equal to zero'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// We strengthen the pre-conditions&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;empty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$destiny&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;\Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Destiny cannot be empty'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// We calculate the shipping cost by&lt;/span&gt;
        &lt;span class="nv"&gt;$shippingCost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;rand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// By changing the post-conditions we allow there to be cases&lt;/span&gt;
        &lt;span class="c1"&gt;// in which the shipping is 0&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Spain'&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nv"&gt;$destiny&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nv"&gt;$shippingCost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$shippingCost&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The problem is that we generate with a class like the previous one is that we are exposing a similar API for programmers, but that has a different implementation.&lt;/p&gt;

&lt;p&gt;This class will be the parent class of our example where its method to calculate the shipping price has a pre and a post condition (this way of programming using the pre and post conditions is called Defensive Programming).&lt;/p&gt;

&lt;p&gt;For example, a programmer on our team is sure that the &lt;code&gt;calculateShippingCost()&lt;/code&gt; method, of the &lt;code&gt;Shipping&lt;/code&gt; class, allows &lt;code&gt;null&lt;/code&gt; destination and shipping costs greater than zero, so by wanting to use the &lt;code&gt;WorldWideShipping&lt;/code&gt; class, it could cause the system to burst, for example, if you want to use the result of &lt;code&gt;calculateShippingCost()&lt;/code&gt; in a slice or by giving it a &lt;code&gt;null&lt;/code&gt; destiny.&lt;/p&gt;

&lt;p&gt;Therefore, the WorldWideShipping class is violating the Liskov substitution principle.&lt;/p&gt;

&lt;h3&gt;
  
  
  Shipping calculation - LSP violation due to change of invariants from child class 👎
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;The &lt;a href="https://en.wikipedia.org/wiki/Class_invariant" rel="noopener noreferrer"&gt;invariants&lt;/a&gt; are values ​​of the parent class that cannot be modified by the child classes.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's say we want to modify the &lt;code&gt;Shipping&lt;/code&gt; class that we had before and we want to make the limit of the weight per kilos be 0 but that it is in a variable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Shipping&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$weightGreaterThan&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&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;calculateShippingCost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$weightOfPackageKg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$destiny&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Pre-condition:&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$weightOfPackageKg&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&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;weightGreaterThan&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;\Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Package weight cannot be less than or equal to &lt;/span&gt;&lt;span class="si"&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;weightGreaterThan&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// We calculate the shipping cost by&lt;/span&gt;
        &lt;span class="nv"&gt;$shippingCost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;rand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Post-condition&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$shippingCost&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;\Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Shipping price cannot be less than or equal to zero'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$shippingCost&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;WorldWideShipping&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Shipping&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;calculateShippingCost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$weightOfPackageKg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$destiny&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// We modify the value of the parent class&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;weightGreaterThan&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// Pre-condition&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$weightOfPackageKg&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&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;weightGreaterThan&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;\Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Package weight cannot be less than or equal to &lt;/span&gt;&lt;span class="si"&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;weightGreaterThan&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;// Previous code...&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;h3&gt;
  
  
  Shipping calculation - Following LSP by change of invariants from child class 👍
&lt;/h3&gt;

&lt;p&gt;The easiest way to avoid this would be to simply create the variable &lt;code&gt;$weightOfPackageKg&lt;/code&gt; as a private constant if our version of &lt;strong&gt;PHP (7.1.0)&lt;/strong&gt; allows it but by creating that private variable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Historical Restrictions
&lt;/h2&gt;

&lt;p&gt;Historical restrictions say that there cannot be a method in the child class that goes against a behavior of its parent class.&lt;/p&gt;

&lt;p&gt;That is, if in the parent class there is the &lt;code&gt;FixedTax()&lt;/code&gt; method, then the &lt;code&gt;ModifyTax()&lt;/code&gt; method cannot exist in the child class. Or didn't they teach you not to disobey your parents? 😆.&lt;/p&gt;

&lt;p&gt;For a method of the subclass to modify the value of a property of the base class is a violation of the &lt;strong&gt;Liskov&lt;/strong&gt; principle because classes must be able to change the value of their properties only (&lt;strong&gt;Encapsulation&lt;/strong&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  The easiest way not to break the LSP
&lt;/h2&gt;

&lt;p&gt;The best way not to break LSP is by using Interfaces. Instead of extending our child classes from a parent 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="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;CalculabeShippingCost&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;calculateShippingCost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$weightOfPackageKg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$destiny&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;WorldWideShipping&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;CalculabeShippingCost&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;calculateShippingCost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$weightOfPackageKg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$destiny&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Implementation of logic&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;By using interfaces you can implement methods that various classes have in common, but each method will have its own implementation, its own pre and post conditions, its own invariants, etc. We are not tied to a parent class.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ This does not mean that we start using interfaces everywhere, although they are very good. But sometimes it is better to use base classes and other times interfaces. It all depends on the situation.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Interfaces 🆚 Abstract Class
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Interface benefits

&lt;ul&gt;
&lt;li&gt;Does not modify the hierarchy tree&lt;/li&gt;
&lt;li&gt;Allows to implement N Interfaces&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Benefits of Abstract Class

&lt;ul&gt;
&lt;li&gt;It allows to develop the &lt;code&gt;Template Method&lt;/code&gt;¹ pattern by pushing the logic to the model.
Problem: Difficulty tracing who the actors are and when capturing errors&lt;/li&gt;
&lt;li&gt;Private getters (&lt;a href="https://martinfowler.com/bliki/TellDontAsk.html#:~:text=Tell%2DDon't%2DAsk,an%20object%20what%20to%20do." rel="noopener noreferrer"&gt;Tell-Don't-Ask principle&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;¹. Design pattern Template Method: It states that in the abstract class we would define a method body that defines what operation we are going to perform, but we would be calling some methods defined as abstract (delegating the implementation to the children). But beware! 👀 this implies a loss of traceability of our code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion of Interfaces 🆚 Abstract Class
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;When do we use Interfaces?: When we are going to decouple between layers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When do we use Abstract?: In certain cases for Domain Models (&lt;a href="https://en.wikipedia.org/wiki/Domain_model" rel="noopener noreferrer"&gt;Domain models&lt;/a&gt; not ORM models, to avoid &lt;a href="https://www.martinfowler.com/bliki/AnemicDomainModel.html" rel="noopener noreferrer"&gt;anemic domain models&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🎨 Design patterns that can be useful to us in the LSP
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://refactoring.guru/design-patterns/template-method" rel="noopener noreferrer"&gt;Template method&lt;/a&gt; - &lt;a href="https://youtu.be/7ocpwK9uesw" rel="noopener noreferrer"&gt;Video&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://refactoring.guru/design-patterns/composite" rel="noopener noreferrer"&gt;Composite&lt;/a&gt; - &lt;a href="https://youtu.be/EWDmWbJ4wRA" rel="noopener noreferrer"&gt;Video&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://refactoring.guru/design-patterns/strategy" rel="noopener noreferrer"&gt;Strategy&lt;/a&gt; - &lt;a href="https://youtu.be/v9ejT8FO-7I" rel="noopener noreferrer"&gt;Video&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://refactoring.guru/design-patterns/state" rel="noopener noreferrer"&gt;State&lt;/a&gt; - &lt;a href="https://youtu.be/N12L5D78MAA" rel="noopener noreferrer"&gt;Viedo&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  I - Interface Segregation Principle (ISP)
&lt;/h1&gt;

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

&lt;blockquote&gt;
&lt;p&gt;💡 A client should only know the methods they are going to use and not those that they are not going to use.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Basically, what this principle refers to is that we should not create classes with thousands of methods where it ends up being a huge file. Since we are generating a monster class, where most of the time we will only use some of its methods each time. And for that it refers to the need for interfaces, it is also important to understand that this helps a lot at the &lt;strong&gt;Single Responsibility Principle(SRP)&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How to accomplish

&lt;ul&gt;
&lt;li&gt;Define interface contracts based on the clients that use them and not on the implementations that we could have (The interfaces belong to the clients).&lt;/li&gt;
&lt;li&gt;Avoid &lt;em&gt;Header Interfaces&lt;/em&gt; by promoting &lt;em&gt;Role Interfaces&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Purpose or gain:

&lt;ul&gt;
&lt;li&gt;High cohesion and low structural coupling&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Header Interfaces
&lt;/h2&gt;

&lt;p&gt;Martin fowler in the article &lt;a href="https://martinfowler.com/bliki/HeaderInterface.html" rel="noopener noreferrer"&gt;HeaderInterface&lt;/a&gt; sustain.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💬 A header interface is an explicit interface that mimics the implicit public interface of a class. Essentially you take all the public methods of a class and declare them in an interface. You can then supply an alternative implementation for the class. This is the opposite of a RoleInterface - I discuss more details and the pros and cons there.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Role Interfaces
&lt;/h2&gt;

&lt;p&gt;Martin fowler in the article &lt;a href="https://martinfowler.com/bliki/RoleInterface.html#:~:text=A%20role%20interface%20is%20defined,only%20have%20a%20single%20interface." rel="noopener noreferrer"&gt;RoleInterface&lt;/a&gt; sustain.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💬 A role interface is defined by looking at a specific interaction between suppliers and consumers. A supplier component will usually implement several role interfaces, one for each of these patterns of interaction. This contrasts to a HeaderInterface, where the supplier will only have a single interface.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Examples
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Simple Example
&lt;/h3&gt;

&lt;p&gt;We want to be able to send notifications via email, Slack, or txt file. What signature will the interface have? 📨&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a) $notifier($content) ✔️&lt;/li&gt;
&lt;li&gt;b) $notifier($slackChannel, $messageTitle, $messageContent, $messageStatus) ❌&lt;/li&gt;
&lt;li&gt;c) $notifier($recieverEmail, $emailSubject, $emailContent) ❌&lt;/li&gt;
&lt;li&gt;d) $notifier($destination, $subject, $content) ❌&lt;/li&gt;
&lt;li&gt;e) $notifier($filename, $tag, $description) ❌&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can rule out that options B, C and E, since Header Interface would be based on the implementation (for Slack, email and file respectively).&lt;/p&gt;

&lt;p&gt;In the case of option D, we could consider it invalid given that the type &lt;code&gt;$destination&lt;/code&gt; It does not offer us any specificity (we do not know if it is an email, a channel ...).&lt;/p&gt;

&lt;p&gt;Finally, in option A, we would only be sending the content, so the particularities of each of the types of notification would have to be given in the constructor (depending on the use case you could not always).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;👁 The interfaces belong to the clients and not to those who implement them.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Example Developer | QA | PM - ISP violation due to excess responsibilities and poor abstraction 👎
&lt;/h3&gt;

&lt;p&gt;A simple example would be the following situation. Let's imagine that we have developers, a QA team and a project manager who have to determine whether to program.&lt;/p&gt;

&lt;p&gt;Let's say the programmer can program and test, while the QA can only test.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;Workable&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;canCode&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;code&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;test&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Developer&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Workable&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;canCode&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="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="n"&gt;code&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;'coding'&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;test&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;'testing in localhost'&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Tester&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Workable&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;canCode&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="kc"&gt;false&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;code&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// El QA no puede programar&lt;/span&gt;
         &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Opps! I can not code'&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;test&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;'testing in test server'&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ProjectManagement&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;processCode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Workable&lt;/span&gt; &lt;span class="nv"&gt;$member&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$member&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;canCode&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nv"&gt;$member&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;code&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we pay attention we will see that the &lt;code&gt;Tester&lt;/code&gt; class has a method that does not correspond to it since it is not called and if it is called it would give us an &lt;code&gt;Exception&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So we should make a small refactor to be able to comply with the principle of segregation of interfaces.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example Developer | QA | PM - Following ISP 👍
&lt;/h3&gt;

&lt;p&gt;The first thing is to identify what actions we have to perform, design the interfaces and assign these interfaces to the corresponding actors depending on the use case.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;Codeable&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;code&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;Testable&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;test&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Programmer&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Codeable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Testable&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;code&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;'coding'&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;test&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;'testing in localhost'&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Tester&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Testable&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;test&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;'testing in test server'&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ProjectManagement&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;processCode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Codeable&lt;/span&gt; &lt;span class="nv"&gt;$member&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$member&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;code&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code does comply with the principle of segregation of interfaces. As with the previous principles.&lt;/p&gt;

&lt;h2&gt;
  
  
  🎨 Design patterns that can be useful to us in the ISP
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://refactoring.guru/design-patterns/chain-of-responsibility" rel="noopener noreferrer"&gt;Chain of Responsibility&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://refactoring.guru/design-patterns/strategy" rel="noopener noreferrer"&gt;Strategy&lt;/a&gt; - &lt;a href="https://youtu.be/v9ejT8FO-7I" rel="noopener noreferrer"&gt;Video&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://refactoring.guru/design-patterns/state" rel="noopener noreferrer"&gt;State&lt;/a&gt; - &lt;a href="https://youtu.be/N12L5D78MAA" rel="noopener noreferrer"&gt;Viedo&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  D - Dependency Inversion Principle (DIP)
&lt;/h1&gt;

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

&lt;p&gt;I must first make it clear that Dependency Injection is NOT the same as Dependency Inversion. Dependency inversion is a principle, while dependency injection is a design pattern.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 High-level modules should not depend on low-level ones. Both should depend on abstractions&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;How to accomplish

&lt;ul&gt;
&lt;li&gt;Inject dependencies (parameters received in constructor).&lt;/li&gt;
&lt;li&gt;Rely on the interfaces (contracts) of these dependencies and not on specific implementations.&lt;/li&gt;
&lt;li&gt;LSP as a premise.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Purpose or gain:

&lt;ul&gt;
&lt;li&gt;Facilitate the modification and replacement of implementations.&lt;/li&gt;
&lt;li&gt;Better class testability&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;The principle of dependency injection tries to maintain a low coupling.&lt;/p&gt;

&lt;h2&gt;
  
  
  Laravel controller example
&lt;/h2&gt;

&lt;p&gt;Let's say we have a &lt;code&gt;UserController&lt;/code&gt;. What in its &lt;code&gt;index&lt;/code&gt; method what it does is return a &lt;code&gt;JSON&lt;/code&gt; list of users with the users created the previous day.&lt;/p&gt;

&lt;h3&gt;
  
  
  Laravel controller - DIP Violation 👎
&lt;/h3&gt;



&lt;div class="highlight js-code-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="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nv"&gt;$users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$users&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'created_at'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Carbon&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;yesterday&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;get&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;response&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;json&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'users'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$users&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code wouldn't be bad, because it would clearly work. But at the same time it would generate the following problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;We cannot reuse the code&lt;/strong&gt; as we are tied to Eloquent.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It is difficult to test&lt;/strong&gt; the methods that instantiate one or several objects (high coupling), since it is difficult to verify that it is failing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It breaks the principle of single responsibility&lt;/strong&gt;, because, in addition to the method doing its job, it also has to create the objects in order to do its job.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Laravel controller - Following the DIP 👍
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;UserRepositoryInterface&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// 👁 I am returning an array&lt;/span&gt;
    &lt;span class="c1"&gt;// but it should return Domain Models&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;getUserFromYesterday&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;DateInterface&lt;/span&gt; &lt;span class="nv"&gt;$date&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;array&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserEloquentRepository&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;UserRepositoryInterface&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;getUserFromYesterday&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;DateInterface&lt;/span&gt; &lt;span class="nv"&gt;$date&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;array&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'created_at'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'&amp;gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;get&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;toArray&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserSqlRepository&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;UserRepositoryInterface&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;getUserFromYesterday&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;DateInterface&lt;/span&gt; &lt;span class="nv"&gt;$date&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;array&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;\DB&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'users'&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;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'created_at'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'&amp;gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;get&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;toArray&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserCsvRepository&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;UserRepositoryInterface&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;getUserFromYesterday&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;DateInterface&lt;/span&gt; &lt;span class="nv"&gt;$date&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;array&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// 👁 I am accessing the infrastructure&lt;/span&gt;
        &lt;span class="c1"&gt;// from the same method maybe not the best&lt;/span&gt;
        &lt;span class="nv"&gt;$fileName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"users_created_&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$date&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.csv"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;$fileHandle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;fopen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$fileName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'r'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;$users&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;fgetscsv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$fileHandle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;","&lt;/span&gt;&lt;span class="p"&gt;))&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;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="nb"&gt;fclose&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$fileHandle&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;$users&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 we can see, all classes implement the &lt;code&gt;UserRespositoryInterface&lt;/code&gt; interface. And this gives us the freedom to get the users either from &lt;code&gt;Eloquent&lt;/code&gt;, from&lt;code&gt;SQL&lt;/code&gt; or from a &lt;code&gt;CSV&lt;/code&gt; 👏😲 file.&lt;/p&gt;

&lt;p&gt;This is fine and would work in a normal application, but how do we make the Laravel controller receive that repository in its index method?&lt;/p&gt;

&lt;p&gt;The answer is registering the interface with which class it has &lt;strong&gt;by default&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="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\Providers&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;Illuminate\Support\ServiceProvider&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;AppServiceProvider&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;ServiceProvider&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;register&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s1"&gt;'App\Repositories\Contracts\UserRepositoryInterface'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'App\Repositories\UserCsvRepository'&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;In other frameworks like Symfony it can be done using &lt;a href="https://php-di.org/" rel="noopener noreferrer"&gt;PHP DI&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusions
&lt;/h1&gt;

&lt;p&gt;In order to make a more maintainable, reusable and testable code we should try to implement these principles. Like we should know the design patterns that could be useful when we use these principles.&lt;/p&gt;

&lt;h1&gt;
  
  
  Webgraphy
&lt;/h1&gt;

&lt;p&gt;🇪🇸&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.franciscougalde.com/2019/07/26/patrones-de-diseno-en-php-solid/" rel="noopener noreferrer"&gt;Francisco&lt;/a&gt; - &lt;a href="https://twitter.com/fjugaldev" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://youtu.be/Be-ULOIGAZk" rel="noopener noreferrer"&gt;Por qué NO usar getters y setters | Tell don't ask&lt;/a&gt; - &lt;a href="https://twitter.com/CodelyTV" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; - &lt;a href="https://www.youtube.com/CodelyTV" rel="noopener noreferrer"&gt;Youtube&lt;/a&gt; - &lt;a href="https://codely.tv/pro/cursos?utm_source=youtube&amp;amp;utm_medium=social&amp;amp;utm_campaign=dev.to-emmanuel-valverde-ramos&amp;amp;utm_content=Cursos"&gt;Courses&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://youtu.be/mDAQLkdNGHU" rel="noopener noreferrer"&gt;Errores comunes al diseñar Interfaces - #SOLID - ISP&lt;/a&gt; - &lt;a href="https://twitter.com/CodelyTV" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; - &lt;a href="https://www.youtube.com/CodelyTV" rel="noopener noreferrer"&gt;Youtube&lt;/a&gt; - &lt;a href="https://codely.tv/pro/cursos?utm_source=youtube&amp;amp;utm_medium=social&amp;amp;utm_campaign=dev.to-emmanuel-valverde-ramos&amp;amp;utm_content=Cursos"&gt;Courses&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://youtu.be/EzUIbMdxJTk" rel="noopener noreferrer"&gt;Principio de Segregación de Interfaces - SOLID&lt;/a&gt; - &lt;a href="https://twitter.com/CodelyTV" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; - &lt;a href="https://www.youtube.com/CodelyTV" rel="noopener noreferrer"&gt;Youtube&lt;/a&gt; - &lt;a href="https://codely.tv/pro/cursos?utm_source=youtube&amp;amp;utm_medium=social&amp;amp;utm_campaign=dev.to-emmanuel-valverde-ramos&amp;amp;utm_content=Cursos"&gt;Courses&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://herminioheredia.com.mx/2019/06/19/domina-la-inyeccion-de-dependencias-de-laravel/" rel="noopener noreferrer"&gt;Herminio Heredia Santos - domina la inyeccion de dependencias de laravel&lt;/a&gt; - &lt;a href="https://twitter.com/HerminioHeredia" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; - &lt;a href="https://www.linkedin.com/in/herminio-heredia-santos-477aab19/" rel="noopener noreferrer"&gt;LinkedLn&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.laraveltip.com/desacoplando-laravel-de-tu-aplicacion/" rel="noopener noreferrer"&gt;Laravel tip - Desacoplando Laravel de tu aplicación&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;(🇬🇧/🇺🇸)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/playlist?list=PLrhzvIcii6GNjpARdnO4ueTUAVR9eMBpc" rel="noopener noreferrer"&gt;Design Patterns in Object Oriented Programming&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>php</category>
      <category>solid</category>
      <category>oop</category>
      <category>laravel</category>
    </item>
  </channel>
</rss>
