<?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: Javier Ledezma</title>
    <description>The latest articles on DEV Community by Javier Ledezma (@javleds).</description>
    <link>https://dev.to/javleds</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%2F405343%2F66b28b1f-0725-4797-be8c-4b412888b362.jpeg</url>
      <title>DEV Community: Javier Ledezma</title>
      <link>https://dev.to/javleds</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/javleds"/>
    <language>en</language>
    <item>
      <title>"Controladores delgados, modelos delgados", modelos de Laravel mantenibles.</title>
      <dc:creator>Javier Ledezma</dc:creator>
      <pubDate>Fri, 07 May 2021 06:01:09 +0000</pubDate>
      <link>https://dev.to/javleds/controladores-delgados-modelos-delgados-modelos-de-laravel-mantenibles-2lnl</link>
      <guid>https://dev.to/javleds/controladores-delgados-modelos-delgados-modelos-de-laravel-mantenibles-2lnl</guid>
      <description>&lt;p&gt;¿Alguna vez has escuchado la frase "Modelos delgados, Controladores gordos"?&lt;/p&gt;

&lt;p&gt;Hablando en una arquitectura Modelo, vista, controlador (MVC), la frase se refiere a una filosofía cuyo objetivo es delegar mayor responsabilidad a los controladores e intentar dejar los modelos con la menor cantidad de líneas posibles. &lt;/p&gt;

&lt;p&gt;Al igual que esta filosofía, también existe su contraparte: "Modelos gordos, Controladores delgados" que como imaginarás, se refiere a la filosofía de delegar mayor carga a los modelos e intentar dejar los controladores con la menor cantidad de líneas de código &lt;/p&gt;

&lt;p&gt;Esta última ha sido adoptada por múltiples frameworks populares, ya que la mayoría de ellos cuentan con un ORM (Object-Relational Mapping) que permite explotar de manera muy práctica la base de datos. Un ejemplo de estos frameworks, cuyo ORM es una de las características más fuerte, es Laravel.&lt;/p&gt;

&lt;p&gt;Gracias a las características de Laravel, en los modelos solemos mapear la tabla de la base de datos, definir relaciones, colocar accesores, modificadores, eventos, colecciones, alcances, etc... Teniendo al final clases enormes y poco mantenibles.&lt;/p&gt;

&lt;p&gt;El objetivo de Laravel no es precisamente que los modelos sean poco mantenibles, simplemente se brindan las herramientas para volverlo muy práctico. Aquí es donde comienza nuestra labor como desarrolladores de software al ejercer las mejores prácticas para no llegar a ese punto.&lt;/p&gt;

&lt;p&gt;Primero que nada, debemos entender que "modelo" no es sinónimo de "lógica de negocio". Un modelo es la representación abstracta de un objeto de dominio, toda la lógica de negocio debe ser manejada por otras clases, pudiendo ser "servicios" o "acciones". Entender esto es crucial para poder comenzar a delegar responsabilidades a clases independientes.&lt;/p&gt;

&lt;p&gt;La idea en general de mantener modelos mantenibles en Laravel, es mantener el mapeo de la base de datos, definición de relaciones, casteos y accesores simples que no requieran cálculos.&lt;/p&gt;

&lt;h3&gt;
  
  
  Delegando queries a un QueryBuilder personalizado.
&lt;/h3&gt;

&lt;p&gt;Si requerimos crear fragmentos de query que puedan ser frecuentemente utilizados, también conocidos como "scopes", laravel nos provee una forma de hacerlo en 2 sencillos pasos:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Crear una clase que extienda de &lt;code&gt;Illuminate\Database\Eloquent\Builder&lt;/code&gt; en dónde vivirán todos los queries reutilizables necesarios para el proyecto.&lt;br&gt;
&lt;/p&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\QueryBuilders&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\Database\Eloquent\Builder&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;UserQueryBuilder&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Builder&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;whereActive&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;self&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'status'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;ACTIVE_STATUS&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;/li&gt;
&lt;li&gt;
&lt;p&gt;Indicar en nuestro modelo que utilice el &lt;code&gt;Builder&lt;/code&gt; que acabamos de crear.&lt;br&gt;
&lt;/p&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\Models&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kn"&gt;use&lt;/span&gt;  &lt;span class="nc"&gt;App\QueryBuilders\UserQueryBuilder&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;User&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Model&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;newEloquentBuilder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$builder&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;UserQueryBuilder&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;UserQueryBuilder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$query&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;De esta manera, Laravel sabrá que debe utilizar nuestro Builder personalizados y podremos hacer uso de él cuando sea necesario, ejemplo:&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="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;whereActive&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Moviendo colecciones a Collection personalizada.
&lt;/h3&gt;

&lt;p&gt;Si la intención es utilizar las colecciones para manipular y/o filtrar datos, Laravel nos provee la facilidad de utilizar colecciones personalizadas, nuevamente en 2 pasos:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Crear una clase que extienda de &lt;code&gt;Illuminate\Database\Eloquent\Collection&lt;/code&gt; en el que colocaremos todas las funciones relacionadas a la colección.&lt;br&gt;
&lt;/p&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\Collections&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\Database\Eloquent\Collection&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;UserCollection&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Collection&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;active&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;self&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;User&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;email_verified_at&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;null&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;/li&gt;
&lt;li&gt;
&lt;p&gt;Indicar en nuestro modelo que la colección por defecto será la clase que acabamos de crear.&lt;br&gt;
&lt;/p&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\Models&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kn"&gt;use&lt;/span&gt;  &lt;span class="nc"&gt;App\Collections\UserCollection&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;User&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Model&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;newCollection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$models&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;UserCollection&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;UserCollection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$models&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;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Nuevamente, al hacer ésto podremos hacer uso de una maner más fluida y sin cargar demasiado nuestros modelos. Ejemplo:&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="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;all&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;active&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Delegando lógica de eventos
&lt;/h3&gt;

&lt;p&gt;Uno de los mecanismos más importantes a la hora de delegar responsabilidades, es utilizar eventos y subscriptores para llevar a cabo aquellos procesos de "efecto secundario". Por default, los modelos de laravel son capaces de emitir eventos genéricos en diversas acciones, como al ser creados, modificados o eliminados. Nosotros podemos tomar ventaja de estos para mantener nuestros procesos aislados.&lt;/p&gt;

&lt;p&gt;La manera de lograrlo es a través de 4 pasos:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Crear un evento que funcionará como DTO, regularmente transportará el modelo afectado.
&lt;/li&gt;
&lt;/ol&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\Events&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

       &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Models\User&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;UserSavingEvent&lt;/span&gt;
       &lt;span class="p"&gt;{&lt;/span&gt;
           &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;User&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

           &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;User&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;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&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;ol&gt;
&lt;li&gt;Crear un subscriptor para dicho evento, nótese que la definición de qué evento se escucha se encuentra en el método &lt;code&gt;subscribe&lt;/code&gt;:
&lt;/li&gt;
&lt;/ol&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\Subscribers&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

       &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Events\UserSavingEvent&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
       &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Services\NotifyUserCreation&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\Events\Dispatcher&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;UserSubscriber&lt;/span&gt;
       &lt;span class="p"&gt;{&lt;/span&gt;
           &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;NotifyUserCreation&lt;/span&gt; &lt;span class="nv"&gt;$notifyUserCreation&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;NotifyUserCreation&lt;/span&gt; &lt;span class="nv"&gt;$notifyUserCreation&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;notifyUserCreation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$notifyUserCreation&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;saving&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;UserSavingEvent&lt;/span&gt; &lt;span class="nv"&gt;$event&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
           &lt;span class="p"&gt;{&lt;/span&gt;
               &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;notifyUserCreation&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="nv"&gt;$event&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&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;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Dispatcher&lt;/span&gt; &lt;span class="nv"&gt;$dispatcher&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
           &lt;span class="p"&gt;{&lt;/span&gt;
               &lt;span class="nv"&gt;$dispatcher&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                   &lt;span class="nc"&gt;InvoiceSavingEvent&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;'@saving'&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;ol&gt;
&lt;li&gt;Ahora debemos registrar al suscriptor dentro de nuestro &lt;code&gt;EventServiceProvider&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;       &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Subscribers\UserSubscriber&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;EventServiceProvider&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;protected&lt;/span&gt; &lt;span class="nv"&gt;$subscribe&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
               &lt;span class="nc"&gt;UserSubscriber&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="p"&gt;];&lt;/span&gt;
       &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Finalmente debemos indicarle a nuestro modelo, en la propiedad &lt;code&gt;$dispatchesEvents&lt;/code&gt; aquellos eventos que queremos despachar:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;       &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Events\UserSavingEvent&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;Invoice&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Model&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;$dispatchesEvents&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
               &lt;span class="s1"&gt;'saving'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;UserSavingEvent&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="p"&gt;];&lt;/span&gt;
       &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esta solución parece un poco larga, sin embargo, es muy escalable, si en algún momento se requiere quitar o agregar funcionalidad, nuestro Modelo se va a ver afectado en menor escala. Además separaremos toda aquella lógica en Subscribers separados, haciendo piezas más pequeñas y mantenibles.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusión
&lt;/h3&gt;

&lt;p&gt;Aunque realmente no parezca de gran impacto, comenzar a delegar responsabilidades de los modelos a clases con responsabilidades únicas nos va a ayudar a mantener nuestros modelos delgados y nuestro código en general mantenible. Y si seguimos con la idea de encapsular lógica de negocio en "servicios" o "acciones", podemos concluir que lo ideal es tener "controladores delgados y modelos delgados".&lt;/p&gt;

&lt;p&gt;En este post hablamos de Laravel en particular, sin embargo, estoy casi seguro de que los frameworks en general tienden a brindar características para que desarrollemos software a toda velocidad, sin embargo, es necesario detenernos a pensar si vale la pena sacrificar practicidad por calidad.&lt;/p&gt;

&lt;p&gt;Te invito a que pongas en práctica estas maneras de optimizar tus modelos y si vienes de un lenguaje o framework diferente, compártenos de qué manera solucionar estos problemas.&lt;/p&gt;

&lt;p&gt;Hasta la próxima.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>¿Es Laravel un aliado de software mantenible de gran escala?</title>
      <dc:creator>Javier Ledezma</dc:creator>
      <pubDate>Sun, 14 Mar 2021 20:01:28 +0000</pubDate>
      <link>https://dev.to/javleds/es-laravel-un-aliado-de-software-mantenible-de-gran-escala-5cjd</link>
      <guid>https://dev.to/javleds/es-laravel-un-aliado-de-software-mantenible-de-gran-escala-5cjd</guid>
      <description>&lt;h2&gt;
  
  
  Introducción.
&lt;/h2&gt;

&lt;p&gt;Laravel es un frameworks de desarrollo ágil que te permite desarrollar código a muy buena velocidad y centrado en el requerimiento gracias a las características "out of the box" que provee, desde base de datos, email, eventos, jobs/qeues, testing, entre otros.&lt;/p&gt;

&lt;p&gt;En este blog analizaremos que tan buen candidato es Laravel respecto a las buenas prácticas y principios de programación como lo son DDD, arquitectura hexagonal y principios SOLID.&lt;/p&gt;

&lt;h2&gt;
  
  
  Estado de Laravel en cuanto a arquitectura hexagonal.
&lt;/h2&gt;

&lt;p&gt;La arquitectura hexagonal es una forma de diseñar software por capas, se podría resumir en algo similar a lo siguiente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Dominio (Lvl 1) &amp;lt;- Aplicación (Lvl 2) &amp;lt;- Infraestructura (Lvl 3)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La capa de dominio hace referencia a una esfera de conocimiento, en otras palabras, esta capa se centra en definir y/o conceptualizar toda la lógica de negocio.&lt;/p&gt;

&lt;p&gt;La capa de aplicación, por su parte, concentra la manera de interactuar entre los usuarios y/o clientes con toda la lógica de negocio (dominio).&lt;/p&gt;

&lt;p&gt;Finalmente, la capa de infraestructura se refiere a todos los elementos externos que son necesarios para desarrollar software que no están directamente relacionados con el dominio, por ejemplo: servidores, bases de datos, incluso software o librerías de terceros.&lt;/p&gt;

&lt;p&gt;La única regla estricta en la arquitectura basada en capas es que las capas menor nivel no pueden utilizar capas de mayo nivel. Esto quiere decir, por ejemplo, que la capa de dominio puede utilizar la capa de dominio, pero no puede saber de la existencia de la capa de aplicación ni de infraestructura.&lt;/p&gt;

&lt;p&gt;La capa de aplicación puede utilizar elementos de la capa de aplicación y dominio, pero no puede saber de la existencia de elementos de la capa de infraestructura. El mismo caso para la capa de infraestructura...&lt;/p&gt;

&lt;p&gt;Retomando el tema, Laravel sacrifica un poco los principios de la arquitectura en capas para brindar practicidad. El ejemplo más claro que tenemos es Eloquent, el ORM por defecto de Laravel, permite ejecutar operaciones CRUD a una velocidad increíble, sin embargo, la definición del modelo pertenece a la capa de dominio, y la conexión con la base de datos a la capa de infraestructura.&lt;/p&gt;

&lt;h2&gt;
  
  
  Estado de Laravel respecto principios SOLID.
&lt;/h2&gt;

&lt;p&gt;Laravel, al igual que la mayoría de frameworks vienen con una serie de lineamientos que se consideran buenas prácticas, en este caso, conocido como "the laravel way". Y aunque la misma documentación busca que se implementen buenas prácticas de desarrollo, existen prácticas que podrían mejorar el desarrollo de aplicaciones con Laravel.&lt;/p&gt;

&lt;p&gt;Un ejemplo de esto es el caso de los modelos, actualmente los modelos en Laravel se utilizan para mapeo de datos, pero no solo eso, en ellos recaen responsabilidades de serialización, notificaciones, etc... &lt;/p&gt;

&lt;p&gt;"The laravel way" recomienda delegar aún más responsabilidades a los modelos con query builders, colecciones, entre otras. Sin embargo, el framework brinda todas las herramientas para abstraer estas funcionalidades en clases concretas con responsabilidades únicas, pueden verse más detalles de cómo mejorar la calidad del código en el libro/curso Laravel Beyound CRUD.&lt;/p&gt;

&lt;h2&gt;
  
  
  Estado de Laravel respecto a DDD.
&lt;/h2&gt;

&lt;p&gt;Domain Driven Design (DDD) se define como una serie de principios cuyo objetivo es desarrollar software mantenible y agnóstico a frameworks usando como base principios SOLID y arquitectura hexagonal.&lt;/p&gt;

&lt;p&gt;Para aplicar principios DDD en Laravel será necesario realizar algunos ajustes en cuanto a las convenciones de escafolding para separar el código en capas y mantenerlo organizado respecto a responsabilidades, pero es totalmente factible.&lt;/p&gt;

&lt;p&gt;En este sentido, Laravel actúa a nivel de aplicación e infraestructura, brindando mecanismos sencillos y eficientes respecto a ruteo, middlewares, controllers, comandos, etc. Por lo que debemos centrarnos en abstraer la capa de Dominio con toda la lógica de negocio y de esta manera cumplir el propósito general de DDD.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusión.
&lt;/h2&gt;

&lt;p&gt;Laravel es un framework estupendo, uno de los mejores en cuanto a practicidad y más completo en cuanto a características. Siempre busca que los desarrolladores implementen buenas prácticas, aunque en su núcleo algunas de estas prácticas se sacrifiquen para lograr esta facilidad y agilidad de desarrollo.&lt;/p&gt;

&lt;p&gt;Respecto a las herramientas de Laravel que violan algunas reglas de arquitecturas limpias o en capas, pueden ser encapsuladas para evitar este tipo de inconvenientes, sin embargo, será necesario evaluar si es totalmente necesario dependiendo de la magnitud y alcance del proyecto final para no caer en sobre ingeniería. &lt;/p&gt;

&lt;p&gt;Lo importante del desarrollo de software es crear código funcional, mantenible y de fácil crecimiento, no es necesario implementar DDD en todos los proyectos incluso, se podría implementar parcialmente dependiendo de la complejidad, pero entre más grande y complejo apegarse a estos principios facilitarán el ciclo de desarrollo del producto.&lt;/p&gt;

&lt;p&gt;Recuerda que todo comentario en bienvenido y si consideras que el contenido puede ser mejorado siéntete libre de expresarlo en comentarios.&lt;/p&gt;

&lt;p&gt;Hasta la próxima.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Entornos de desarrollo de software con Windows</title>
      <dc:creator>Javier Ledezma</dc:creator>
      <pubDate>Sat, 28 Nov 2020 15:53:42 +0000</pubDate>
      <link>https://dev.to/javleds/entornos-de-desarrollo-con-windows-1cbi</link>
      <guid>https://dev.to/javleds/entornos-de-desarrollo-con-windows-1cbi</guid>
      <description>&lt;p&gt;Si bien es cierto que los sistemas con base UNIX han demostrado ser los sistemas operativos más confiables para desarrollo de software, es muy cierto que Windows ha hecho un gran esfuerzo por posicionarse de buena manera. Y aunque siempre ha existido soporte para desarrollar con la mayoría de las tecnologías, teníamos ciertas desventajas como la dificultad para trabajar proyectos con diferentes versiones de tu lenguaje favorito (ya que cada versión tiende a venir con su propio ejecutable) y en ciertas ocasiones el rendimiento (dependiendo de las alternativas que utilizaramos).&lt;/p&gt;

&lt;p&gt;Por ejemplo, una de las opciones a las que solíamos recurrir para solucionar este problema era virtualizar aquellos entornos de desarrollo, como lo son VirtualBox o VMware, sin embargo, solía ser muy costoso en recursos y seguíamos teniendo el problema de rendimiento.&lt;/p&gt;

&lt;p&gt;Ante todo esto surgió la tecnología Windows Linux Subsystem (o WSL) quién haciendo uso de Hyper-v logró crear una capa que podía correr aplicaciones para linux de manera nativa, sin embargo, esto no se trataba más que emular un subsistema de linux en nuestro sistema operativo y teníamos ciertas limitantes de compatibilidad y también de rendimiento.&lt;/p&gt;

&lt;p&gt;Cuando surgió la segunda versión de WSL estos problemas dejaron de existir, ya que realmente utiliza el núcleo de linux como base, haciendo posible el uso total de las características de shell y mejorando por mucho los temas de rendimiento en cuanto escritura y/o lectura, con la única desventaja de tener que mover todos nuestros archivos al sistema de directorios creado por el propio WSL.&lt;/p&gt;

&lt;p&gt;La principal ventaja que trajo WSL2 fue su alta compatibilidad con docker y es que estas herramientas en conjunto resuelven la mayor parte de los problemas que teníamos, nos permiten ejecutar contenedores con las tecnología que necesitemos sin sacrificar el rendimiento.&lt;/p&gt;

&lt;p&gt;Lo que es muy cierto es que WSL2 en conjunto con docker puede requerir ajustes adicionales para lograr configurar al 100% tu entorno de desarrollo habitual, algo con lo que yo tuve problemas, fue configurar un debugger y ciertamente hay poca información al respecto, sin embargo, espero que con el tiempo uso de estas tecnologías siga incrementando y con ello el soporte para la comunidad.&lt;/p&gt;

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

&lt;p&gt;Si eres desarrollador y por alguna razón sigues pensando que windows no es una opción, te invito a que pruebes WSL2, no es una experiencia igual a trabajar sobre linux nativo, pero sin duda es una experiencia satisfactoria y te permitirá tener aquellos ejecutables que tristemente no eran compatibles con sistemas linux.&lt;/p&gt;

&lt;p&gt;Si ya tuviste experiencia utilizando WSL2 cuéntanos en los comentarios qué te ha parecido, o si tienes algún comentario o sugerencia, siempre son bienvenidos.&lt;/p&gt;

&lt;p&gt;¡Hasta pronto!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Domain Driven Design (Parte 1: Dominio)</title>
      <dc:creator>Javier Ledezma</dc:creator>
      <pubDate>Sun, 27 Sep 2020 23:18:23 +0000</pubDate>
      <link>https://dev.to/javleds/domain-driven-design-parte-1-dominio-10pa</link>
      <guid>https://dev.to/javleds/domain-driven-design-parte-1-dominio-10pa</guid>
      <description>&lt;p&gt;Dado el increíble crecimiento tecnológico de los últimos años, el desarrollo de software se ha visto forzado a evolucionar muy rápido, con ello, nacieron frameworks y librerías que nos permitían crear aplicaciones a velocidad increíble en en todos los ramos posibles, desde aplicaciones móviles con ambientes híbridos hasta librerías de Machine Learning e inteligencia artificial. El desarrollo web no es la excepción, existen múltiples herramientas que te permiten crear aplicaciones desde frontend (cómo react, vue o svelte), backend (como laravel, spring, rails o django) o aplicaciones fullstack en tiempo real (como metheor o express + socket.io).&lt;/p&gt;

&lt;p&gt;Todo parece ser muy bueno hasta que llegamos al punto de mantenibilidad, cuando necesitamos crear un producto cuyo ciclo de vida es para mucho años, en este caso, nos veremos afectados por diversas cuestiones: haciendo énfasis en la parte técnica, nos encontrarnos con actualizaciones del framework, dependencias e inclusive actualizaciones del lenguaje mismo, haciendo que el desarrollo del producto se prolongue demasiado y afectado directamente en los costos del desarrollo.&lt;/p&gt;

&lt;p&gt;Para solucionar este tipo de problemas existen arquitecturas que intentan separar lo más posible las dependencias del proyecto de los requerimientos del mismo, tal es caso de Domain Driven Design (o &lt;code&gt;DDD&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Ahora bien, &lt;code&gt;DDD&lt;/code&gt; se basa en tres principales capas, Dominio, Aplicación e Infraestructura (Puede haber variantes muy pequeñas). En esta serie de posts intentaré explicar en qué consiste &lt;code&gt;DDD&lt;/code&gt; comenzando por la capa de dominio.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dominio
&lt;/h2&gt;

&lt;p&gt;La capa de dominio es en núcleo de &lt;code&gt;DDD&lt;/code&gt;, en ella se contienen todas las clases que "modelan" a los componentes del sistema, por ejemplo, la clase &lt;code&gt;Usuario&lt;/code&gt;, &lt;code&gt;Producto&lt;/code&gt;, &lt;code&gt;Precio&lt;/code&gt;, entre otros y también en la capa de dominio se crean aquellos contratos (interfaces) que deben ser seguidos por los nuestras fuentes de datos (repositorios).&lt;/p&gt;

&lt;h3&gt;
  
  
  Entidades y objetos de valor
&lt;/h3&gt;

&lt;p&gt;Hablado de las clases base, tenemos 2 posibles variantes, &lt;code&gt;Entidades&lt;/code&gt; y &lt;code&gt;Objetos de valor&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Entidades: Representan un objeto clave de nuestra aplicación, como lo puede ser un &lt;code&gt;Usuario&lt;/code&gt;, las entidades tienden a mutar a lo largo del tiempo y tienen un grado alto de persistencia en las bases de datos, la principal característica de las entidades, es que tienden a tener un identificador.&lt;/li&gt;
&lt;li&gt;Objetos de valor: A diferencia de una entidad, un objeto de valor es inmutable, regularmente se utilizan para crear propiedades de una entidad, por ejemplo, si se tuviera nuevamente la entidad &lt;code&gt;Usuario&lt;/code&gt;,  cuyo &lt;code&gt;id&lt;/code&gt; es único, el &lt;code&gt;id&lt;/code&gt; puede ser considerado como un objeto de valor, dado que nunca va a cambiar a lo largo de todo el ciclo de vida del software.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Nota:&lt;/strong&gt; Es importante mencionar que las clases que representan &lt;code&gt;entidades&lt;/code&gt; y &lt;code&gt;objetos de valor&lt;/code&gt;, pueden cambiar de postura dependiendo del proyecto y el requerimiento, por ejemplo, en algunos sistemas, las direcciones postales pueden ser una &lt;code&gt;entidad&lt;/code&gt; y en otros simplemente una propiedad de una entidad (&lt;code&gt;objeto de valor&lt;/code&gt;).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Agregados
&lt;/h3&gt;

&lt;p&gt;Otro concepto muy importante dentro de la capa de dominio son los &lt;code&gt;agregados&lt;/code&gt;, un &lt;code&gt;agregado&lt;/code&gt; es una referencia a un grupo de objetos de dominio, un ejemplo muy práctico en un e-commerce es una &lt;code&gt;Orden&lt;/code&gt; o &lt;code&gt;Pedido&lt;/code&gt;, el cual se compone de una serie de &lt;code&gt;Artículos&lt;/code&gt; (en dónde un &lt;code&gt;Articulo&lt;/code&gt; es una entidad).&lt;/p&gt;

&lt;p&gt;El objetivo de un &lt;code&gt;agregado&lt;/code&gt; es poder crear transacciones sobre ese grupo en concreto de entidades u objetos de valor, en dónde, regresando al ejemplo del &lt;code&gt;Pedido&lt;/code&gt;, podríamos aplicar un descuento sobre el total o sobre ciertos productos si se cumplen ciertas condiciones. &lt;/p&gt;

&lt;p&gt;Es importante no confundir un &lt;code&gt;agregado&lt;/code&gt; con una &lt;code&gt;colección&lt;/code&gt;, los agregados están dirigidos por conceptos clave de dominio, mientras que una colección siempre es genérica. &lt;/p&gt;

&lt;h3&gt;
  
  
  Repositorios
&lt;/h3&gt;

&lt;p&gt;Un &lt;code&gt;repositorio&lt;/code&gt; es un contrato en el cual establecemos aquellos métodos que necesitemos para obtener/persistir los datos de nuestra aplicación. &lt;/p&gt;

&lt;p&gt;El objetivo de crear un &lt;code&gt;repositorio&lt;/code&gt; dentro de la capa de dominio es mantener el control de todo lo que necesitamos independientemente de la fuente de datos que utilicemos, de esta manera si utilizamos MySQL, Oracle, MongoDB, Firebase o filesystem o incluso todas en conjunto, la aplicación seguirá funcionando, y si en algún futuro necesitamos reemplazar alguna fuente o motor de DB, esto no involucra cambios en la capa de dominio, ni siquiera en la capa de aplicación, solo se creará la nueva implementación en la capa de infraestructura siguiendo contrato y asunto resuelto.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fábricas (Factories)
&lt;/h3&gt;

&lt;p&gt;Las fábricas son clases que nos permiten crear instancias de nuestras entidades, objetos de valor o agregados basadas en diversos parámetros y condiciones, de este concepto en general existe mucha información, por lo que no haré tanto énfasis.&lt;/p&gt;

&lt;h3&gt;
  
  
  Evento de dominio
&lt;/h3&gt;

&lt;p&gt;Un &lt;code&gt;evento&lt;/code&gt; es una forma de comunicar que alguno de nuestros elementos de dominio ha tenido cierto tipo de interacción, los &lt;code&gt;eventos&lt;/code&gt; pueden ser de muchos tipos, desde la creación de una instancia, la persistencia de la misma, la modificación de alguna propiedad, etc. El objetivo de los &lt;code&gt;eventos&lt;/code&gt; es notificar a toda la aplicación con el fin de que se propaguen tantas acciones en consecuencia sean necesarias.&lt;/p&gt;

&lt;p&gt;Para sacar el máximo provecho de un &lt;code&gt;evento&lt;/code&gt;  se requiere de escuchadores, estos escuchadores son clases que tienden a realizar acciones adicionales en consecuencia a un evento, por ejemplo, cuando un usuario se crea, se suele enviar un correo de bienvenida; en un ambiente de &lt;code&gt;DDD&lt;/code&gt; se ejecutaría el &lt;code&gt;caso de uso&lt;/code&gt; de &lt;code&gt;CrearUsuario&lt;/code&gt; quien a su vez, lanzará el evento &lt;code&gt;UsuarioCreado&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Por otro lado, tendremos un escuchador &lt;code&gt;EnviarCorreoBienvenida&lt;/code&gt;, que se disparará en cuanto el evento &lt;code&gt;UsuarioCreado&lt;/code&gt; sea lanzado.&lt;/p&gt;

&lt;p&gt;La manera en la cual los escuchadores son notificados, es a través de un &lt;code&gt;bus&lt;/code&gt; que está conectado a toda nuestra aplicación, este bus se maneja dentro de la capa de aplicación y se hablará en futuros posts.&lt;/p&gt;

&lt;p&gt;Una característica muy importante de los &lt;code&gt;eventos&lt;/code&gt;, es que se pueden manejar de manera asíncrona (si así se desea), dejando que la interacción con el usuario se dé de manera muy rápido y creando colas (o &lt;code&gt;queues&lt;/code&gt;) que se encarguen de ejecutar dichos eventos en otra ocasión o en paralelo, aumentando los tiempos de respuesta.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Nota:&lt;/strong&gt; Los eventos, son clases DTO (data transfer objects) u objetos planos que suelen contener información importante del evento en curso, es importante que estas clases utilizan datos primitivos o escalares ya que de ésta manera pueden ser serializados para delegar su ejecución a algún comando con la base de datos o a una cola como &lt;code&gt;rabbitmq&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;El motivo por el cuál se suelen utilizar eventos en vez de escribir el código como programación lineal, es que en cualquier momento se pueden agregar más eventos y/o eliminarlos si llegase a cambiar el requerimiento, nuevamente, teniendo una afectación mínima en el código de la aplicación. &lt;/p&gt;

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

&lt;p&gt;A pesar de que la capa de dominio es meramente la representación conceptual del sistema y los contratos a seguir, es una de las capas más importantes, ya que define las bases para las siguientes capas. Es importante mencionar que todas aquellas clases que representen algún concepto, como &lt;code&gt;Excepciones personalizadas&lt;/code&gt; y &lt;code&gt;DTOs&lt;/code&gt; o &lt;code&gt;modelos&lt;/code&gt; que no tengan lógica implícita, pueden ser creadas dentro de la capa de dominio.&lt;/p&gt;

&lt;p&gt;Recuerda que si tienes alguna duda, sugerencia u observación sobre el contenido, puedes dejarme un comentario, o enviarme un correo a &lt;a href="mailto:juls0593@gmail.com"&gt;juls0593@gmail.com&lt;/a&gt;. Espero que el blog de hoy te haya sido de mucha ayuda.&lt;/p&gt;

&lt;p&gt;¡Hasta la próxima!&lt;/p&gt;

</description>
      <category>ddd</category>
      <category>architecture</category>
      <category>software</category>
    </item>
    <item>
      <title>DDD Objetos de valor como atributos de clase.</title>
      <dc:creator>Javier Ledezma</dc:creator>
      <pubDate>Mon, 07 Sep 2020 06:48:53 +0000</pubDate>
      <link>https://dev.to/javleds/ddd-objetos-de-valor-como-atributos-de-clase-1npa</link>
      <guid>https://dev.to/javleds/ddd-objetos-de-valor-como-atributos-de-clase-1npa</guid>
      <description>&lt;h1&gt;
  
  
  DDD Objetos de valor como atributos de clase.
&lt;/h1&gt;

&lt;p&gt;En un poco de contexto, Domain Driven Design (&lt;code&gt;DDD&lt;/code&gt;) es una forma de desarrollar software en capas, dando prioridad a la lo lógica del negocio (o dominio), unificando el lenguaje de expertise de negocio con el lenguaje técnico en algo conocido como &lt;code&gt;Ubiquitous Language&lt;/code&gt; y utilizando los principios &lt;code&gt;SOLID&lt;/code&gt; como el medio para lograr el producto final.&lt;/p&gt;

&lt;p&gt;Dentro de la metodología de DDD los términos relacionados con los objetos más básicos del sistema son las &lt;code&gt;entidades&lt;/code&gt; y los &lt;code&gt;objetos de valor&lt;/code&gt;.  Ambos conceptos hacen referencia a una clase representativa de nuestro proyecto, regularmente un sustantivo en un caso de uso, por ejemplo, un usuario, una orden de compra, un artículo de inventario, etc.&lt;/p&gt;

&lt;p&gt;La diferencia entre las &lt;code&gt;entidades&lt;/code&gt; y los &lt;code&gt;objetos de valor&lt;/code&gt; es que  estos últimos tienden a ser inmutables y mientras que una &lt;code&gt;entidad&lt;/code&gt; es un recurso que puede cambiar de estado, ser persistido y/o posteriormente eliminado.&lt;/p&gt;

&lt;p&gt;Mientras estudiaba DDD me encontré con una implementación en la que los atributos de las clases pasaban de ser un tipo primitivo (por ejemplo, string o int)  a un objeto de valor. &lt;/p&gt;

&lt;p&gt;Para ejemplificarlo en detalle, supongamos que tenemos una clase &lt;code&gt;Usuario&lt;/code&gt; que tiene los atributos &lt;code&gt;nombre&lt;/code&gt; y &lt;code&gt;edad&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;# User.php&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Usuario&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="cd"&gt;/** @var string */&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nv"&gt;$nombre&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="cd"&gt;/** @var int */&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nv"&gt;$edad&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;float&lt;/span&gt; &lt;span class="nv"&gt;$nombre&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="nv"&gt;$edad&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;nombre&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$nombre&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;edad&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$edad&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;
  
  
  Clase con objetos de valor como atributos
&lt;/h3&gt;

&lt;p&gt;Primero que nada, se tenía una clase para representar el tipo de dato &lt;code&gt;string&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;# StringValueObject.php&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StringValueObject&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="cd"&gt;/** @var string */&lt;/span&gt;
  &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$value&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;$value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;getValue&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;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;toString&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="nf"&gt;getValue&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;Posteriormente se tenía una clase para representar el atributo &lt;code&gt;name&lt;/code&gt; del objeto &lt;code&gt;Usuario&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;# NombreUsuario.php&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NombreUsuario&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;StringValueObject&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;$value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;parent&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lo mismo sucedía para la edad, inicialmente una clase para representar el tipo de dato &lt;code&gt;int&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;# IntValueObject.php&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;IntValueObject&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="cd"&gt;/** @var int */&lt;/span&gt;
  &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$value&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;int&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;getValue&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;toString&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="nb"&gt;strval&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;getValue&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;Después de una representación del tipo &lt;code&gt;int&lt;/code&gt;, continúa una clase para representar el atributo &lt;code&gt;edad&lt;/code&gt; del &lt;code&gt;Usuario&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;# EdadUsuario.php&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EdadUsuario&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;IntValueObject&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;int&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;parent&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finalmente se tenía la clase &lt;code&gt;Usuario&lt;/code&gt; queda de la siguiente manera:&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="c1"&gt;# Usuario.php&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Usuario&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="cd"&gt;/** @var NombreUsuario */&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nv"&gt;$nombre&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="cd"&gt;/** @var EdadUsuario */&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nv"&gt;$edad&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;NombreUsuario&lt;/span&gt; &lt;span class="nv"&gt;$nombre&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;EdadUsuario&lt;/span&gt; &lt;span class="nv"&gt;$edad&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;nombre&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$nombre&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;edad&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$edad&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;Mi primera reacción fue un notable &lt;code&gt;WFT?&lt;/code&gt; &lt;/p&gt;

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

&lt;p&gt;Después de detenerme a analizar el porqué de todo esto, entendí lo siguiente.&lt;/p&gt;

&lt;h3&gt;
  
  
  Delegar reglas de dominio a los objetos de valor
&lt;/h3&gt;

&lt;p&gt;Primero que nada, al crear una clase para cada atributo,  podemos delegar la validación a éstas clases, por ejemplo, en el caso del nombre, nunca aceptaríamos un string vacío, por lo que extenderíamos esa funcionalidad de la siguiente manera:&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="c1"&gt;# NombreUsuario.php&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NombreUsuario&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;StringValueObject&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;$value&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;asegurarNombreNoVacio&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;parent&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;asegurarNombreNoVacio&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;$value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;''&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nf"&gt;InvalidArgumentException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'El nombre no puede estar vacío.'&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;En dónde, si el valor no es vacío en automático arroja una excepción, lo mismo aplica para las validaciones de la clase &lt;code&gt;EdadUsuario&lt;/code&gt;, en dónde la edad no puede ser menor a 0, quedando:&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="c1"&gt;# EdadUsuario.php&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EdadUsuario&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;IntValueObject&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;int&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;parent&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;asegurarEdadMinimaDe0&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$value&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="err"&gt;\&lt;/span&gt;&lt;span class="nf"&gt;InvalidArgumentException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'La edad no puede ser menor a 0.'&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;
  
  
  Integridad en nuevas instancias
&lt;/h3&gt;

&lt;p&gt;Al delegar las validaciones a un &lt;code&gt;objeto de valor&lt;/code&gt;, cuando nosotros requiramos una instancia de &lt;code&gt;Usuario&lt;/code&gt;, no deberemos preocuparnos por la integridad, dado que todos los valores ingresados serían válidos o se detendrá la ejecución mostrando un error.&lt;/p&gt;

&lt;h3&gt;
  
  
  Código en un solo lugar
&lt;/h3&gt;

&lt;p&gt;A parte de esto, nos brinda la facilidad de crear atributos compartidos entre clases y "módulos" (conocidos como &lt;code&gt;sudominios&lt;/code&gt; en DDD), por ejemplo, si el &lt;code&gt;Usuario&lt;/code&gt; tuviera alguna relación con alguna otra &lt;code&gt;entidad&lt;/code&gt; como lo puede ser &lt;code&gt;Rol&lt;/code&gt;, los atributos en formato de &lt;code&gt;objeto de valor&lt;/code&gt; utilizarán la misma cla, y por ende no necesitaremos duplicar código en todos aquellos recursos compartidos.&lt;/p&gt;

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

&lt;p&gt;DDD tiene bastantes conceptos interesantes, muchos de ellos parecen hacer el código muy complejo, pero a largo plazo, proporciona una manera muy escalable y mantenible de hacer código, ¿qué te parece la implementación de objetos de valor como atributos de clase?&lt;/p&gt;

</description>
      <category>ddd</category>
      <category>php</category>
      <category>entities</category>
      <category>development</category>
    </item>
    <item>
      <title>Sistema de caché para optimizar web PHP</title>
      <dc:creator>Javier Ledezma</dc:creator>
      <pubDate>Tue, 01 Sep 2020 14:03:00 +0000</pubDate>
      <link>https://dev.to/javleds/sistema-de-cache-para-optimizar-web-1p92</link>
      <guid>https://dev.to/javleds/sistema-de-cache-para-optimizar-web-1p92</guid>
      <description>&lt;p&gt;Uno de los factores por los cuales deberíamos preocuparnos en nuestro día a día es tener un buen tiempo de respuesta en nuestras aplicaciones, este se puede ver degradado por varios factores, pero por fortuna para nosotros, existen muchos componentes y procedimientos que nos pueden ayudar a optimizarlo. En este blog te compartiré una serie de pasos relacionados con el caché, que pueden ayudarte a mejorar bastante los tiempos de respuesta.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Qué es Caché?
&lt;/h2&gt;

&lt;p&gt;El caché es un componente que nos permite almacenar en memoria datos previamente procesados, regularmente los sistemas de caché funcionan como un Hashmaps o diccionario clave-valor, en dónde la clave es una cadena de texto que funciona como identificador y el valor puede contener casi cualquier cosa.&lt;/p&gt;

&lt;p&gt;En general el concepto de caché se traduce a lo siguiente:&lt;/p&gt;

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

&lt;p&gt;En dónde:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;El cliente envía una petición al servidor.&lt;/li&gt;
&lt;li&gt;Si la petición ya se encuentra en caché, entonces regresa la respuesta guardada.&lt;/li&gt;
&lt;li&gt;Si la petición no se encuentra en caché, entonces es enviada a nuestra aplicación para que sea procesada.&lt;/li&gt;
&lt;li&gt;La aplicación procesa los datos y crea una respuesta.&lt;/li&gt;
&lt;li&gt;La aplicación almacena la respuesta en caché&lt;/li&gt;
&lt;li&gt;La respuesta es enviada al cliente.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;La memoria caché está limitada a valores computables, sin embargo, existen herramientas y técnicas que nos pueden ayudar a emular un sistema de caché para archivos físicos e inclusive para manejar bytecode, a continuación hablaremos de ellas.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Cuándo debería usar caché?
&lt;/h2&gt;

&lt;p&gt;La respuesta a esta pregunta es casi siempre, un sistema de caché mejorará de manera increíble los tiempos de respuesta de tu aplicación, inclusive si tienes contenido generado dinámicamente puedes ahorrar unos milisegundos o segundos dependiendo de la complejidad y configuración que utilices.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Cuándo no usar caché?
&lt;/h2&gt;

&lt;p&gt;El único enemigo real del caché son los sistemas real-time, en dónde se tienen actualizaciones por milisegundos, como lo puede ser un sistema de seguimiento de vehículos a través de GPS. De todos modos, se pueden utilizar ciertas técnicas de caché para agilizar parte del proceso completo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Invalidar caché
&lt;/h2&gt;

&lt;p&gt;Dado que el caché almacena datos/archivos procesados, es importante hacer limpieza de este cada cierto tiempo, haciendo que nuestra aplicación no se quede obsoleta en cuanto información y liberando memoria, el término "invalidar" hace referencia a eliminar los datos que se encuentran en caché.&lt;/p&gt;

&lt;p&gt;Existen 3 factores que provocan la invalidación de caché:&lt;/p&gt;

&lt;h3&gt;
  
  
  Invalidación por tiempos definidos
&lt;/h3&gt;

&lt;p&gt;Cuando almacenamos datos en caché, tenemos la posibilidad de elegir un tiempo que se mantendrá guardado, al pasar este tiempo, el caché será invalidado automáticamente.&lt;/p&gt;

&lt;p&gt;El tiempo que debemos mantener los datos en caché dependerá de la concurrencia de la aplicación o fragmento de código, si es un código que regresa siempre la misma salida, por ejemplo, una landing page, podemos establecer un periodo de 30 mins a 2 horas, sin embargo, si el código que queremos cachear está en constante cambio, podemos incluso hacer caché de 3 a 20 segundos, en dónde no parece de mucha ayuda, pero en escenarios concurridos puede mejorar muchísimo los tiempos de respuesta.&lt;/p&gt;

&lt;h3&gt;
  
  
  Invalidación por elementos poco utilizados
&lt;/h3&gt;

&lt;p&gt;Los elementos de caché que se utilizan en menor frecuencia también puede ser invalidados, en especial si la memoria está por agotarse, es muy probable que el propio sistema de caché invalide estos datos de manera automática.&lt;/p&gt;

&lt;h3&gt;
  
  
  Invalidación manual
&lt;/h3&gt;

&lt;p&gt;Al igual que tenemos el control sobre lo que se almacena en caché, podemos definir en qué momento invalidar, esto resulta útil cuando, por ejemplo, cambiamos el estado de la base de datos y necesitamos que el caché obtenga las nuevas entradas.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cacheando variables
&lt;/h2&gt;

&lt;p&gt;Si lo que deseamos es almacenar valores diversos, siendo éstos, variables de sesión, resultados de queries, etc, entonces, necesitaremos de algún motor para manejar el caché, las principales opciones que tenemos en PHP son &lt;a href="https://www.php.net/manual/en/book.memcached.php"&gt;memcached&lt;/a&gt; y &lt;a href="https://redis.io/"&gt;redis&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;En ambos casos tenemos una API bastante amplia que nos permitirán almacenar valores en caché en una estructura clave-valor, ambos cuentan con la opción de establecer el tiempo que permanecerán los datos en caché.&lt;/p&gt;

&lt;p&gt;Dado que ambas herramientas son muy buenas, tienden a tener muy buena integración con frameworks, por lo que muy probablemente ya tengas pre-configurado una librería en la herramienta que utilizas día a día.&lt;/p&gt;

&lt;p&gt;La instalación de un servidor para procesar caché no es complicada y brinda muchísimos beneficios.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cacheando bytecode
&lt;/h2&gt;

&lt;p&gt;A pesar de que &lt;code&gt;php&lt;/code&gt; es un lenguaje interpretado, es posible guardar fragmentos de código que siempre regresan la misma salida, haciendo que su ejecución sea mucho más rápida.&lt;/p&gt;

&lt;p&gt;Para lograr ésto, existe la extensión &lt;a href="https://www.php.net/manual/es/book.opcache.php"&gt;OPCache&lt;/a&gt;, disponible a partir de php 5.5, su trabajo es análizar todos esos fragmentos de código y de manera automática los irá gestionando.&lt;/p&gt;

&lt;p&gt;La configuración de la extensión se hace en el archivo &lt;code&gt;php.ini&lt;/code&gt; y se recomienda una configuración inicial como la siguiente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=4000
opcache.revalidate_freq=60
opcache.fast_shutdown=1
opcache.enable_cli=1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En dónde:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;memory_consumption&lt;/code&gt;:Indica el tamaño de la memoria en MB que puede ser utilizada por OPCache, el valor mínimo permitido es de 8MB.&lt;/li&gt;
&lt;li&gt; &lt;code&gt;interned_strings_buffer&lt;/code&gt;: Indica la cantidad de memoria en MB para almacenar cadenas de téxto.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;max_accelerated_files&lt;/code&gt;:  Indica el número máximo de scripts que pueden ser almacenados en OPCache.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;revalidate_freq&lt;/code&gt;: Tiempo en segundos que se mantendrán cacheados los scripts.&lt;/li&gt;
&lt;li&gt; &lt;code&gt;fast_shutdown&lt;/code&gt;: Permite deshabilitar el sistema de caché de manera rápida, delegando la limpieza de memoria al engine &lt;code&gt;Zend&lt;/code&gt;. En versiones de php 7.2 o mayor, esta configuración no es necesaria.&lt;/li&gt;
&lt;li&gt; &lt;code&gt;enable_cli&lt;/code&gt;: Habilita el caché para la versión CLI de php.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;El resto de configuraciones son opcionales, sin embargo, te comparto la &lt;a href="https://www.php.net/manual/en/opcache.configuration.php"&gt;documentación oficial&lt;/a&gt; de OPCache por si deseas saber más al respecto. &lt;/p&gt;

&lt;h2&gt;
  
  
  Cacheando archivos
&lt;/h2&gt;

&lt;p&gt;Una técnica muy utilizada especialmente en herramientas que pre-procesan archivos, es mantener una versión cacheada del archivo previamente procesado, siguiendo el mismo concepto inicial, si el archivo ya fue procesado, se regresa como respuesta, de lo contrario, se compila, se guarda físicamente en una carpeta y regresa el archivo.&lt;/p&gt;

&lt;p&gt;Una ventaja que tenemos es que podemos combinar partes físicas, con datos previamente guardados en memcached o redis teniendo una mezcla entre contenido estático y dinámico, pero cargado en memoria y con la posibilidad de manejar diferentes tiempos de vida.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cacheando respuestas
&lt;/h2&gt;

&lt;p&gt;La manera de cachear respuestas para ser servidas a mayor velocidad se da a través de cabeceras en la petición/respuesta, éstas pueden ser gestionadas con ayuda de tu servidor http como &lt;a href="https://tn123.org/mod_xsendfile/"&gt;apache&lt;/a&gt; o &lt;a href="https://www.nginx.com/resources/wiki/start/topics/examples/x-accel/"&gt;nginx&lt;/a&gt; y suelen trabajar muy bien con librerías como &lt;a href="http://docs.php-http.org/"&gt;cache-plugin&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Las cabeceras que suelen ser utilizadas para el control de caché son:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Expires&lt;/code&gt;: Tiempo de expiración del caché.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Cache-Control&lt;/code&gt;: Directivas que indican el comportamiento del caché.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ETag&lt;/code&gt;: Hash del contenido, se utiliza cuando se generan datos dinámicamente.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Last-Modified&lt;/code&gt;: Última fecha de modificación.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;If-None-Match&lt;/code&gt;: Cabecera que indica que el contenido no se encuentra en caché.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;If-Modified-Since&lt;/code&gt;: Cabecera que indica que el contenido que encuentra en caché ha sido actualizado.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusión:
&lt;/h2&gt;

&lt;p&gt;El caché es el mejor aliado que tenemos para optimizar los tiempos de respuesta de nuestra aplicaciones, es importante que dediquemos un tiempo a comprender y experimentar respecto al uso de caché. &lt;/p&gt;

&lt;p&gt;Si es que utilizas algún framework, te invito a que investigues que métodos de cahé implementa y lo compartas en los comentarios o si tienes alguna otra implementación que nos pueda ayudar, sería genial que la compartieras.&lt;/p&gt;

&lt;p&gt;Espero que esta guía te haya sido de ayuda.&lt;/p&gt;

&lt;p&gt;¡Hasta la próxima!&lt;/p&gt;

</description>
      <category>optimize</category>
      <category>webdev</category>
      <category>cache</category>
    </item>
    <item>
      <title>Una nota para quienes quieren ser parte del mundo de TI</title>
      <dc:creator>Javier Ledezma</dc:creator>
      <pubDate>Mon, 24 Aug 2020 03:42:11 +0000</pubDate>
      <link>https://dev.to/javleds/una-nota-para-quienes-quieren-ser-parte-del-mundo-de-ti-1o36</link>
      <guid>https://dev.to/javleds/una-nota-para-quienes-quieren-ser-parte-del-mundo-de-ti-1o36</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Nota:&lt;/strong&gt; TI es la abreviatura de "Tecnologías de información", abarca desde desarrollo de software, calidad en software, pruebas automatizadas y manuales, redes, soporte técnico de hardware y software, ciencia de datos, entre otros.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Hace poco empecé a tomar gusto por "asistir" a charlas gratuitas (videoconferencias) hechas por diversas comunidades de TI,  charlas en las que se habla de diversos temas, desde  lenguajes, nuevos frameworks hasta experiencias o tips que nos pueden servir día a día.&lt;/p&gt;

&lt;p&gt;Por la buena experiencia que había tenido, decidí compartir una plática con uno de mis colegas que está muy interesado en sumergirse en el campo de TI, pero,  a diferencia de mí, él terminó mucho más desanimado que interesado en ser parte de éste ámbito, y es que en la plática existieron muchos comentarios del tipo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Si no sabes inglés no la vas a hacer"&lt;/li&gt;
&lt;li&gt;"Las entrevistas de las empresas grandes no sirven"&lt;/li&gt;
&lt;li&gt;"No existen programadores full-stack"&lt;/li&gt;
&lt;li&gt;"Es imposible que aprendas en poco tiempo"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Me sentí frustrado al escuchar estas frases y le pedí una disculpa a mi colega, entiendo que todos esos comentarios tienen un motivo válido para existir, aunqué no esté totalmente de acuerdo con ello. Si al igual que mi colega, estás interesado en involucrarte en el mundo de TI, voy a compartirte mi opinión al respecto.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. No necesitas saber inglés para aprender.
&lt;/h2&gt;

&lt;p&gt;Si bien es muy cierto que las carreras relacionadas a TI van de la mano con el idioma inglés, no es necesario que sepas inglés para aprender, existen miles de recursos en línea que te pueden ayudar a dar tus primeros pasos en español, inclusive, me atrevo a decir que vas a aprender inglés sobre la marcha.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;No saber inglés vuelve el camino más difícil, pero no imposible. ¡Avientante!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  2. ¿Deberías preocuparte por las entrevistas de empresas grandes, cómo Amazon, Facebook, Google, etc?
&lt;/h2&gt;

&lt;p&gt;La respuesta a esta pregunta puede ser ambigua, así que te pondré dos variantes dependiendo de tus intereses:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Siéntete libre de leer solo la respuesta que coincida con tus intereses.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Si no estás interesado en trabajar en una empresa grande.
&lt;/h3&gt;

&lt;p&gt;No, no es necesario que te preocupes por ello, aprende a la tecnología que te guste, a tu ritmo, únete a comunidades que estén interesadas en las mismas tecnologías y participa lo más que puedas.&lt;/p&gt;

&lt;h3&gt;
  
  
  Si estás interesado en trabajar en una empresa grande.
&lt;/h3&gt;

&lt;p&gt;Si recién estás comenzando con tu carrera en TI y aspiras a llegar a una de éstas empresas, deberías preocuparte por conocer sus procesos de selección y las tecnologías que estás solicitando, pero siempre, priorizando tu proceso de aprendizaje. &lt;/p&gt;

&lt;p&gt;Entrar en una empresa grande regularmente toma mucho tiempo, pero no está mal que dediques tu esfuerzo para entrar a alguna empresa, incluso puedes utilizar su career-path para construir tu camino de aprendizaje y orientar tus esfuerzos a ser especialista en aquello que solicitan.&lt;/p&gt;

&lt;p&gt;Una vez que te sientas comodo, práctica haciendo código en un pizarrón o una hoja de papel, prepárate en términos de algoritmos y optimización de procesos.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Nota:&lt;/strong&gt; Si estás interesado en una empresa grande, entonces, el inglés si es un factor obligatorio, pero tampoco necesitas ser un gurú, con que entiendas lo que te piden y sepas explicar tus ideas, es suficiente.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  3. Los programadores full-stack si existen.
&lt;/h2&gt;

&lt;p&gt;Para aquellos que no estén muy familiarizados con el término full-stack, se refiere a la capacidad de las personas de hacer aplicaciones completas por sí solas, desde la parte del diseño de las ventanas y la interacción con los usuarios (front-end), hasta el diseño y construcción de todo lo que necesita tu aplicación para funcionar, en términos de base de datos, optimización de recursos, construcción de API's, la arquitectura de tu aplicación (backend) e incluso la manera en la que se lleva a producción (sysadmin).&lt;/p&gt;

&lt;p&gt;Si te das cuenta, ser un programador full-stack requiere mucho esfuerzo, pero es totalmente tangible, inclusive, puedes saber hacer todas esas actividades con diversas tecnologías, diversos lenguajes, etc. Estas son cosas que se aprenden con la práctica y que pueden tomarte tiempo, pero siempre es alcanzable.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Nota:&lt;/strong&gt; No es necesario que lo aprendas todo, al igual que existen personas que tienen conocimientos generales de muchos ámbitos, hay quienes son profesionistas en ciertas áras, por ejemplo, UX/UI, front-end, back-end, DevOps, bases de datos, etc.&lt;/p&gt;

&lt;p&gt;Elige la rama que más te guste y trabaja sobre ella, poco a poco irás mejorando tus conocimientos en general sobre todas las áreas.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  4. El tiempo de aprendizaje es relativo.
&lt;/h2&gt;

&lt;p&gt;Las personas aprendemos a diferentes ritmos, tomate tu tiempo para estudiar, practicar y preguntar sobre aquello que te guste y no te preocupes si tus colegas avanza más rápido que tu, al contrario, podrías acercarte a él para que te apoye con ciertas dudas y al igual, acércate con personas que vayan más lento que tu y ayudalas.&lt;/p&gt;

&lt;p&gt;Una de las ventajas de TI, es que las comunidades son asombrosas y siempre están dispuestas a ayudar.&lt;/p&gt;

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

&lt;p&gt;El mundo de TI es increíble en general, no hay límites para que puedes construir o lograr, te invito a que te animes y le des una oportunidad, inclusive si tu profesión o actividades están muy alejadas, TI es multidisciplinario y seguro podrás construir algo genial para lo que haces en tu día a día.&lt;/p&gt;

&lt;p&gt;Si te sientes confundido por no saber cómo iniciar, ponte en contacto conmigo, estoy dispuesto a ayudarte, envíame un correo a &lt;a href="mailto:juls0593@gmail.com"&gt;juls0593@gmail.com&lt;/a&gt; y hablaremos de ello. Igual si tienes algún comentario o duda siéntete libre de colocarlo en los comentarios.&lt;/p&gt;

&lt;p&gt;¡Hasta la próxima!&lt;/p&gt;

</description>
      <category>news</category>
      <category>tips</category>
      <category>opinion</category>
    </item>
    <item>
      <title>Consejos de CSS que me hubiera gustado saber cuando comencé a programar web</title>
      <dc:creator>Javier Ledezma</dc:creator>
      <pubDate>Mon, 17 Aug 2020 06:15:37 +0000</pubDate>
      <link>https://dev.to/javleds/consejos-de-css-que-me-hubiera-gustado-saber-cuando-comence-a-programar-web-1341</link>
      <guid>https://dev.to/javleds/consejos-de-css-que-me-hubiera-gustado-saber-cuando-comence-a-programar-web-1341</guid>
      <description>&lt;p&gt;A pesar de que &lt;code&gt;css&lt;/code&gt; no es aceptado como un lenguaje de programación por muchos desarrolladores, tengo que confesar que fue una de las herramientas que me causaron más dolor de cabeza a lo largo de mi carrera, y atribuyó esto a que, a diferencia de otros lenguajes de programación, si en CSS escribes mal una regla, simplemente no funciona, no hay &lt;br&gt;
errores que te digan qué estás haciendo mal o si tienes algún error de sintaxis, o peor aún, puede ser que tu regla esté funcionando pero no veas los resultados que esperabas en el navegador, sin explicaciones del por qué se comporta de esa manera.&lt;/p&gt;

&lt;p&gt;Para las personas que no están familiarizadas con CSS, css es un la herramienta que hace de las páginas web una obra de arte visual, nos permite modificar la forma en la que se muestran los elementos como el color o tamaño de la letra, el espacio entre párrafos, tamaño de imágenes e inclusive nos permite crear animaciones. La sintaxis de CSS es muy sencilla, se ve similar a lo siguiente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;selector&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;regla&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;valor&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;regla-multivalor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;valor1&lt;/span&gt; &lt;span class="n"&gt;valor2&lt;/span&gt; &lt;span class="n"&gt;valorN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;selector&lt;/span&gt;&lt;span class="nd"&gt;:pseudo-selector&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;regla&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;valor&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;selector&lt;/span&gt;&lt;span class="nd"&gt;::pseudo-elemento&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;regla&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;valor&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;En dónde:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;selector&lt;/code&gt;: Es el elemento que al que se le va a aplicar la regla de estilo, existen múltiples selectores, algunos de ellos son, id (#), clase (.), selector universal (*), o selectores de etiqueta (h1, p, div), entre otros.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;regla&lt;/code&gt;: Las reglas de CSS se utilizan para saber que "propiedad" del elemento se debe modificar, por ejemplo, la regla puede ser sobre el &lt;code&gt;color&lt;/code&gt; de la tipografía, sobre los &lt;code&gt;márgenes&lt;/code&gt;, o la almohadilla (&lt;code&gt;padding&lt;/code&gt;) de los elementos.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;valor&lt;/code&gt;: Es el valor que se le va a aplicar a cada "propiedad", por ejemplo, si modificamos la regla de &lt;code&gt;color&lt;/code&gt; de tipografía, el valor será un color hexadecimal.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;pseudo-selector&lt;/code&gt;: Considera éstos como modificadores acorde al estado del elemento, por ejemplo, si el usuario coloca el puntero del mouse sobre un elemento, éste cambia su estado a &lt;code&gt;hover&lt;/code&gt; y nosotros podemos definir qué reglas necesitamos para cuando el elemento se encuentre en ese estado.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;pseudo-elementos&lt;/code&gt;: Éstos son elementos que se crean automáticamente por los navegadores y envuelven el contenido del elemento HTML, agregando un bloque antes (&lt;code&gt;before&lt;/code&gt;) y un bloque después (&lt;code&gt;after&lt;/code&gt;), por lo general, estos elementos son invisibles porque el contenido que se crea está vacío por default, sin embargo, son muy útiles para  agregar efectos adicionales como etiquetas flotantes, o un clon de nuestro elemento con estilos diferentes.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Nota: Hay reglas que solo aplican a ciertos elementos, por ejemplo, la regla &lt;code&gt;list-style&lt;/code&gt; solo puede ser utilizada un elementos de tipo lista (&lt;code&gt;ol&lt;/code&gt; o &lt;code&gt;ul&lt;/code&gt;). &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ahora que estamos un poco en contexto, les compartiré algunos tips que me hubiera gustado saber cuando comencé a trabajar con CSS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Entendiendo la regla "Display"
&lt;/h2&gt;

&lt;p&gt;La propiedad &lt;code&gt;display&lt;/code&gt; es una de las propiedades más importantes, nos permite modificar la forma en la que los elementos se muestran en el DOM, permitiéndonos colocar elementos uno tras otro o simplemente modificando propiedades como la altura y el ancho de los elementos.&lt;/p&gt;

&lt;p&gt;Los valores más importantes son:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;block&lt;/code&gt;: Utiliza el 100% del largo del DOM y se expande a lo largo dependiendo del contenido, si no tiene contenido, su altura es 0. Estas propiedades se pueden cambiar con las reglas &lt;code&gt;width&lt;/code&gt; y &lt;code&gt;height&lt;/code&gt; y sus variantes &lt;code&gt;min&lt;/code&gt; y &lt;code&gt;max&lt;/code&gt; (min-height, max-height, min-width, max-width).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;inline-block&lt;/code&gt;: A diferencia de los &lt;code&gt;display: block&lt;/code&gt;, en vez de utilizar el 100% del DOM, este crece a los ancho acorde al contenido que tiene dentro. El comportamiento del tamaño vertical es similar.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;flex&lt;/code&gt;: Una de las reglas que me hubiera gustado conocer cuando incié con CSS, se encarga de "envolver" el contenido del elemento y te permite modificar de qué manera de muestra con ayuda de otras propiedades, te permite cambiar las dimensiones del contenedor, ajustar el contenido al centro, al inicio, al final o simplemente rellenar el contenedor con el contenido que tenga (en ambos sentidos, horizontal y vertical)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;grid&lt;/code&gt;: Otra regla que me hubiera gustado conocer en mis inicios, te permite colocar el contenido del elemento en formato de tabla, ajustando los hijos como si fueran un sistema de celdas y columnas.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Entendiendo la regla "Position"
&lt;/h2&gt;

&lt;p&gt;Uno de los conceptos que más me costó trabajo entender, fue la regla &lt;code&gt;position&lt;/code&gt;, hace referencia a la forma en la que un elemento se posiciona o se dibuja en el DOM. La mayoría del tiempo tendremos que modificar la posición de los elementos para lograr efectos increíbles, sin embargo, mal utilizada puede destruir por completo el layout de nuestra aplicación.&lt;/p&gt;

&lt;p&gt;Antes de comenzar tenemos que saber que todos los elementos tienen la posición  &lt;code&gt;static&lt;/code&gt; que permite el flujo normal de los elementos, a partir de allí viene una nota importante:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;la regla &lt;code&gt;position&lt;/code&gt; no solo afecta el flujo de posición del elemento actual, sino también de los elementos hijo. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Una vez que se modifica la posición de un elemento, se pueden utilizar las reglas: &lt;code&gt;left&lt;/code&gt;, &lt;code&gt;right&lt;/code&gt;, &lt;code&gt;top&lt;/code&gt; o &lt;code&gt;bottom&lt;/code&gt; para ayudar a colocar el elemento en donde sea que se requiera.&lt;/p&gt;

&lt;p&gt;Los valores que regularmente encontraremos son:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;static&lt;/code&gt;: Es el valor por defecto de todos los elementos. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;absolute&lt;/code&gt;: Permite romper el flujo normal y permite posicionar el elemento utilizando el contenedor padre (o DOM si es que no hay un contenedor padre) como referencia para colocar el elemento.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;relative&lt;/code&gt;: Permite colocar el elemento en relación directa con el elemento padre.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;fixed&lt;/code&gt;: Permite que el elemento se quede fijo en una posición, independientemente de que se se utilice scroll.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Prioridad de reglas CSS
&lt;/h2&gt;

&lt;p&gt;La prioridad de las reglas CSS puede salvarte de muchas horas de frustración, existe un juego de prioridades que siempre se van a seguir:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Regla: !important: La regla &lt;code&gt;!important&lt;/code&gt; se utiliza para forzar que un elemento tenga un estilo, aunque puede ser útil en algunas ocasiones, es importante evitar el uso de esta regla, ya que tenemos darle mantenimiento en ocasiones futuras puede ser muy difícil. Ejemplo:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;   &lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;green&lt;/span&gt; &lt;span class="cp"&gt;!important&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;ol&gt;
&lt;li&gt;Estilos in-line: Los estilos in-line son aquellos que colocan directamente en el elemento html, y tienen prioridad sobre todas las reglas, a excepción de un &lt;code&gt;!important&lt;/code&gt;. Ejemplo:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;   &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"color: red;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Mayor especificidad: La especificidad es un término que se refiere a que tan específico es el selector de una regla css, por ejemplo, teniendo el siguiente html:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;   &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"product-detail"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"product-properties"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
       &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"product-property"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Los ejemplos de especificidad:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;   &lt;span class="c"&gt;/* Especificidad de 3, mayor prioridad */&lt;/span&gt;
   &lt;span class="nc"&gt;.product-detail&lt;/span&gt; &lt;span class="nc"&gt;.product-properties&lt;/span&gt; &lt;span class="nc"&gt;.product-property&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

   &lt;span class="c"&gt;/* Especificidad de 2 */&lt;/span&gt;
   &lt;span class="nc"&gt;.product-properties&lt;/span&gt; &lt;span class="nc"&gt;.product-property&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

   &lt;span class="c"&gt;/* Especificidad de 1 */&lt;/span&gt;
   &lt;span class="nc"&gt;.product-property&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Última línea: Las reglas se suelen aplicar de arriba hacia abajo, es decir que la regla que se encuentre más abajo, sobreescribirá las que se encuentren antes, a excepción de que caiga en los puntos anteriormente mencionados. Ejemplo:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;   &lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;

   &lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;

   &lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="c"&gt;/* Este valor sobreescribe el que se definió en la primera regla. */&lt;/span&gt;
     &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;green&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;
  
  
  Preprocesadores
&lt;/h2&gt;

&lt;p&gt;Los preprocesadores son herramientas que nos permiten escribir reglas css de manera muy sencilla, tienen ciertas funciones que permiten crear css reutilizable y mantenible, un ejemplo de preprocesador de css (y mi favorito) es &lt;code&gt;sass/scss&lt;/code&gt;, te permite escribir css con la misma sintaxis, pero con muchas facilidades, como anidar selectores, también te permiten crear variables, funciones con estilos repetitivos, etc.&lt;/p&gt;

&lt;p&gt;Las reglas creadas con preprocesadores tienen que ser convertidas a css antes de que puedan ser utilizadas, pero los mismos preprocesadores te dan estas facilidades.&lt;/p&gt;

&lt;p&gt;Para hacer una comparación de &lt;code&gt;scss&lt;/code&gt; vs &lt;code&gt;css&lt;/code&gt; utilizaré el siguiente ejemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"product"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"product-properties"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Suponiendo que quisiéramos crear estilos para cada uno de los elementos del ejemplo, en css tendríamos algo similar a:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.product&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c"&gt;/* reglas de producto */&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#222222&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="err"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.product&lt;/span&gt; &lt;span class="nc"&gt;.product-properties&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c"&gt;/* reglas de las propiedades de producto */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.product&lt;/span&gt; &lt;span class="nc"&gt;.product-properties&lt;/span&gt; &lt;span class="nt"&gt;li&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c"&gt;/* reglas de cada elemento de la lista de propiedades de producto */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.product&lt;/span&gt; &lt;span class="nc"&gt;.product-properties&lt;/span&gt; &lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c"&gt;/* reglas de cada elemento de la lista de propiedades de producto hover */&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#222222&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#ff22ff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.product&lt;/span&gt; &lt;span class="nc"&gt;.product-properties&lt;/span&gt; &lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="nc"&gt;.active&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c"&gt;/* reglas de cada elemento de la lista de propiedades de producto activo */&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#222222&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#ff22ff&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;Utilizando sass, se vería similar a esto:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="nv"&gt;$primary-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mh"&gt;#222222&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;$text-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mh"&gt;#ff22ff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nc"&gt;.product&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="cm"&gt;/* reglas de producto */&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$primary-color&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nt"&gt;-properties&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cm"&gt;/* reglas de las propiedades de producto */&lt;/span&gt;

    &lt;span class="nt"&gt;li&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="cm"&gt;/* reglas de cada elemento de la lista de propiedades de producto */&lt;/span&gt;

      &lt;span class="k"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
      &lt;span class="k"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nc"&gt;.active&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$primary-color&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$text-color&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;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En donde, al ser convertido a css, obtendremos el mismo resultado, pero a nivel sitáxis evitamos repetir selectores y a demás utilizamos variables para definir ciertos atributos que pueden cambiar con el tiempo y sin tener que modificar mucho nuestros archivos css.&lt;/p&gt;

&lt;h2&gt;
  
  
  Arquitectura de estilos 7-1
&lt;/h2&gt;

&lt;p&gt;Al igual que el backend y las tecnologías de fontend, los estilos también pueden ser manejados por una arquitectura, permitiendo que proyectos medianos y grandes sean mantenibles a lo largo del tiempo, estas arquitecturas se adaptan perfectamente con los preprocesadores y aunque puede haber variantes, me gustaría hablar un poco de la arquitectura &lt;code&gt;7-1&lt;/code&gt; que me ha funcionado perfectamente.&lt;/p&gt;

&lt;p&gt;En resumen, la arquitectura &lt;code&gt;7-1&lt;/code&gt; es un juego de 7 directorios con responsabilidades definidas y un archivo que se encarga de concentrar todos los estilos de estos directorios, este último será incluido en nuestro archivo HTML o bien será exportado como punto de salida para nuestras aplicaciones.&lt;/p&gt;

&lt;p&gt;Consta de construir el siguiente árbol de archivos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sass
|
|– abstracts/
|   |– _variables.scss    # Sass Variables
|   |– _functions.scss    # Sass Functions
|   |– _mixins.scss       # Sass Mixins
|   |– _placeholders.scss # Sass Placeholders
|
|– base/
|   |– _reset.scss        # Reset/normalize
|   |– _typography.scss   # Typography rules
|   …                     # Etc.
|
|– components/
|   |– _buttons.scss      # Buttons
|   |– _carousel.scss     # Carousel
|   |– _cover.scss        # Cover
|   |– _dropdown.scss     # Dropdown
|   …                     # Etc.
|
|– layout/
|   |– _navigation.scss   # Navigation
|   |– _grid.scss         # Grid system
|   |– _header.scss       # Header
|   |– _footer.scss       # Footer
|   |– _sidebar.scss      # Sidebar
|   |– _forms.scss        # Forms
|   …                     # Etc.
|
|– pages/
|   |– _home.scss         # Home specific styles
|   |– _contact.scss      # Contact specific styles
|   …                     # Etc.
|
|– themes/
|   |– _theme.scss        # Default theme
|   |– _admin.scss        # Admin theme
|   …                     # Etc.
|
|– vendors/
|   |– _bootstrap.scss    # Bootstrap
|   |– _jquery-ui.scss    # jQuery UI
|   …                     # Etc.
|
`– main.scss              # Main Sass file
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Si bien, la estructura se explica por sí sola, me gustaría recapitular un poco sobre las responsabilidades de cada directorio:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;abstract&lt;/code&gt;: Contiene archivos cuya funcionalidad es mantener los elementos reutilizables en términos de estilos, también suele contener clases de utilerías.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;base&lt;/code&gt;: Contiene los estilos necesarios para dejar nuestra aplicación normalizada ante todos los navegadores,  hace mucho énfasis en los márgenes, almohadillas y tipografía.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;components&lt;/code&gt;: En esta carpeta crearemos cuantos archivos necesitemos, cada archivo contendrá los estilos de un fragmento de código que pudiese ser reutilizado en diversas partes de la aplicación, por ejemplo,  una tarjeta, los botones de la aplicación, los mensajes de feedback, entre otros.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;layout&lt;/code&gt;: En esta carpeta colocaremos aquellos estilos de los elementos  centrados en la navegación de la página, como lo son sidebars, header y footer.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;pages&lt;/code&gt;: En esta carpeta se crean los estilos que deben ser aplicados a una página en concreto, por ejemplo, estilos que lleva la sección de landing page y que no tiene la sección de productos, y viceversa.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;themes&lt;/code&gt;: En caso de que quieras brindar la posibilidad de cambiar la interfaz de usuario dependiendo del rol o simplemente personalizar los colores, el fondo u otros elementos, puedes crear estos estilos en la carpeta de temas.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;vendors&lt;/code&gt;: En caso de que tu aplicación utilice librerías externas como &lt;code&gt;bootstrap&lt;/code&gt;, &lt;code&gt;materializecss&lt;/code&gt; o &lt;code&gt;element-ui&lt;/code&gt; puedes importar los estilos de esas librerías en esta carpeta.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;main.scss&lt;/code&gt;: También llamado &lt;code&gt;app.scss&lt;/code&gt;, el archivo no contiene ninguna regla css, su función es importar los archivos que se vayan creando en las subcarpetas mencionadas anteriormente.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Media Queries
&lt;/h2&gt;

&lt;p&gt;Una de las ventajas del desarrollo web, es que puede ser transportado fácilmente a dispositivos móviles con solo modificar estilos, esto permite adaptar el contenido del DOM a cualquier tamaño. Los &lt;code&gt;media-queries&lt;/code&gt; son reglas css que nos permiten modificar los estilos cuando el viewport (el tamaño de la pantalla en la que se visualiza el DOM) cumpla con ciertos requisitos, por ejemplo, si el viewport es mayor a 300px de ancho, o si el DOM está siendo visualizado en alguna tablet.&lt;/p&gt;

&lt;p&gt;Los media-query tienden a verse similar a esto:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;600px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.selector&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&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;En dónde la función &lt;code&gt;@media&lt;/code&gt; puede contener las medidas sobre las cuales aplicará las reglas que se encuentren en el cuerpo de la función.&lt;/p&gt;

&lt;p&gt;Es un poco complicado hacer un estudio de todas las posibles variantes de tamaño de dispositivo, pero te puedo recomendar ir a la documentación de librerías o frameworks de fronted, como lo son bootstrap o semantic-ui, ellos tienen una tabla de medias que puedes utilizar de referencia para adaptar tus estilos a computadoras con definición muy grande, regular, tablets y celulares.&lt;/p&gt;

&lt;h2&gt;
  
  
  Animaciones
&lt;/h2&gt;

&lt;p&gt;Desde el lanzamiento de CSS3, hacer animaciones es muy sencillo, basta con conocer la propiedad &lt;code&gt;transition&lt;/code&gt; o bien &lt;code&gt;animation&lt;/code&gt;  y la función &lt;code&gt;@keyframes&lt;/code&gt;,  la primera es una forma sencilla en la que CSS esuchará los cambios en las reglas de CSS, haciendo una animación pequeña entre el valor de inicio y valor final del cambio.&lt;/p&gt;

&lt;p&gt;Un ejemplo sencillo es:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;block&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;150px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;all&lt;/span&gt; &lt;span class="m"&gt;.3s&lt;/span&gt; &lt;span class="n"&gt;ease-out&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.card&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;200px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;250px&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;En dónde, al posicionar el puntero del mouse sobre los elementos con la clase card, estos aumentaran su tamaño de 100x150 a 200x250, y css aplicará una transición de 300 milisegundos entre estos cambios de tamaño. El atributo &lt;code&gt;ease-out&lt;/code&gt; es un alias para el comportamiento de la animación (curva), nos dice que inicie rápido pero que al final la animación sea lenta, existen muchas posibles curvas de comportamiento de animaciones, te invito a darles una revisada &lt;a href="https://easings.net/"&gt;aquí&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;La segunda forma de hacer animaciones es a través de la función &lt;code&gt;@keyframes&lt;/code&gt; y la regla &lt;code&gt;animation&lt;/code&gt;. Un &lt;code&gt;@keyframes&lt;/code&gt; define una serie de pasos que se tienen que cumplir, esta se define utilizando un rango de 0% a 100%, en donde 0% es el inicio de la animación y 100% es el final. Se pueden crear tantos pasos sean necesarios, los &lt;code&gt;@keyframes&lt;/code&gt; se definen de la siguiente manera:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;nombre-del-keyframe&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c"&gt;/* css que se va a aplicar */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="err"&gt;30&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c"&gt;/* css que se va a aplicar */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="err"&gt;68&lt;/span&gt;&lt;span class="o"&gt;%,&lt;/span&gt; &lt;span class="err"&gt;72&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c"&gt;/* css que se va a aplicar */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="err"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c"&gt;/* css que se va a aplicar */&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;Finalmente, podemos hacer uso de los keyframes con la propiedad &lt;code&gt;animation&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;nombre-del-keyframe&lt;/span&gt; &lt;span class="m"&gt;2s&lt;/span&gt; &lt;span class="n"&gt;ease-out&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;En dónde especificamos que utilizará el &lt;code&gt;@keyframe&lt;/code&gt; que se acaba de crear, la duración será de 2 segundos y la curva de animación será con inicio rápido y término lento (&lt;code&gt;ease-out&lt;/code&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusión:
&lt;/h2&gt;

&lt;p&gt;CSS es muy divertido una vez lo entiendes, con él puedes crear páginas fabulosas, en ésta guía te compartí los tips que me hubiera gustado saber cuando inicié a utilizar &lt;code&gt;css&lt;/code&gt; con el fin de que tu curva de aprendizaje sea muy suave, que comiences a conocer las herramientas que se utilizan hoy en día (preprocesadores) y también un tip rápido para comiences a animar tus proyectos, esos pequeños detalles le un plus enorme a tu aplicación y una experiencias muy agradable a los usuarios. &lt;/p&gt;

&lt;p&gt;Te invito a que me compartas tus experiencias con CSS, y si consideras que se puede mejorar el contenido, tu comentario es muy valioso para mi.&lt;/p&gt;

&lt;p&gt;¡Hasta la próxima!.&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>css</category>
      <category>scss</category>
      <category>tips</category>
    </item>
    <item>
      <title>Controladores livianos y buenas prácticas.</title>
      <dc:creator>Javier Ledezma</dc:creator>
      <pubDate>Mon, 03 Aug 2020 15:12:51 +0000</pubDate>
      <link>https://dev.to/javleds/controladores-livianos-y-buenas-practicas-4d5i</link>
      <guid>https://dev.to/javleds/controladores-livianos-y-buenas-practicas-4d5i</guid>
      <description>&lt;h1&gt;
  
  
  Controladores livianos y buenas prácticas.
&lt;/h1&gt;

&lt;p&gt;Gracias a los frameworks modernos de desarrollo web, crear aplicaciones se vuelve una tarea muy sencilla y basta con entender un poco el funcionamiento del protocolo HTTP y un poco de MVC (o variantes) para darnos cuenta de que todo se reduce a:&lt;/p&gt;

&lt;p&gt;Request -&amp;gt; Router -&amp;gt; Controller -&amp;gt; Response&lt;/p&gt;

&lt;p&gt;En dónde el cliente envía una &lt;code&gt;petición&lt;/code&gt; al servidor, esta es procesada por un sistema de rutas (&lt;code&gt;router&lt;/code&gt;), quien lo envía al &lt;code&gt;controlador&lt;/code&gt; correspondiente y el &lt;code&gt;controlador&lt;/code&gt; se encarga de ejecutar una o varias acciones y construir una respuesta en el formato necesario (por ejemplo un archivo html o una respuesta xml o json) y la envía como respuesta al cliente.&lt;/p&gt;

&lt;p&gt;Y siguiendo ese patrón nosotros podemos construir todo tipo de aplicaciones, sin embargo, el mal manejo de controladores puede resultar en una aplicación imposible de mantener y por ende, un software que estará destinado al fracaso.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"El mayor costo en el desarrollo de software no es para crearlo, sino para mantenerlo. "&lt;/p&gt;

&lt;p&gt;Una frase del libro &lt;code&gt;Clean Code&lt;/code&gt; de &lt;code&gt;Robert C. Martin&lt;/code&gt;, el cual hace énfasis en las buenas prácticas de la programación orientada a objetos.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Una de las mejores maneras de crear código mantenible es dejar que los &lt;code&gt;controladores&lt;/code&gt; de nuestra aplicación solo se encarguen únicamente de acciones CRUD y utilizar otros patrones de diseño o técnicas para delegar actividades secundarias.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;CRUD es un acrónimo de: Create, Read, Update &amp;amp; Delete (Crear, Leer, Actualizar y eliminar).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Un controlador CRUD debería verse similar a:&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;Controller&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// lista un recurso&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;index&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="c1"&gt;// muestra formulario de creación (opcional en API's)&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;create&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="c1"&gt;// crea un nuevo registro en BD&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;store&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;   

  &lt;span class="c1"&gt;// muestra detalles de un registro&lt;/span&gt;
  &lt;span class="kt"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;show&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;   

  &lt;span class="c1"&gt;// muestra formulario de edición (opcional en API's)&lt;/span&gt;
  &lt;span class="kt"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;edit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="c1"&gt;// actualiza un registro en BD&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;update&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="c1"&gt;// elimina un registro en DB&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;delete&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;blockquote&gt;
&lt;p&gt;Puede llegar a tener variantes dependiendo del lenguaje y el framework utilizado.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Existen un par de escenarios en los que te puede causar ruido el uso de los &lt;code&gt;controladores CRUD&lt;/code&gt;, estos son:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Cuando necesitamos manejar recursos relacionados.&lt;/li&gt;
&lt;li&gt;Cuando nuestro controlador contiene un sólo método.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  1. Manejado recursos relacionados
&lt;/h3&gt;

&lt;p&gt;Si tu controlador requiere trabajar con recursos relacionados, por ejemplo, si tienes un blog, en dónde un &lt;code&gt;artículo&lt;/code&gt; puede tener &lt;code&gt;comentarios&lt;/code&gt; y para administrar los &lt;code&gt;comentarios&lt;/code&gt; necesitas una instancia de &lt;code&gt;artículo&lt;/code&gt;, en vez de agregar métodos adicionales al &lt;code&gt;controlador&lt;/code&gt; de &lt;code&gt;artículos&lt;/code&gt;, crea un controlador que se encargue de manejar esas relaciones, ejemplo:&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;ArticleCommentsController&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// lista los comentarios de un artículo&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;index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$idArticle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="c1"&gt;// crea un nuevo comentario para un artículo&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;store&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$idArticle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   

  &lt;span class="c1"&gt;// muestra detalles de un comentario relacionado a un artículo&lt;/span&gt;
  &lt;span class="kt"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;show&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$idArticle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   

  &lt;span class="c1"&gt;// actualiza un comentario relacionado al artículo&lt;/span&gt;
  &lt;span class="kt"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$idArticle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="c1"&gt;// elimina un comentario relacionado al artículo&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;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$idArticle&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;En dónde cada método recibe el id del recurso principal (en este caso &lt;code&gt;articulo&lt;/code&gt;) y pero las acciones afectan al recurso &lt;code&gt;comentario&lt;/code&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  2. Manejando controladores de un solo método
&lt;/h3&gt;

&lt;p&gt;Cuando tu controlador tiene una función distinta a la de acciones CRUD, por ejemplo, si tenemos una página de inicio para una landing page o un dashboard si estámos trabajando con usuarios administradores. En éstos casos se puede utilizar el método &lt;code&gt;index&lt;/code&gt; como la única fuente o si tu framework te lo permite, también puedes utilizar controladores invocables, esto quiere decir que se sobreescribe el método &lt;code&gt;invoke&lt;/code&gt; de la clase, ejemplo:&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;HomeController&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;__invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="cm"&gt;/* parameters */&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Lógica aquí&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;De ésta manera nos aseguramos que nuestro controlador solo ejecutará una acción.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quitando carga a los controladores
&lt;/h2&gt;

&lt;p&gt;Todo método o funcionalidad fuera de lo métodos CRUD puede ser extraído a su propia clase, en seguida te comparto algunas herramientas que puedes utilizar para lograr mantener tu &lt;code&gt;controlador&lt;/code&gt; libre de código adicional:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Es muy probable que el framework de tu preferencia no cuente algunos de los elementos citados.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Middleware
&lt;/h3&gt;

&lt;p&gt;Un middleware es una capa de software que puede interceptar la petición del cliente o la respuesta generada por nuestra aplicación y regularmente se utilizan para hacer revisar de los datos de &lt;code&gt;sesión&lt;/code&gt;, &lt;code&gt;encabezados&lt;/code&gt; del navegador, validar datos de la &lt;code&gt;petición&lt;/code&gt; del cliente y/o agregar &lt;code&gt;encabezados&lt;/code&gt; adicionales a las respuestas.&lt;/p&gt;

&lt;h3&gt;
  
  
  Eventos
&lt;/h3&gt;

&lt;p&gt;Un evento es una forma de decirle a nuestra aplicación que algo ha ocurrido, dando paso a que la aplicación pueda actuar en consecuencia con una o más acciones (estas acciones también son conocidas como &lt;code&gt;escuchadores&lt;/code&gt; o &lt;code&gt;suscriptores&lt;/code&gt;). &lt;/p&gt;

&lt;p&gt;Uno de los ejemplos más concurridos es disparar un evento cuando un usuario se registra en nuestra aplicación, dejando que el controlador se encargue de persistir al usuario y delegando la lógica de enviar un correo de bienvenida a un &lt;code&gt;escuchador&lt;/code&gt; o a algún &lt;code&gt;suscriptor&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Una ventaja de utilizar eventos, es que se pueden ejecutar muchas acciones en consecuencia, cada una con su propia lógica.&lt;/p&gt;

&lt;h3&gt;
  
  
  Peticiones personalizadas
&lt;/h3&gt;

&lt;p&gt;Gran parte de la lógica de los controladores se basa en validar que los datos ingresados por el usuario sean correctos y que estos no vayan a provocar inconsistencias en nuestra base de datos.&lt;/p&gt;

&lt;p&gt;Por fortuna, muchos frameworks cuentan con peticiones personalizadas, estas son clases que “decoran” una petición HTTP común y agregan esa capa de validación necesaria.&lt;/p&gt;

&lt;p&gt;En caso de que el framework que utilices no cuente con esta opción, puedes utilizar middlewares para este fin.&lt;/p&gt;

&lt;h3&gt;
  
  
  Servicios
&lt;/h3&gt;

&lt;p&gt;Un servicio es una clase encarga de hacer algo.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;No muy claro, ¿cierto?. Esto se debe a la versatilidad que puede tener un servicio.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Un servicio es un componente que cumple con una función relacionada a regas de negocio de la aplicación. regularmente son fragmentos pequeños de código de responsabilidad única.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Estas clases  suelen delegarse al &lt;code&gt;contenedor&lt;/code&gt; de la aplicación utilizando &lt;code&gt;inyección de dependencias&lt;/code&gt; para instanciarse de manera automática y brindando la posibilidad de que de manera interna puedan utilizar otros servicios en caso de que sea lógica muy compleja.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Los servicios suelen utilizarse cuando un controlador requiere mucha lógica en sus métodos CRUD y/o cuando tenemos fragmentos de código que pueden ser reutilizados en nuestra aplicación.&lt;/p&gt;

&lt;h3&gt;
  
  
  Repositorios
&lt;/h3&gt;

&lt;p&gt;Un repositorio es una fuente de datos y se traduce a clases encargadas de brindar información de diversas fuentes, por ejemplo, traer un arreglo de una base de datos local o proporcionar datos de una API externa, entre ortro.&lt;/p&gt;

&lt;p&gt;Una buena práctica es definir contratos o interfaces que definan los métodos que necesitemos en nuestra aplicación y hacer tantas implementaciones como se requieran. De esta manera, si en algún futuro se llega a cambiar la fuente de datos, entonces, la aplicación no tendrá que modificar todo el código, solo las implementaciones de los contratos.&lt;/p&gt;

&lt;p&gt;Ejemplo:&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="c1"&gt;# src/Repositories/UserRepository.php&lt;/span&gt;

&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;UserRepository&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;findById&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;User&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;all&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&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;# src/Repositories/Implementations/DbUserRepository.php&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DbUserRepository&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="cm"&gt;/* @var DBAL */&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nv"&gt;$connection&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

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

  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;findById&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;User&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;all&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&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;h3&gt;
  
  
  Utilerías
&lt;/h3&gt;

&lt;p&gt;En ocasiones tenemos código que no está relacionado a las reglas de negocio, pero que puede utilizado en muchas partes de la aplicación, por ejemplo, si necesitamos dar formato a un &lt;code&gt;decimal&lt;/code&gt; para mostrarlo en formato de moneda, o si necesitamos hacer conversiones de fechas, en éstos casos se puede crear una clase de utilerías que contenga estas funciones.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Es muy importante que &lt;strong&gt;no&lt;/strong&gt; intentes crear "navajas suizas" en las clases de utilerías, para evitarlo, intenta agrupar las funciones por su tipo, por ejemplo, crea una utilería para manejar strings (&lt;code&gt;class StringUtils&lt;/code&gt;), y otra para manejar fechas (&lt;code&gt;class DateUtils&lt;/code&gt;). &lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;Utilizar estas técnicas o patrones nos van a ayudar a tener controladores y componentes muy fáciles de mantener a largo plazo. Y aunque en éste post solamente se mencionan de manera muy superficial, es importante que conozcas los conceptos para que puedas comenzar a implementarlos en tus proyectos.&lt;/p&gt;

&lt;p&gt;Te invito a que comiences por utilizar lo aprendido en éste post en tus proyectos y si tienes algún consejo adicional o comentario, siempre será bienvenido en los comentarios, ¡gracias por tu tiempo!&lt;/p&gt;

&lt;p&gt;¡Hasta la próxima!&lt;/p&gt;

</description>
      <category>buenaspracticas</category>
      <category>solid</category>
      <category>web</category>
      <category>tips</category>
    </item>
    <item>
      <title>Estilo de código en proyectos PHP</title>
      <dc:creator>Javier Ledezma</dc:creator>
      <pubDate>Mon, 27 Jul 2020 05:13:23 +0000</pubDate>
      <link>https://dev.to/javleds/estilo-de-codigo-en-proyectos-php-2kch</link>
      <guid>https://dev.to/javleds/estilo-de-codigo-en-proyectos-php-2kch</guid>
      <description>&lt;p&gt;Una de las mejores maneras de  mantener un código legible a lo largo del tiempo es definir estándares de estilo, con esto me refiero a; por ejemplo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Definir que las clases se deben declarar utilizando StudlyCaps.&lt;/li&gt;
&lt;li&gt;Se deben utilizar 4 espacios para identar el código.&lt;/li&gt;
&lt;li&gt;No se deben dejar líneas en blanco después de abrir una llave.&lt;/li&gt;
&lt;li&gt;entre otros... &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Y aunque parece trivial el hecho de seguir estas convenciones, en ocasiones podemos cometer algún error, ya sea por la velocidad del desarrollo, desconocimiento de los estándares o simplemente por pereza. Por fortuna para nosotros existen herramientas automatizadas que nos permiten "forzar" a que el código siga nuestras convenciones iniciales, tal es el caso de &lt;a href="https://github.com/FriendsOfPHP/PHP-CS-Fixer"&gt;PHP Code Sniffer&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Uso
&lt;/h2&gt;

&lt;p&gt;PHP sniffer es una librería que se encarga de la validación de sintaxis del código (también conocido como estilo de código), la librería está configurada para seguir con los estándares oficiales definidos en &lt;a href="https://www.php-fig.org/psr/"&gt;https://www.php-fig.org/psr/&lt;/a&gt; (apartados &lt;code&gt;PSR-1&lt;/code&gt; y &lt;code&gt;PSR-12&lt;/code&gt;), sin embargo, tiene flexibilidad para que puedas modificar esas reglas y configurarlas de tal manera que se adapte a los estándares de tu proyecto.&lt;/p&gt;

&lt;p&gt;Una ventaja de utilizar &lt;code&gt;code sniffer&lt;/code&gt; es que a demás de validar la sintaxis, cuenta con una utilidad que puede corregir algunos de los errores detectados por la misma herramienta. &lt;/p&gt;

&lt;h2&gt;
  
  
  Instalación y configuración
&lt;/h2&gt;

&lt;p&gt;Si estás utilizando composer, bastará con ejecutar la siguiente instrucción en tu terminal, en la raíz de tu proyecto:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer require &lt;span class="nt"&gt;--dev&lt;/span&gt; friendsofphp/php-cs-fixer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Nota:&lt;/strong&gt; En caso de no utilizar composer, code sniffer cuenta con ejecutable &lt;strong&gt;.phar&lt;/strong&gt; además de otros métodos de instalación, te recomiendo visitar el &lt;a href="https://github.com/FriendsOfPHP/PHP-CS-Fixer"&gt;repositorio oficial&lt;/a&gt; que mantendrá actualizada la guía de instalación para cada caso.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Se utiliza la bandera &lt;code&gt;--dev&lt;/code&gt; ya que la validación del estilo de código solamente se realiza durante la etapa de desarrollo.&lt;/p&gt;

&lt;p&gt;Una vez instalada la libreŕia, se puede utilizar ejecutando la siguiente línea:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php ./vendor/bin/ {SRC_FOLDER}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En dónde:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;SRC_FOLDER&lt;/code&gt;: Es el directorio que queremos que se analizado por &lt;code&gt;phpcs&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Al igual que las librerías de complemento del proyecto, se puede crear un archivo para configurar las reglas necesarias, en el caso de &lt;code&gt;phpcs&lt;/code&gt; la configuración se realiza en php aunque el archivo de configuración no lleve como tal la extensión php. &lt;/p&gt;

&lt;p&gt;Para poder configurarlo podemos crear en el directorio raíz un archivo llamado &lt;code&gt;.php_cs&lt;/code&gt; o &lt;code&gt;.php_cs.dist&lt;/code&gt;, con algo similar a lo siguiente:&lt;br&gt;
&lt;/p&gt;

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

&lt;span class="nv"&gt;$finder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;PhpCsFixer\Finder&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;in&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'DIRECTORIO_DEL_PROYECTO'&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;PhpCsFixer\Config&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;setRules&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
        &lt;span class="s1"&gt;'array_syntax'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'syntax'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'short'&lt;/span&gt;&lt;span class="p"&gt;],&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;setFinder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$finder&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En dónde:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;$finder&lt;/code&gt;: Es un objeto en dónde podemos definir los archivoso directorios que queremos que sean analizados por &lt;code&gt;phpcs&lt;/code&gt;, se crea utilizando el objeto &lt;code&gt;PhpCsFixer\Finder&lt;/code&gt; y en él puedes encadenar los métodos &lt;code&gt;in(DIRECTORY)&lt;/code&gt; para establecer el directorio del proyecto, y el método &lt;code&gt;exclude(DIRECTORY)&lt;/code&gt; si deseas excluir algunos archivos.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Nota: DIRECTORY, es un string, y por lo regular, el método puede tener como parámetro la constante mágica &lt;code&gt;__DIR__&lt;/code&gt; haciendo referencia al directorio actual.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;El archivo debe regresar una instancia del objeto &lt;code&gt;PhpCsFixer\Config&lt;/code&gt; el cual contiene todas las reglas que se desean agregar al verificador de estilos. Nuevamente reitero que se siguen las convenciones más recientes, pero eres libre de agregar en el método &lt;code&gt;setRules()&lt;/code&gt; todas las reglas que necesites, para que &lt;code&gt;phpcs&lt;/code&gt; se adapte a su proyecto.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No encadenar el método &lt;code&gt;setFinder&lt;/code&gt;  a la instancia de &lt;code&gt;PhpCsFixer\Config&lt;/code&gt; , para decírle los directorios que debe analizar y/o excluir.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Ejecución de phpcs
&lt;/h2&gt;

&lt;p&gt;Una vez configurado &lt;code&gt;phpcs&lt;/code&gt; con las reglas que deseemos y archivos que deben ser analizados, entonces tenemos un par de comandos que se encargarán de ejecutar la herramienta de phpcs:&lt;/p&gt;

&lt;h3&gt;
  
  
  Revisión de estilos
&lt;/h3&gt;

&lt;p&gt;Bastará con ejecutar la instrucción:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./vendor/bin/php-cs-fixer fix &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="nt"&gt;--diff&lt;/span&gt; &lt;span class="nt"&gt;--dry-run&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En dónde:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;fix&lt;/code&gt;: Es la instrucción que se encarga de ejecutar el análisis de los estilos del código.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-v&lt;/code&gt;: Le indica a &lt;code&gt;phpcs&lt;/code&gt; que muestre la mayor cantidad de información posible respecto a su ejecución.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--diff&lt;/code&gt;: Le indica a phpcs que nos muestre las diferencias encontradas en cada archivo.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--dry-run&lt;/code&gt;: Le indica a &lt;code&gt;phpcs&lt;/code&gt; que el comando debe ejecutarse sin realizar ningún cambio en los archivos analizados.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Al finalizar el proceso, &lt;code&gt;phpcs&lt;/code&gt; te entregará una salida en la que cada archivo analizado se puede representar con los  valores:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;? = Pasó algo inesperado.
I = Sintaxis de php incorrecta, se saltará la revisión.
S = Archivo saltado, por estar vacío o por ya estar en caché.
. = No requiere cambios.
F = Arreglado.
E = Archivo que tiene errores de estilo.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A parte de darte una representación rápida de cada archivo, el comando hará una lista de los errores que se detectaron en cada archivo.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Nota: &lt;code&gt;phpcs&lt;/code&gt; utiliza un sistema de caché para no tener que analizar aquellos archivos que ya fueron analizados y que no tienen cambios. Si tu proyecto es muy extenso, es muy probable que éste proceso demore un buen rato.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Corrección de estilos
&lt;/h3&gt;

&lt;p&gt;Parte de la magia de &lt;code&gt;phpcs&lt;/code&gt; no es solo asegurarse de que las reglas se cumplan, sino que tiene la capacidad de corregir de manera automática aquellos errores que se detectaron durante el análisis, para ello, se ejecuta el siguiente comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./vendor/bin/php-cs-fixer fix &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="nt"&gt;--diff&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Si nos damos cuenta, el comando es muy similar al anterior, pero eliminado la opción &lt;code&gt;--dry-run&lt;/code&gt;, de ésta manera &lt;code&gt;phpcs&lt;/code&gt; intentaŕa agregar los estilos erróneos que detecte.&lt;/p&gt;

&lt;p&gt;Una vez terminado el proceso, obtendremos una salida similar a la del comando anterior.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creando un alias para ejecutar phpcs (solo composer)
&lt;/h2&gt;

&lt;p&gt;Ahora bien, es muy probable que pienses que los comandos son un poco difíciles de memorizar, por fortuna para nosotros, si es que utilizamos &lt;code&gt;composer&lt;/code&gt;, es que podemos crear un &lt;code&gt;script&lt;/code&gt; personalizado que haga más fácil la ejecución de cualquier herramienta externa, nosotros crearemos 2, una para revisar el código y otra para corregirlo.&lt;/p&gt;

&lt;p&gt;Para ello, basta con abrir el archivo &lt;code&gt;composer.json&lt;/code&gt; , y agregar una nueva entrada llamada &lt;code&gt;"scripts"&lt;/code&gt;, similar a lo siguiente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"phpcs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"php-cs-fixer fix -v --diff --dry-run"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"phpcs-fix"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"php-cs-fixer fix -v --diff"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Una vez realizados los cambios, guardamos el archivo y podremos ejecutar los comandos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;composer phpcs&lt;/code&gt; para hacer la revisión del código&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;composer phpcs-fix&lt;/code&gt; para intentar solucionar los errores de manera automática.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Una de las principales ventajas de &lt;code&gt;phpcs&lt;/code&gt; , a parte de ayudar mantener el código igual a lo largo de todo su desarrollo, es que se presta perfectamente para un proceso de &lt;code&gt;integración continua&lt;/code&gt;, por ende, te permite que tu proyecto pueda ser construido por varios programadores y que en caso de no cumplir con las reglas, el código no se podrá integrar al proyecto.&lt;/p&gt;

&lt;p&gt;Y a pesar de que &lt;code&gt;phpcs&lt;/code&gt;  tiene una herramienta que te permite corregir los estilos automáticamente, yo te sugiero que intentes escribir código que no tenga errores de estilo (sin la necesidad de usar la herramienta de corrección). Esto te ayudará a mejorar tu calidad de código en general.&lt;/p&gt;

&lt;p&gt;Espero que este post te haya sido de utilidad, recuerda que si tienes alguna duda o comentario que pueda mejorar el contenido, siéntete libre de compartirlo en los comentarios, puedes expresarlo en los comentarios.&lt;/p&gt;

&lt;p&gt;¡Hasta la próxima!  &lt;/p&gt;

</description>
      <category>php</category>
      <category>codestyle</category>
      <category>bestpractices</category>
      <category>tools</category>
    </item>
    <item>
      <title>¿Eres un buen programador?</title>
      <dc:creator>Javier Ledezma</dc:creator>
      <pubDate>Mon, 20 Jul 2020 02:43:26 +0000</pubDate>
      <link>https://dev.to/javleds/eres-un-buen-programador-56lg</link>
      <guid>https://dev.to/javleds/eres-un-buen-programador-56lg</guid>
      <description>&lt;p&gt;Desde que comencé a desarrollar software siempre he temido al hecho de no ser un buen programador, un miedo que se basaba en la curiosidad de comparar mis habilidades con el resto de mis colegas, de saber si seré capaz de completar las tareas que me designen, si mis soluciones serán las correctas, de saber si mi velocidad de desarrollo es la óptima, e inclusive, antes de ser contratado en algúna empresa o comenzar algún proyecto, el hecho de cuestionar si mis conocimientos eran suficientes.&lt;/p&gt;

&lt;p&gt;Probablemente a ti te haya pasado algo similar, este proceso de dudar de tus capacidades para llevar a cabo cierta actividad es conocida como &lt;code&gt;síndrome del impostor&lt;/code&gt;, en el podcast &lt;a href="https://twitter.com/chilemoleytech"&gt;chile, mole &amp;amp; tech&lt;/a&gt; tienen un &lt;a href="https://anchor.fm/chilemoleytech/episodes/S1E14---El-Sndrome-del-Impostor-eghl20"&gt;episodio completo&lt;/a&gt; respecto al tema por si te gustaría saber más al respecto.&lt;/p&gt;

&lt;p&gt;En éste blog te compartiré un ciclo de actividades que me han hecho superar el síndrome del impostor a lo largo de mi carrera, inclusive si no sufres del síndrome del impostor, podrían ayudarte a mejorar bastante:&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Aprende algo nuevo de tu tecnología favorita
&lt;/h2&gt;

&lt;p&gt;Ya sea que tu rama sea backend, frontend, desarrollo móvil, ciencia de datos o cualquier otra, elije un lenguaje y/o un framework y aprende lo más que puedas de esa tecnología, intenta leer su documentación oficial, si se te complica demasiado, busca blogs o videos en youtube e intenta seguir los tutoriales que encuentres.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;En internet hay información gratuita de todo lo que necesites, sin embargo, si tienes la posibilidad, intenta invertir en recursos que te ayuden a aprenderlo, por ejemplo un curso de paga, no dudes en invertir en ellos, regularmente son recursos que te ayudan a aprender y a mejorar notablemente.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Si ya conoces las bases del lenguaje o tecnología, ahora céntrate en aprender buenas prácticas, intenta aprender patrónes de diseño y profundiza lo más que puedas respecto al lenguaje.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Mi colega Juan Perdomo, esta escribiendo blogs de &lt;a href="https://kanabos.wordpress.com"&gt;patrones de diseño&lt;/a&gt;) por si estás interesado en ellos.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Practica
&lt;/h2&gt;

&lt;p&gt;Con cada cosa nueva que aprendas, intenta crear un mini-proyecto en dónde utilices lo que aprendiste, intenta que tu propuesta de proyecto no sea muy complicada, por ejemplo, si aprendiste cómo crear e invocar funciones, entonces plantea un reto en dónde tengas que crear una serie de funciones, con diversos tipos de parámetros, con diversos valores de retorno y asegurate de llamarlas en algún lado.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Si te sientes seguro de lo que sabes hasta ahora, en vez de crear un proyecto, intenta contribuir a algún proyecto open source, ésta es una de las mejores maneras que existen para dejar de lado el síndrome del impostor.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Comparte
&lt;/h2&gt;

&lt;p&gt;Hay una diferencia enorme entre un proyecto que se queda en un ambiente local y uno que es compartido en internet. En internet recibirás críticas de todo tipo, pero estoy seguro de que sabrás interpretarlas para mejorar lo que hiciste.&lt;/p&gt;

&lt;p&gt;Si tu mini-proyecto es un script sencillo, no tienes que crear una págna web o un ejecutable perfecto, basta con que subas tu código a un repositorio como GitHub o GitLab. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Para este paso, tendrás que dedicar un poco de tiempo para aprender a los comandos básicos de herramientas de control de versiones como lo es &lt;code&gt;git&lt;/code&gt;. Por fortuna, hay muchos recursos gratuitos y de paga en los que te puedes apoyar para aprenderlo, si no encuentras algo, sientete libre de preguntar en los comentarios.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Crear el hábito de subir tu código a un repositorio, además de servirte como respaldo en caso de que algo suceda con tu computadora, te permite medir los avances que has tenido desde que comenzaste, y también podrías utilizar esto como un portafolio para alguna entevista de trabajo.&lt;/p&gt;

&lt;p&gt;Por otro lado, no solo puedes compartir código, si conoces alguna manera de hacer las cosas, puedes escribir un blog o crear un apunte y compartirlo en tus redes sociales, esto también te deja mucho aprendizaje.&lt;/p&gt;

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

&lt;p&gt;Hazle llegar tu código a tus compañeros de trabajo, amigos programadores o si te sientes con un poco más de confianza, a grupos redes sociales como Facebook o algúna comunidad de la tecnología y pide algún mensaje de mejora, siempre mencionando tu tiempo de conocer la tecnología, esto ayudará a tus colegas a saber que tan duras pueden ser las críticas contigo.&lt;/p&gt;

&lt;p&gt;No solo puedes preguntar si tu código esta bien o mal, puedes preguntar que podrías mejorar o de qué manera podría hacer más complicado tu mini-proyecto. Esto te dará ideas para seguir creando retos.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A veces es muy complicado encontrar a alguien que te pueda apoyar dado que las personas tienen otras cosas que hacer, si gustas, pregunta por feedback en los comentarios y con suerte, yo o alguien con mayor experiencia en tu área pueda ayudarte.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Al igual, si tienes más experiencia, tomate un tiempo apra revisar el código de otras personas y brindale los mejores consejos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Escribe pruebas automatizadas
&lt;/h2&gt;

&lt;p&gt;En general, éste punto es uno de los que yo he aprendido recientemente y, siendo honesto, no es fácil adquirir una cultura de programación de pruebas, sin embargo, tiene muchísimos beneficios. Concéntrate en entender cuál es el propósito de una prueba unitaria, cómo se programan y cómo ejecutarlas.&lt;/p&gt;

&lt;p&gt;Intenta agregar pruebas para cada uno de los mini-proyectos que has desarrollado, esto te dará la pauta para comenzar desde cosas sencillas hasta lo más complejo que hayas hecho.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mejora (Refactoriza)
&lt;/h2&gt;

&lt;p&gt;De vez en cuando, vuelve a alguno de tus proyectos anteriores y con ayuda de las pruebas automatizadas, mejora el código que tenías, ya sea que mejores el performance, mejores la forma en que se hizo o que le des estílo a tu código, este hábito te permitirá medir el progreso que has tenido a lo largo de tu carrera y te dará la confianza necesaria para afrontar nuevos retos.&lt;/p&gt;

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

&lt;p&gt;Este ciclo de actividades es una forma de llegar a tu siguiente versión de programador, en mi caso logré hacer de estas actividades un hábito e implementarlas en proyectos open source ha sido la mejor manera de mejorar la confianza en mi mismo.&lt;/p&gt;

&lt;p&gt;Espero que  el contenido de este blog te haya sido de mucha ayuda. Recuerda que tus comentarios siempre son bienvenidos, si tienes algo que agregar o necesitas ayuda en un punto específico, con gusto te ayudaré.&lt;/p&gt;

&lt;p&gt;¡Hasta la próxima!&lt;/p&gt;

</description>
      <category>improvement</category>
      <category>software</category>
      <category>habits</category>
      <category>activities</category>
    </item>
    <item>
      <title>¿Cosas deberías saber antes de iniciar en el mundo de DevOps?</title>
      <dc:creator>Javier Ledezma</dc:creator>
      <pubDate>Sun, 05 Jul 2020 23:45:07 +0000</pubDate>
      <link>https://dev.to/javleds/cosas-deberias-saber-antes-de-iniciar-en-el-mundo-de-devops-3bml</link>
      <guid>https://dev.to/javleds/cosas-deberias-saber-antes-de-iniciar-en-el-mundo-de-devops-3bml</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Foto de bongkarn thanyakij en Pexels&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;DevOps es un término que está atrayendo cada vez mas a muchos programadores y administradores de sistemas y tiene mucho sentido, DevOps es una filosofía y conjunto de prácticas que nos permiten crear software escalable, delegando actividades como escuchar cambios en el código, construir nuestra aplicación y llevar nuestros cambios a producción a ciertas herramientas (también conocido como automatizar).&lt;/p&gt;

&lt;p&gt;Y realmente nos podemos aventurar en aprender alguna herramienta que nos ayude a lograr dicho cometido, pero antes de comenzar, te recomendaría que te tomes un tiempo para entender ¿por qué necesitas aprender DevOps?.&lt;/p&gt;

&lt;h2&gt;
  
  
  Entendiendo el proceso de desarrollo de software
&lt;/h2&gt;

&lt;p&gt;Los procesos de desarrollo de software suelen variar por cada proyecto, equipo o empresa, pero regularmente se apegan mucho a lo siguiente:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creación del entorno de desarrollo.&lt;/li&gt;
&lt;li&gt;Desarrollo de software.&lt;/li&gt;
&lt;li&gt;Validación de calidad interna del código.&lt;/li&gt;
&lt;li&gt;Construcción o empaquetamiento de aplicación.&lt;/li&gt;
&lt;li&gt;Despliegue a producción.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Antes de DevOps
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Creación del entorno de desarrollo
&lt;/h3&gt;

&lt;p&gt;Todo proyecto de software requiere de un entorno de desarrollo, esto incluye la instalación de aplicaciones y servicios para que tu código pueda ser ejecutado, por ejemplo, motores de bases de datos, apache o nginx, firewalls, etc. En éste paso también se incluye la configuración de estas aplicaciones y servicios. &lt;/p&gt;

&lt;p&gt;Para poder determinar qué requiere el entorno de desarrollo podríamos hacer una lista de todo aquello que se necesita instalar/configurar en una computadora recién salida de fabrica para nuestra aplicación pueda ejecutarse. &lt;/p&gt;

&lt;h3&gt;
  
  
  Desarrollo de software
&lt;/h3&gt;

&lt;p&gt;Una vez que logramos echar a andar nuestra aplicación en nuestro entorno de desarrollo, solemos agregar funcionalidades, mejorar el rendimiento o corregir los errores encontrados en la aplicación. &lt;/p&gt;

&lt;h3&gt;
  
  
  Validación de calidad interna del código
&lt;/h3&gt;

&lt;p&gt;Cada que un equipo de desarrollo (o desarrollador) completa un fragmento funcional de la aplicación, se realiza una revisión para saber si el código entregado por el equipo de desarrollo cumple con los estándares de calidad del proyecto, si cumple con los requerimientos y si no  tiene errores.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Nota:&lt;/strong&gt; En este paso también nos aseguramos de que la nueva funcionalidad no afecte el código que ya se encuentra funcionando.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Construcción o empaquetamiento de aplicación
&lt;/h3&gt;

&lt;p&gt;En caso de que el código cumpla con todo lo necesario, entonces, una persona se encargaba de ejecutar en su computadora una serie de tareas para construir o empaquetar nuestra aplicación, tareas como instalar las dependencias del proyecto y construir un ejecutable (si es que se requería).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Nota:&lt;/strong&gt; Cuando hablamos de dependencias del proyecto, nos referimos a las librerías propias del código, por ejemplo, librerías para manejar fechas, librerías para leer archivos CSV, etc.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Despliegue a producción
&lt;/h3&gt;

&lt;p&gt;Finalmente se toma la construcción de nuestra aplicación (o empaquetado) y se realiza un proceso de despliegue, en el que colocamos nuestro producto final a disposición de nuestros clientes, nuevamente, los pasos para hacer despliegue pueden variar dependiendo de la aplicación, lenguaje, etc. Y cada uno de estos pasos era ejecutado por una persona encargada a través de una terminal ssh o mediante archivos de transferencia de archivos (FTP).&lt;/p&gt;

&lt;h3&gt;
  
  
  Problemas frecuentes
&lt;/h3&gt;

&lt;p&gt;Una vez que conocemos el proceso por cual pasa una simple mejora de código, nos podemos percatar de que se requiere de demasiado esfuerzo, por ello, las empresas o equipos solían hacer despliegue de un grupo de mejoras cada cierto tiempo o cuando se cumplía cierto entregable.  &lt;/p&gt;

&lt;p&gt;A parte de que las entregas se tornaban lentas, si algo salía mal, se tenía que hechar para atrás todo el grupo de mejoras que se habían lanzado a producción.&lt;/p&gt;

&lt;h2&gt;
  
  
  Con DevOps
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Creación del entorno de desarrollo
&lt;/h3&gt;

&lt;p&gt;En vez de crear un entorno de desarrollo manualmente, se opta por utilizar herramientas como virtualización o contenedores para armar éstos entornos de desarrollo, de ésta manera, solo se crea un servicio para cada aplicación y éste servicio se instancía cada que sea necesario. &lt;/p&gt;

&lt;p&gt;Ejemplos de herramientas con las que se logra esto: Docker, VMWare.&lt;/p&gt;

&lt;h3&gt;
  
  
  Desarrollo de software
&lt;/h3&gt;

&lt;p&gt;Para este punto se suelen utilizar sistemas de versionamiento de archivos, como git o mercurial. Estas herramientas pueden ser configuradas para trabajar en conjunto con otros servicios que se encarguen de realizar automáticamente el despliegue a producción cada que se detecte un cambio. &lt;/p&gt;

&lt;p&gt;En este paso se agrega una capa adicional y "obliga" a los desarrolladores a crear pruebas automatizadas para su código, cada que un desarrollador o equipo de desarrollo completa una funcionalidad, el código va acompañado de una serie de pruebas que se encargan de validar que el código cumple con su función.&lt;/p&gt;

&lt;p&gt;Ejemplos de herramientas con la que se peude lograr esto: github, gitlab, bitbucket.&lt;/p&gt;

&lt;h3&gt;
  
  
  Validación de calidad interna del código
&lt;/h3&gt;

&lt;p&gt;En éste paso, se obtienen los últimos cambios registrados en el sistema de versionamiento, y las herramientas se encargan de utilizar instanciar un contenedor o levantar una máquina virtual con el entorno de desarrollo, configurar el proyecto y ejecutar la suite completa de pruebas sobre los cambios detectados. Si algo llegara a salir mal, el proceso de despliegue se detiene aquí, de lo contrario procede a la construcción.&lt;/p&gt;

&lt;p&gt;Ejemplos de herramientas con las que se logra esto: Jenkins, TravisCI, CircleCI.&lt;/p&gt;

&lt;h3&gt;
  
  
  Construcción o empaquetamiento de aplicación
&lt;/h3&gt;

&lt;p&gt;Una vez asegurada la calidad del código se realiza una serie de pasos automatizados que se encargan de construir la aplicación, a través de comandos o de ciertos plugins de la herramienta de integración continua.&lt;/p&gt;

&lt;p&gt;Ejemplos de herramientas con las que se logra esto: Jenkins, TravisCI, CircleCI.&lt;/p&gt;

&lt;h3&gt;
  
  
  Despliegue a producción
&lt;/h3&gt;

&lt;p&gt;Las mismas herramientas de integración continua, nos permiten configurar los pasos necesarios para poder hacer un depliegue a producción, esto conlleva la preparación del entorno productivo, la configuración de las variables de entorno y la copia de archivos necesarios para poder tener nuestra aplicaicón disponible para nuestros usuarios.&lt;/p&gt;

&lt;p&gt;Ejemplos de herramientas con las que se logra esto: Jenkins, TravisCI, CircleCI.&lt;/p&gt;

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

&lt;p&gt;DevOps requiere de una configuración muy fuerte al incio para poder automatizar todo el proceso, sin embargo, una vez configurada nos permite realizar despliegues mucho más confiables, haciendo que cada entrega se puede realizar de manera independiente y no requiera de esperar a una fecha para desplegar un grupo de cambios&lt;/p&gt;

&lt;p&gt;A demás, en caso de error, solamente se regresaría ese último cambio desplegado.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nota:&lt;/strong&gt; Te recomiendo no implementar DevOps si no conoces el proceso completo de desarrollo de tu proyecto, ya que DevOps no es una receta única, se debe crear y configurar acorde a las necesidades de cada proyecto.&lt;/p&gt;

&lt;p&gt;Te invito a que analices el proceso actual de desarrollo de tu empresa o tu proyecto siguiendo los pasos que te comenté en éste post. &lt;/p&gt;

&lt;p&gt;Si tienes dudas de como iniciar a automatizar con alguna herramienta, deja tu inquietud en un comentario y te pasaré algún recurso de utilidad, al igual si ya tienes experiencia en DevOps cuentanos de ella y finalmente, si tienes algún comentario o sugerencia, siempre serán bienvenidos.&lt;/p&gt;

&lt;p&gt;¡Hasta la próxima!&lt;/p&gt;

</description>
      <category>devops</category>
      <category>ci</category>
      <category>cd</category>
      <category>software</category>
    </item>
  </channel>
</rss>
