<?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>Forem: Josa Vicente</title>
    <description>The latest articles on Forem by Josa Vicente (@josavicente).</description>
    <link>https://forem.com/josavicente</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%2F641279%2F8b0e8459-83ba-410f-a443-e5f7408ee6c7.jpeg</url>
      <title>Forem: Josa Vicente</title>
      <link>https://forem.com/josavicente</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/josavicente"/>
    <language>en</language>
    <item>
      <title>Que nos hace crecer? Coaching vs Mentorship vs Sponsorship</title>
      <dc:creator>Josa Vicente</dc:creator>
      <pubDate>Mon, 17 Apr 2023 22:00:00 +0000</pubDate>
      <link>https://forem.com/josavicente/que-nos-hace-crecer-coaching-vs-mentorship-vs-sponsorship-o8</link>
      <guid>https://forem.com/josavicente/que-nos-hace-crecer-coaching-vs-mentorship-vs-sponsorship-o8</guid>
      <description>&lt;p&gt;Creo que no hay duda, y que si lees este blog estarás de acuerdo, la forma natural de progresar en nuestras carreras no depende únicamente&lt;br&gt;
de nosotros. Obviamente el rol protagonista lo tenemos nosotros, pero lo que marca la diferencia en un momento dado son las relaciones. No estoy&lt;br&gt;
hablando de relaciones por interés, sino de relaciones genuinas.&lt;/p&gt;

&lt;p&gt;Todos crecemos con ayuda, todos podemos pensar en una persona o varias que nos han ayudado en nuestras carreras. Pueden ser etapas largas o&lt;br&gt;
simplemente pequeños momentos en los que algún compañero nos aporto una pieza de su experiencia para saber lidiar con un problema.&lt;/p&gt;

&lt;p&gt;El objetivo de este post es intentar hacer más relevante, más intencionada y eficaz la forma en la que pedimos ayuda a personas con más experiencia&lt;br&gt;
y como ofrecérsela a las personas de nuestros equipos.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sponsors, Mentors, and Coaches
&lt;/h3&gt;

&lt;p&gt;Podemos ayudar a nuestros equipos de distintas formas. En función de lo directa o indirecta que sea nuestra forma de actuar. En el ámbito profesional podemos&lt;br&gt;
separar en tres tipos de relaciones:&lt;/p&gt;

&lt;h4&gt;
  
  
  🗣️ Coaching
&lt;/h4&gt;

&lt;p&gt;La más indirecta de todas, cuando hacemos coaching lo que estamos tratando de generar es la respuesta en la propia persona. No se trata de dar la respuesta, sino&lt;br&gt;
de provocar de distintas formas la propia respuesta en el razonnamiento de la persona que queremos ayudar, mediante preguntas, haciendo challenge o animando a dedicar más&lt;br&gt;
tiempo a la búsqueda o aprendizaje. De nada sirve proporcionar la respuesta directamente, es más, puede que ni la sepamos,&lt;br&gt;
nuestro papel no es saberlo todo y dar la respuestra a nuestro equipo, sino darles las herramientas para encontrar la solución por ellos mismos, generando así&lt;br&gt;
un aprendizaje y desarrollando una experiencia que de otra forma no sería posible.&lt;/p&gt;

&lt;p&gt;El coaching se da en las etapas iniciales de un problema/situación, cuando la persona no tiene ni idea de por donde avanzar, se trata de ayudar con el "que" y no con el "como".&lt;/p&gt;

&lt;h4&gt;
  
  
  📘 Mentoring
&lt;/h4&gt;

&lt;p&gt;En el caso del mentoring, la relación es más directa. En este caso, el mentor es alguien que:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tiene una expertise técnica que favorece la ayuda a la persona y/o puede darle los recuros y conocimientos necesarios para solucionar un problema.&lt;/li&gt;
&lt;li&gt;Es alguien que tiene una experiencia en la empresa o en el sector que puede ayudar a la persona a entender mejor el contexto en el que se mueve.&lt;/li&gt;
&lt;li&gt;Ha pasado por la misma situación y por tanto puede dar una guía de como afrontarla.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;En este caso, es la siguiente etapa, una vez ya sabes el &lt;strong&gt;que&lt;/strong&gt;, el mentoring ayudará al mentee con el &lt;strong&gt;cómo&lt;/strong&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  🏅 Sponsorship
&lt;/h4&gt;

&lt;p&gt;El sponsorship es la relación más directa de todas. En este caso, el sponsor es alguien que realiza acciones reales para ayudar a la persona a avanzar en su carrera.&lt;br&gt;
Mientras un mentor da consejos, un sponsor te empodera y te ofrece oportunidades reales para crecer. Estas oportunidades pueden ser desde aportar su opinión acerca de una posible promoción,&lt;br&gt;
dar oportunidades en proyectos de mayor visibilidad, ayudarte presentándote personas que pueden crear impacto en tu carrera e incluso ofercerte un nuevo trabajo.&lt;/p&gt;

&lt;h3&gt;
  
  
  💭 Ok, pero como aplico estos tipos de relaciones?
&lt;/h3&gt;

&lt;p&gt;Tanto si estás en un lado o en el otro, no a todos ni en todo momento nos sirve una de estas figuras. Es posible que por el momento vital/personal en el que te encuentres, no estés preparado&lt;br&gt;
para ser sponsorizado, o tu no puedas sponsorizar a otra persona porque tu rol no te permite esa clase de impacto. Un perfil junior necesitará inicialmente más un coach y una vez es hábil con el "que",&lt;br&gt;
entonces necesitará la figura del mentor. Como en casi todo, la palabra clave es &lt;strong&gt;depende&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;La mejor forma de hacerlo, es una mezcla de todos ellos. Como Engineer Manager, podremos ser parte o tener el papel de alguno o de varios de estos approaches, pero:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Es imposible serlo de todo el equipo&lt;/li&gt;
&lt;li&gt;No siempre estás en la posición o rol adecuado, pero de ser así, tu papel será ayudar a encontrar para esa persona su siguiente next step.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Por ejemplo, cuando se plantea un problema en el que mis skills coincide con las de la persona, actúo como mentor, sugiriendo formas prácticas de avanzar. Cuando no es así, sin embargo, doy un paso atrás y actúo como coach: &lt;br&gt;
les hago reflexionar sobre las cuestiones de fondo, apoyo su forma de razonar y trato de ayudar a encontrar la mejor solución posible.&lt;br&gt;
Mi forma de actuar es ligeramente distinta en el caso de ser un perfil junior. En estos casos, creo que la mejor forma de aprender es pelearse con los problemas y por tanto, en lugar de darles la solución, les planteo las preguntas&lt;br&gt;
que creo adecuadas para hacerles challenge y que saquen su propia solución. Quizá en la primera iteración no sea la mejor, pero cada iteración proporciona posibilidades de aprendizaje distintas.&lt;/p&gt;

&lt;p&gt;El papel que se me antoja más complejo es el de sponsor, si bien podemos sponsorizar a distintas escalas, está claro que cuanta más influencia tengas más vas a poder impactar en la carrera de esa persona.&lt;/p&gt;

&lt;p&gt;En mi opinión el coaching requiere mucho más esfuerzo, es más duro. Tendemos a mentorizar en su lugar porque el coaching nos exige más, nos exige ser más reflexivos y más pacientes. De todas maneras es la fórmula que más me gusta,&lt;br&gt;
creo que por un lado, lo que te sirve a ti no le sirve a los demás y en un mundo que cambia con tanta rápidez, mentorizar en base a tu experiencia pasada me parece que parte de una base ya obsoleta. Además le quita gran parte&lt;br&gt;
del ownership a la persona que lo recibe, pues no le empodera tanto una vez lo soluciona. Por otro lado, el coaching le permite desarrollar su propia experiencia, lo que le permitirá afrontar problemas similares en el futuro.&lt;/p&gt;

&lt;h3&gt;
  
  
  🏈 Ahora, como hacerlo en tu equipo?
&lt;/h3&gt;

&lt;p&gt;Bueno, en teoría, en un equipo la gente se ayuda constantemente, o eso debería. Si no es así, este no es el artículo que debes leer. Hay algunos escenarios típicos que pueden facilitar estos tipos de relaciones:&lt;/p&gt;

&lt;h5&gt;
  
  
  Onboardings
&lt;/h5&gt;

&lt;p&gt;El primer día de un nuevo miembro del equipo es un momento clave para establecer una relación de mentoría. En este caso, el mentor es el que tiene más experiencia en la empresa y el mentee es el nuevo miembro del equipo.&lt;/p&gt;

&lt;h5&gt;
  
  
  Training a juniors
&lt;/h5&gt;

&lt;p&gt;En este caso, es positivo tanto para el mentor como el mentorizado. El junior recibe ayuda de un perfil experimentado del que aprender y el mentor mejora sus capacidades de comunicación y perfecciona su conocimiento. &lt;br&gt;
La mejor forma de interiorizar conocimiento es compartirlo con los demás. Depende en que lado estés:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Como Engineer Manager: Facilito el crecimiento de los perfiles juniors? Obtienen suficiente mentoría?&lt;/li&gt;
&lt;li&gt;Como junior: pide a un compañero senior que sea tu mentor. Pídele consejo de forma recurrente.&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  La relación con tu manager
&lt;/h5&gt;

&lt;p&gt;Como engineer manager puedes ejercer los distintos papeles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Como sponsor, ayudas a los miembros de tu equipo a obtener reconocimiento y oportunidades. Por ejemplo, darle la oportunidad de dirigir proyectos con cierta visibilidad o importancia, dar charlas al equipo u otros equipos. En este punto debemos poner especial atención a los sesgos. Está demostrado que mujeres y minorías tienden a ser sobre-mentorizados y infra-sponsorizados. &lt;/li&gt;
&lt;li&gt;Como mentor: debes ser más directo y ofrecer consejos de como mejorar las habilidades de una persona. Debes balancearlo bien, ya que un exceso puede tender a quitar ownership del equipo. Es un típico error de managers primerizos o que les cuesta dejar su rol de IC (individual contributor)&lt;/li&gt;
&lt;li&gt;Como coach: trabajas para averiguar cuáles son sus objetivos, qué le hace feliz y qué dirección quiere dar a su carrera. Aquí tenemos el error contrario, si nos pasamos de dejar a la persona sin cierta dirección, podemos provocar frustración y desmotivación al dejar que choquen demasiado a menudo con los problemas.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🌎 Y si no puedes hacerlo en tu trabajo?
&lt;/h3&gt;

&lt;p&gt;Si no puedes desarrollar estas relaciones en tu puesto de trabajo, ya sea dándolas o recibiéndolas. Otras opciones pueden ser:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tu red, si tienes una red de contactos, puedes buscar a alguien que pueda ser tu mentor. Si no tienes una red, puedes empezar a construirla.&lt;/li&gt;
&lt;li&gt;Comunidades&lt;/li&gt;
&lt;li&gt;Conferencias&lt;/li&gt;
&lt;li&gt;Meetups &lt;/li&gt;
&lt;li&gt;Coaching profesional&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Tanto en un sentido u otro, las distintas relaciones tienen aportes en tu carrera que merecen la pena explotar. Como persona que durante mucho tiempo no tuvo ningún tipo de estas relaciones, tener que construirlas es complejo y agotador.&lt;br&gt;
Por este motivo, en mi caso, me esfuerzo por construirlas tanto para mi equipo como para mi. Creo que es una inversión que merece la pena y que aporta mucho valor tanto para el equipo como para uno mismo.&lt;/p&gt;

</description>
      <category>mentorship</category>
      <category>sponsorship</category>
      <category>coaching</category>
      <category>growth</category>
    </item>
    <item>
      <title>Principios SOLID VI: Principio de inversión de dependencias</title>
      <dc:creator>Josa Vicente</dc:creator>
      <pubDate>Sun, 16 Apr 2023 22:00:00 +0000</pubDate>
      <link>https://forem.com/josavicente/principios-solid-vi-principio-de-inversion-de-dependencias-eea</link>
      <guid>https://forem.com/josavicente/principios-solid-vi-principio-de-inversion-de-dependencias-eea</guid>
      <description>&lt;p&gt;El principio de inversión de dependencias indica que las clases de un sistema deben depender de las abstracciones/interfaces y no de las implementaciones concretas. Esto significa que las clases no deben depender directamente de clases específicas, sino de interfaces o clases abstractas. Esto lo haremos inyectando dependencias en el constructor de la clase, pero estas dependencias serán interfaces o clases abstractas, no clases finales.&lt;/p&gt;

&lt;p&gt;Un ejemplo de violación del principio de inversión de dependencias en un programa inspirado en Pokemon podría ser el siguiente. Tenemos una clase &lt;strong&gt;PokemonTrainer&lt;/strong&gt; que se encarga de entrenar a un Pokemon específico y una clase &lt;strong&gt;Charizard&lt;/strong&gt; que representa a un Pokemon de tipo fuego.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PokemonTrainer&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;train&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pokemon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Charizard&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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Charizard&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 este ejemplo, la clase &lt;strong&gt;PokemonTrainer&lt;/strong&gt; tiene una dependencia directa con la clase &lt;strong&gt;Charizard&lt;/strong&gt; y solo puede entrenar a ese tipo de Pokemon específico, lo cual viola el principio de inversión de dependencias ya que la clase &lt;strong&gt;PokemonTrainer&lt;/strong&gt; depende directamente de la implementación concreta de una clase &lt;strong&gt;Charizard&lt;/strong&gt; y no de una abstracción o interfaz que represente cualquier Pokemon.&lt;/p&gt;

&lt;p&gt;Un ejemplo correcto sería tener una interfaz &lt;strong&gt;Pokemon&lt;/strong&gt; y modificar la clase &lt;strong&gt;PokemonTrainer&lt;/strong&gt; para depender de esta interfaz:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;Pokemon&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;train&lt;/span&gt;&lt;span class="p"&gt;()&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;Charizard&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Pokemon&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;train&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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PokemonTrainer&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;train&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pokemon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Pokemon&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;pokemon&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;train&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;De esta manera, la clase &lt;strong&gt;PokemonTrainer&lt;/strong&gt; depende de una abstracción, la interfaz &lt;strong&gt;Pokemon&lt;/strong&gt;, en lugar de una implementación concreta. Esto permite que se puedan entrenar diferentes tipos de Pokemon en lugar de solo uno específico. Además, si se desea añadir otro tipo de Pokemon, solo se requiere crear una nueva clase que implemente la interfaz &lt;strong&gt;Pokemon&lt;/strong&gt; y no tener que modificar la clase &lt;strong&gt;PokemonTrainer&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Este princpio es una de los más importantes. Cuando escriba sobre arquitectura hexagonal, veremos que se basa en gran medida en el uso de esta inyección de dependencias con el objetivo de facilitar la modificación y la sustitución de implementaciones en entornos cambiantes y que escalan rápidamente tras demostrar una hipótesis. &lt;/p&gt;

&lt;p&gt;Además este principio facilita la testabilidad de las clases porque permite desacoplar las dependencias de las clases. En lugar de crear las dependencias dentro de la clase, las dependencias se pasan a la clase a través de su constructor o métodos de configuración. Esto significa que las dependencias pueden ser fácilmente reemplazadas por sus equivalentes de prueba, lo que permite probar la clase de forma aislada. Veámoslo con un ejemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;
&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;PokemonRepository&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;getPokemon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pokemonId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;Pokemon&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;PokemonService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;repository&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;PokemonRepository&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;getPokemonName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pokemonId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;pokemon&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getPokemon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pokemonId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;pokemon&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;En este ejemplo, &lt;strong&gt;PokemonService&lt;/strong&gt; tiene una dependencia en &lt;strong&gt;PokemonRepository&lt;/strong&gt;. En lugar de crear una instancia de &lt;strong&gt;PokemonRepository&lt;/strong&gt; dentro de &lt;strong&gt;PokemonService&lt;/strong&gt;, se pasa una instancia de &lt;strong&gt;PokemonRepository&lt;/strong&gt; al constructor de &lt;strong&gt;PokemonService&lt;/strong&gt;. Así podremos proporcionar una implementación de prueba o mock de &lt;strong&gt;PokemonRepository&lt;/strong&gt; cuando creamos una instancia de &lt;strong&gt;PokemonService&lt;/strong&gt; para probarlo, lo que nos permite aislar la prueba de &lt;strong&gt;PokemonService&lt;/strong&gt; de su dependencia en &lt;strong&gt;PokemonRepository&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Un ejemplo de código para dicho test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TestPokemonRepository&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;PokemonRepository&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;getPokemon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pokemonId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;Pokemon&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;Pokemon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pokemonId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Pikachu"&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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PokemonServiceTest&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;`test&lt;/span&gt; &lt;span class="nf"&gt;getPokemonName`&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;repository&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;TestPokemonRepository&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;service&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;PokemonService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;pokemonName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getPokemonName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;assertEquals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Pikachu"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pokemonName&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;Creamos un mock llamado &lt;strong&gt;TestPokemonRepository&lt;/strong&gt; que implementa &lt;strong&gt;PokemonRepository&lt;/strong&gt;. &lt;strong&gt;TestPokemonRepository&lt;/strong&gt; devuelve siempre un objeto Pokemon de prueba con el nombre "Pikachu" independientemente del ID del Pokemon que se le pase.&lt;/p&gt;

&lt;p&gt;En la clase de prueba &lt;strong&gt;PokemonServiceTest&lt;/strong&gt;, creamos una instancia de &lt;strong&gt;TestPokemonRepository&lt;/strong&gt; y la pasamos al constructor de &lt;strong&gt;PokemonService&lt;/strong&gt;. Luego llamamos al método &lt;strong&gt;getPokemonName&lt;/strong&gt; con un ID de Pokemon específico y verificamos que el nombre devuelto sea el esperado.&lt;/p&gt;

&lt;p&gt;Así aislamos la prueba de &lt;strong&gt;PokemonService&lt;/strong&gt; de su dependencia con &lt;strong&gt;PokemonRepository&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Y hasta aquí la serie de artículos sobre los principios SOLID.&lt;/p&gt;

</description>
      <category>solid</category>
      <category>cleancode</category>
      <category>cleanarchitecture</category>
      <category>dip</category>
    </item>
    <item>
      <title>Principios SOLID V: Principio de segregación de interfaces</title>
      <dc:creator>Josa Vicente</dc:creator>
      <pubDate>Thu, 13 Apr 2023 22:00:00 +0000</pubDate>
      <link>https://forem.com/josavicente/principios-solid-v-principio-de-segregacion-de-interfaces-5834</link>
      <guid>https://forem.com/josavicente/principios-solid-v-principio-de-segregacion-de-interfaces-5834</guid>
      <description>&lt;p&gt;El principio de segregación de interfaces establece que una clase no debe ser obligada a implementar métodos que no utilizará. En otras palabras, una clase debe implementar solo los métodos necesarios para su comportamiento específico.&lt;/p&gt;

&lt;p&gt;Traduciendolo al mundo real, debemos diseñar las interfaces pensando en quien las usará, sus clientes, no en implementaciones concretas que pudieran tener.&lt;/p&gt;

&lt;p&gt;Veámoslo con un ejemplo, como hasta ahora, seguimos con Pokemons.&lt;/p&gt;

&lt;p&gt;Tenemos una interfaz PokemonActions que define métodos para realizar acciones comunes a todos los Pokemon, como atacar, defenderse, etc. Además, se tiene una clase FlyingPokemon que representa a un Pokemon volador y otra clase ElectricPokemon que representa a un Pokemon eléctrico.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;
&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;PokemonActions&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;attack&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;defend&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;fly&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;electricShock&lt;/span&gt;&lt;span class="p"&gt;()&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;FlyingPokemon&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;PokemonActions&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;attack&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// codigo ataque&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;defend&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// codigo defensa&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;fly&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// codigo vuelo&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;electricShock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// codigo imposible de ejecutar&lt;/span&gt;
    &lt;span class="p"&gt;}&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;ElectricPokemon&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;PokemonActions&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;attack&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// codigo ataque&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;defend&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// codigo defensa&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;fly&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// codigo imposible de ejecutar&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;electricShock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// codigo electricShock&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 este ejemplo, la interfaz &lt;strong&gt;PokemonActions&lt;/strong&gt; obliga a las clases &lt;strong&gt;FlyingPokemon&lt;/strong&gt; y &lt;strong&gt;ElectricPokemon&lt;/strong&gt; a implementar el método &lt;strong&gt;fly()&lt;/strong&gt;, a pesar de que solo es relevante para los Pokemon voladores, y &lt;strong&gt;electricShock()&lt;/strong&gt;, solo relevante para los Pokemon eléctricos. Por lo tanto, se viola el principio de segregación de interfaces ya que se obliga a las clases a implementar métodos que no utilizarán.&lt;/p&gt;

&lt;p&gt;La forma correcta de implementarlo siguiendo el principio de segregación de interfaces:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;FlyingPokemonActions&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;attack&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;defend&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;fly&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;ElectricPokemonActions&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;attack&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;defend&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;electricShock&lt;/span&gt;&lt;span class="p"&gt;()&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;FlyingPokemon&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;FlyingPokemonActions&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;attack&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// codigo ataque&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;defend&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// codigo defensa&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;fly&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// codigo vuelo&lt;/span&gt;
    &lt;span class="p"&gt;}&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;ElectricPokemon&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;ElectricPokemonActions&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;attack&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// codigo ataque&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;defend&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// codigo defensa&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;De esta manera, todo está en su sitio, ninguna clase tiene métodos inservibles y el código es claro y más descriptivo. El objetivo es tener alta cohesión y bajo acoplamiento.&lt;/p&gt;

</description>
      <category>solid</category>
      <category>cleancode</category>
      <category>cleanarchitecture</category>
      <category>isp</category>
    </item>
    <item>
      <title>Principios SOLID IV: Principio de sustitución de Liskov</title>
      <dc:creator>Josa Vicente</dc:creator>
      <pubDate>Tue, 11 Apr 2023 22:00:00 +0000</pubDate>
      <link>https://forem.com/josavicente/principios-solid-iv-principio-de-sustitucion-de-liskov-261a</link>
      <guid>https://forem.com/josavicente/principios-solid-iv-principio-de-sustitucion-de-liskov-261a</guid>
      <description>&lt;p&gt;LSP o Liskov Substitution Principle es una definición particular de una relación de subtipificación, llamada tipificación (fuerte) del comportamiento, que fue introducido por Barbara Liskov en 1987 en una conferencia y reformulado junto a Jeannette Wing en 1994:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Sea ϕ(x) una propiedad comprobable acerca de los objetos x de tipo T. Entonces ϕ(y) debe ser verdad para los objetos y del tipo S, donde S es un subtipo de T.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Por la forma en la que tiene siempre de explicarse este principio y por su nombre, parece más complicado de lo que realmente es. Una forma más clara de definirlo es:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Si una clase B es una subclase de una clase A, entonces un objeto de la clase B debería poder ser utilizado en cualquier lugar donde se espera un objeto de la clase A, sin causar ningún comportamiento inesperado. En otras palabras, una subclase debe ser capaz de sustituir a su superclase sin causar problemas.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Si os ha explotado la cabeza, ok, me pasó igual 🤯&lt;/p&gt;

&lt;p&gt;Con un ejemplo lo veremos muy fácil. De nuevo Pokemon.&lt;/p&gt;

&lt;p&gt;Tenemos una clase Pokemon que representa a un Pokemon en general, y varias subclases que representan a los diferentes tipos de Pokemon (como &lt;strong&gt;FirePokemon&lt;/strong&gt;, &lt;strong&gt;WaterPokemon&lt;/strong&gt;, etc.).&lt;/p&gt;

&lt;p&gt;Si en la clase &lt;strong&gt;FirePokemon&lt;/strong&gt; se incluye un método &lt;strong&gt;burnOpponent()&lt;/strong&gt; que reduce la salud del oponente en una cantidad específica de puntos de salud, sin embargo la clase &lt;strong&gt;waterPokemon&lt;/strong&gt; no incluye un método equivalente para reducir la salud del oponente. Entonces si tenemos la función &lt;strong&gt;battle(p1: Pokemon, p2: Pokemon)&lt;/strong&gt; para simular una combate entre pokemon, vemos que no funcionaría correctamente si se utilizara un WaterPokemon en lugar de un FirePokemon.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Pokemon&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;healthPoints&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FirePokemon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Pokemon&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;firePower&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;burnOpponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Pokemon&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;healthPoints&lt;/span&gt; &lt;span class="p"&gt;-=&lt;/span&gt; &lt;span class="n"&gt;firePower&lt;/span&gt;
    &lt;span class="p"&gt;}&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;WaterPokemon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Pokemon&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;waterPower&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;battle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Pokemon&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;p2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Pokemon&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;healthPoints&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;p2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;healthPoints&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p1&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nc"&gt;FirePokemon&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;p1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;burnOpponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="c1"&gt;// combate aqui&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;charmander&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FirePokemon&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;squirtle&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;WaterPokemon&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nf"&gt;battle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;charmander&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;squirtle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;En este ejemplo, un &lt;strong&gt;WaterPokemon&lt;/strong&gt; no puede ser utilizado en lugar de un &lt;strong&gt;FirePokemon&lt;/strong&gt; en el método battle ya que no tiene una forma de reducir la salud del oponente, lo que causaria un comportamiento inesperado. El principio de sustitución de Liskov se viola ya que un objeto de la subclase no puede ser utilizado en lugar de un objeto de la superclase sin causar problemas.&lt;/p&gt;

&lt;p&gt;La forma correcta de implementarlo siguiendo el principio de Liskov sería:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Pokemon&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;healthPoints&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FirePokemon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Pokemon&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;firePower&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;burnOpponent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/*...*/&lt;/span&gt;&lt;span class="p"&gt;}&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;WaterPokemon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Pokemon&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;waterPower&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;drenchOpponent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/*...*/&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;battle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Pokemon&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;p2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Pokemon&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;healthPoints&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;p2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;healthPoints&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// combate aqui&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;charmander&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FirePokemon&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;squirtle&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;WaterPokemon&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nf"&gt;battle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;charmander&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;squirtle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;De esta manera, se asegura que los objetos de una subclase se comportan de forma esperada, siempre que se utilicen en lugares donde se espera un objeto de su superclase.&lt;/p&gt;

&lt;p&gt;Toda subclase debe ser compatible con todos los métodos y propiedades de la superclase, y no solo aquellos que se utilizan en el contexto actual, ya que cualquier cambio en la superclase podría afectar a la subclase.&lt;/p&gt;

&lt;p&gt;El objetivo principal de este principio es mantener correctitud funcional para poder aplicar OCP.&lt;/p&gt;

</description>
      <category>solid</category>
      <category>cleancode</category>
      <category>cleanarchitecture</category>
      <category>liskov</category>
    </item>
    <item>
      <title>Principios SOLID III: Abierto a extensión y cerrado a modificación</title>
      <dc:creator>Josa Vicente</dc:creator>
      <pubDate>Sun, 09 Apr 2023 22:00:00 +0000</pubDate>
      <link>https://forem.com/josavicente/principios-solid-iii-abierto-a-extension-y-cerrado-a-modificacion-2489</link>
      <guid>https://forem.com/josavicente/principios-solid-iii-abierto-a-extension-y-cerrado-a-modificacion-2489</guid>
      <description>&lt;p&gt;El software debería estar abierto a extensión y cerrado a modificación. Para ello, evitemos depende de implementaciones específicas. Es más sencillo con un ejemplo.&lt;/p&gt;

&lt;p&gt;Volvamos sobre el ejemplo del post anterior inspirado en Pokemon. &lt;br&gt;
Vamos a añadir a la clase base el nombre, nivel y hp del pokemon en cuestión. Ahora añadimos clases hijas para los tipos de pokemon, por ejemplo fuego y agua.&lt;/p&gt;

&lt;p&gt;La clase base tiene una método &lt;strong&gt;attack&lt;/strong&gt;, recibe un pokemon y le reduce su hp basado en el nivel de ataque del pokemon.&lt;/p&gt;

&lt;p&gt;Al principio, este diseño funciona bien. Sin embargo, a medida que añades más características al juego, te das cuenta de que necesitas añadir diferentes tipos de ataque, como fuego y agua, que son fuertes o débiles contra ciertos tipos de Pokemon.&lt;/p&gt;

&lt;p&gt;Para implementar esto, podrías añadir un nuevo atributo llamado &lt;strong&gt;attackType&lt;/strong&gt; a la clase Pokemon y modificar el método de ataque para tener en cuenta el tipo de ataque del Pokemon atacante y el tipo del Pokemon defensor.&lt;/p&gt;

&lt;p&gt;Aquí el error, esto violaría el Principio Abierto-Cerrado, que como describía al inicio, establece que una clase debe estar abierta a extensiones, pero cerrada a modificaciones. Deberías ser capaz de añadir nuevas funcionalidades a una clase sin cambiar su código existente.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;
&lt;span class="c1"&gt;// Clase Base&lt;/span&gt;
&lt;span class="k"&gt;open&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Pokemon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;level&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;hp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Método de ataque&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;attack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Pokemon&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nc"&gt;FirePokemon&lt;/span&gt; &lt;span class="p"&gt;-&amp;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="n"&gt;target&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nc"&gt;WaterPokemon&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hp&lt;/span&gt; &lt;span class="p"&gt;-=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;level&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hp&lt;/span&gt; &lt;span class="p"&gt;-=&lt;/span&gt; &lt;span class="n"&gt;level&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nc"&gt;WaterPokemon&lt;/span&gt; &lt;span class="p"&gt;-&amp;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="n"&gt;target&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nc"&gt;FirePokemon&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hp&lt;/span&gt; &lt;span class="p"&gt;-=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;level&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hp&lt;/span&gt; &lt;span class="p"&gt;-=&lt;/span&gt; &lt;span class="n"&gt;level&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;span class="c1"&gt;// Subclases para tipos de pokemon específicos&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FirePokemon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;level&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Pokemon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;level&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hp&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;WaterPokemon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;level&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Pokemon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;level&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En este ejemplo, la clase Pokemon no está abierta a extensiones porque no puedes añadir nuevos tipos de ataque a un Pokemon sin modificar el método de &lt;strong&gt;attack&lt;/strong&gt;. Para añadir un nuevo tipo de ataque, tendrías que modificar el método para tener en cuenta el nuevo tipo de ataque, lo que provocaría cambiar todas las llamadas a dicho métrodo y obviamente viola OCR. &lt;/p&gt;

&lt;p&gt;En su lugar, podrías seguir OCR creando una nueva clase Ataque que tenga un atributo &lt;strong&gt;attackType&lt;/strong&gt; y un método &lt;strong&gt;calculateDamage&lt;/strong&gt; que reciba un objeto Pokemon y devuelva la cantidad de daño a infligir. Luego puedes extender la clase Ataque para crear tipos de ataque específicos como AtaqueFuego y AtaqueAgua.&lt;/p&gt;

&lt;p&gt;La clase Pokemon puede entonces tener una lista de objetos Ataque y un nuevo método &lt;strong&gt;use_attack&lt;/strong&gt; que selecciona un ataque de la lista y lo usa para atacar a otro Pokemon. De esta manera, puedes añadir nuevos tipos de ataque al juego sin modificar la clase Pokemon existente. Para ello usaríamos un método &lt;strong&gt;learnAttack&lt;/strong&gt;, que como su nombre indica simplemente añadiría ataques a la lista de dicho pokemon.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;
&lt;span class="k"&gt;open&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Pokemon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;level&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;hp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&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="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;attacks&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mutableListOf&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Attack&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()&lt;/span&gt;

    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;useAttack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;attack&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Attack&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Pokemon&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;damage&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;attack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;calculateDamage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hp&lt;/span&gt; &lt;span class="p"&gt;-=&lt;/span&gt; &lt;span class="n"&gt;damage&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;learnAttack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;attack&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Attack&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;attacks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;attack&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="c1"&gt;// Clase base para ataques&lt;/span&gt;
&lt;span class="k"&gt;open&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Attack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;attackType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;AttackType&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;open&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;calculateDamage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Pokemon&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&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="k"&gt;when&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;attackType&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;AttackType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;FIRE&lt;/span&gt; &lt;span class="p"&gt;-&amp;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="n"&gt;target&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nc"&gt;WaterPokemon&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;level&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;level&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="nc"&gt;AttackType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;WATER&lt;/span&gt; &lt;span class="p"&gt;-&amp;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="n"&gt;target&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nc"&gt;FirePokemon&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;level&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;level&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;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FireAttack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Attack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;AttackType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;FIRE&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;WaterAttack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Attack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;AttackType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;WATER&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;FirePokemon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;level&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Pokemon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;level&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hp&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;WaterPokemon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;level&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Pokemon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;level&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AttackType&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;FIRE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;WATER&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En este ejemplo, la clase Pokemon está abierta a extensiones (puedes añadir nuevos ataques a un Pokemon usando el método learnAttack), pero cerrada a modificaciones (no necesitas modificar la clase Pokemon para añadir nuevos tipos de ataque). En su lugar, puedes crear nuevos tipos de ataque extendiendo la clase Ataque y sobreescribiendo el método &lt;strong&gt;calculateDamage&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>solid</category>
      <category>cleanarchitecture</category>
      <category>cleancode</category>
      <category>ocr</category>
    </item>
    <item>
      <title>Principios SOLID II: Principio de responsabilidad única</title>
      <dc:creator>Josa Vicente</dc:creator>
      <pubDate>Wed, 05 Apr 2023 22:00:00 +0000</pubDate>
      <link>https://forem.com/josavicente/principios-solid-ii-principio-de-responsabilidad-unica-1he5</link>
      <guid>https://forem.com/josavicente/principios-solid-ii-principio-de-responsabilidad-unica-1he5</guid>
      <description>&lt;p&gt;Seguimos con SOLID, en esta ocasión la &lt;strong&gt;S&lt;/strong&gt; que corresponde al principio de responsabilidad única. Es posiblemente el más sencillo de identificar y también uno de los más sencillos de violar. Viene a decirnos que cada clase debe tener una única responsabilidad y que debe estar encapsulada en dicha clase. Por tanto cada clase debe tener un propósito específico que debemos identificar y no ser como una navaja suiza multifunción. Aquí el naming es importante para ser específicos.&lt;/p&gt;

&lt;p&gt;Me gusta especialmente porque hace el código fácilmente legible y entendible. Cualquiera que venga a revisar un código que cumple SRP, será capaz de identificar y entender rápidamente su objetivo.&lt;/p&gt;

&lt;h4&gt;
  
  
  Una clase = un concepto = una responsabilidad
&lt;/h4&gt;

&lt;p&gt;Veamos un ejemplo en Kotlin, tenemos esta clase inspirada en Pokemon:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Pokemon&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;level&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;

    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;attack&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// realiza un ataque&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;evolve&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// evoluciona el Pokemon&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;calculateExperience&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// calcula la experiencia del Pokemon&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 este ejemplo, la clase Pokemon tiene tres responsabilidades: atacar, evolucionar y calcular la experiencia. Por lo tanto estamos violando SRP. Cada tarea debería realizarse por una clase distinta. Lo correcto sería:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Pokemon&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;level&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;

    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;attack&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// realiza un ataque&lt;/span&gt;
    &lt;span class="p"&gt;}&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;Evolution&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;evolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pokemon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Pokemon&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// evoluciona el Pokemon&lt;/span&gt;
    &lt;span class="p"&gt;}&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;ExperienceCalculator&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;calculateExperience&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pokemon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Pokemon&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// calcula la experiencia del Pokemon&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;Podría haber hecho el típico ejemplo de la impresión o la BBDD, pero ilustrarlo con este ejemplo me ha parecido más divertido. Quizá semánticamente o el significado de negocio no sea tan directo, pero es mi blog, es mi ejemplo.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Aplicar SRP implica ser muy preciso con los nombres. Esto es especialmente importante, ya que según el tamaño del proyecto. la granularidad puede ser elevada y dificultar la navegación en el mismo. Cuanto más descriptiva y clara sea una clase por su nombre, más fácil nos será ubicarnos dentro del código. &lt;/p&gt;

&lt;p&gt;La principal pega que se le achaca a SRP es que aunque facilita el mantenimiento del código, perjudica, sobretodo en un proyecto grande, por la complejidad de la estructura de clases y el número de las mismas. En mi opinión, las ventajas a medio largo plazo compensan esto. Por muy grande que sea la base de código, será mucho más complejo hacer cambios si hay que tocar en muchas clases por una mala arquitectura. Sin embargo, quizá por volumen pueda llevar más tiempo entender la estructura, pero una vez entendida, el cambio será en un solo lugar.&lt;/p&gt;

&lt;p&gt;A continuación las principales ventajas que aporta SRP: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Facilita el mantenimiento y la actualización del código: Al tener cada clase una única responsabilidad, es más fácil localizar y modificar el código si es necesario.&lt;/li&gt;
&lt;li&gt;Mejora la legibilidad del código: Al tener cada clase un propósito específico, es más fácil entender su función y cómo se relaciona con el resto del código.&lt;/li&gt;
&lt;li&gt;Facilita la reutilización del código: Al tener cada clase una responsabilidad específica, es más fácil utilizar esa clase en diferentes partes del proyecto sin tener que modificarla.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Algunos inconvenientes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Puede aumentar la complejidad del proyecto: Al tener que dividir las responsabilidades en varias clases diferentes, puede resultar en una estructura más compleja y difícil de entender.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Puede requerir más tiempo de desarrollo: Al tener que crear más clases y establecer relaciones entre ellas, puede requerir más tiempo de desarrollo.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Como en todo en desarrollo, esto son principios, no leyes, obviamente depende del proyecto/product y del equipo establecer cuando tiene sentido hacer un trade off.&lt;/p&gt;

</description>
      <category>solid</category>
      <category>cleancode</category>
      <category>cleanarchitecture</category>
      <category>srp</category>
    </item>
    <item>
      <title>Principios SOLID I: Primero, no seas STUPID</title>
      <dc:creator>Josa Vicente</dc:creator>
      <pubDate>Wed, 05 Apr 2023 08:00:00 +0000</pubDate>
      <link>https://forem.com/josavicente/principios-solid-i-primero-no-seas-stupid-gbk</link>
      <guid>https://forem.com/josavicente/principios-solid-i-primero-no-seas-stupid-gbk</guid>
      <description>&lt;p&gt;Esta es la primera de una serie de entradas sobre los principios SOLID. Mi idea es hacer una entrada por principio &lt;br&gt;
pero quería comenzar precisamente con sus antagonistas. La mayoría del tiempo trabajamos con código legado. En un &lt;br&gt;
mundo ideal, lo haríamos todo desacoplado, mantenible y testable. Pero tristemente en muchos proyectos, &lt;br&gt;
te encuentras el gran marrón del código legado.&lt;/p&gt;

&lt;p&gt;He tenido que "remontar" ya más de tres veces grandes bases de código legado. En todas esas ocasiones, cuando tienes &lt;br&gt;
que rehacer o refactorizar algo, los grandes aliados son precisamente todo lo contrario a SOLID, conocerlos &lt;br&gt;
bien y por tanto detectarlos rápidamente.&lt;/p&gt;

&lt;p&gt;Es por eso, que si he de empezar a hablar de los principios SOLID, casi mejor empezar por precisamente por lo &lt;br&gt;
contrario, ya que con toda probabilidad, en muchos proyectos te encuentres precisamente con lo contrario. Empecemos.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Antes un pequeño &lt;strong&gt;disclaimer&lt;/strong&gt;. Los principios SOLID así como los patrones de diseño, son opciones que tenemos para solucionar &lt;br&gt;
problemas. En software casi todo es un trade off, lo que ganas por un lado lo puedes perder por otro. Por tanto, &lt;br&gt;
nada es inamovible y siempre debemos tomar las decisiones que mejor encajen con nuestra situación, es más, &lt;br&gt;
esas decisiones cambiarán con el tiempo casi con total probabilidad.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  STUPID
&lt;/h2&gt;
&lt;h3&gt;
  
  
  1. Singleton
&lt;/h3&gt;

&lt;p&gt;Patrón de diseño singleton, es decir, restringir la instanciación de una clase a una única instancia. El problema en si no &lt;br&gt;
es el patrón, el problema es su mal uso. &lt;/p&gt;

&lt;p&gt;Ejemplo en Kotlin:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;object&lt;/span&gt; &lt;span class="nc"&gt;Cache&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;clearCache&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
        &lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;saveOnCache&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
        &lt;span class="o"&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;Ejemplos típicos serían el de caché o BBDD. Tendriamos nuestra clase Cache, con sus métodos estáticos que estarían siendo llamados &lt;br&gt;
por todas partes en nuestro código. Teniendo el singleton dejamos de inyectar dependencias en nuestras clases lo que: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Te fastidia el testing al depender de un estado global&lt;/li&gt;
&lt;li&gt;Si nuestras clases dependen del objeto singleton, ocultan sus dependencias.&lt;/li&gt;
&lt;li&gt;Todo nuestro sistema se encuentra acoplado al objeto/s singleton.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Casi siempre puedes optar por otra opción antes que el Singleton.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Tight Coupling - Código fuertemente acoplado
&lt;/h3&gt;

&lt;p&gt;Relacionado con el anterior, consecuencia de utilizar singleton. En el ejemplo anterior, imagínate que queremos modificar la cabecera &lt;br&gt;
de alguno de los métodos estáticos. Tendríamos que modificar todas y cada una de las llamadas que hagamos a estos en todo nuestro código. Claramente estamos&lt;br&gt;
acoplados a como sea la implementación de la clase.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Untestability - Código no testable
&lt;/h3&gt;

&lt;p&gt;En muchos de los proyectos los tests brillan por su ausencia, sobretodo en el mundo de la consultoría, donde se considera que los tests no son parte del desarrollo&lt;br&gt;
y por tanto no se contempla dedicarles tiempo. Sin embargo, si pensamos en entornos con CD/CI por bandera, por poner un ejemplo claro, son imprescindibles para &lt;br&gt;
garantizar que no se rompe el ciclo.&lt;/p&gt;

&lt;p&gt;Tu código debe ser fácilmente testable. Es más, si tu código es difícil de testar, claramente tienes un problema. Lo que esa dificultad para testar te dice es que tu código&lt;br&gt;
no es mantenible y probablemente esté sumamente acoplado. Unos buenos tests te permitirán refactorizar sin peligro.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Premature Optimization
&lt;/h3&gt;

&lt;p&gt;Básicamente, no te &lt;strong&gt;flipes&lt;/strong&gt;. Los desarrolladores tendemos a fliparnos y complicarnos la vida. Nos adelantamos a lo que pueda pasar y muchas veces, eso, nunca pasa.&lt;br&gt;
Una optimización prematura lleva a costes innecesarios tanto en tiempo como económicos. Primero, valida tu hipótesis, luego ya montarás la BBDD más actual o la UI &lt;br&gt;
con el framework de moda.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Indescriptive naming
&lt;/h3&gt;

&lt;p&gt;Poco que decir, básicamente pon nombres que tu yo del futuro sea capaz de entender de un vistazo para que sirven. Por favor, no sigas esas tendencias de nombres crípticos &lt;br&gt;
o varibales de una sola letra. Eso es para señoros con riñonera que huelen fuerte.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Duplication
&lt;/h3&gt;

&lt;p&gt;No dupliques código. Si duplicas código te vas a tener que patear toda la base de código para corregir cualquier pequeño error. A estas alturas diría que es obvio, pero el ser humano&lt;br&gt;
es sorprendende para mal casi siempre.&lt;/p&gt;

</description>
      <category>bestpractices</category>
      <category>solid</category>
      <category>architecture</category>
      <category>cleancode</category>
    </item>
    <item>
      <title>Radical Candor III: Escucha más, habla menos.</title>
      <dc:creator>Josa Vicente</dc:creator>
      <pubDate>Tue, 04 Apr 2023 08:00:00 +0000</pubDate>
      <link>https://forem.com/josavicente/radical-candor-iii-escucha-mas-habla-menos-f7i</link>
      <guid>https://forem.com/josavicente/radical-candor-iii-escucha-mas-habla-menos-f7i</guid>
      <description>&lt;p&gt;Te estarás preguntando porque la imagen de cabecera es la de Jony Ive, el que fue el jefe de diseño de Apple durante 27 años, cuando el post es sobre el contenido de Radical Candor.&lt;br&gt;
Jony en una ocasión dijo:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Give the quiet ones a voice&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Es decir, da voz a los silenciosos. Esta frase resume a la perfección la idea del post y es el punto de partida de cara al último post sobre Radical Candor, &lt;strong&gt;la rueda de Get Stuff Done&lt;/strong&gt;.&lt;br&gt;
Para que las cosas pasen, hay que escuchar. Hay distintas formas de escuchar y de fomentar esa cultura de escucha.&lt;/p&gt;

&lt;h3&gt;
  
  
  Quiet listening
&lt;/h3&gt;

&lt;p&gt;El hecho de estar callado y escuchar, acaba provocando en el interlocutor la necesidad de llenar ese silencio. Esto lleva a obtener más información de la que se podría obtener con una pregunta directa. &lt;br&gt;
Es una forma de escuchar que se basa en la empatía y en la capacidad de ponerse en el lugar del otro. No solo obtienes más información y por tanto conoces mejor a la persona y como ayudarla. &lt;br&gt;
También obtienes más feedback, cosas que igual no dirían. También fomentas que la otra persona comparta ideas que si fuera interrumpida no aportaría.&lt;/p&gt;

&lt;p&gt;Por otro lado, tiene algunas contras, como que la gente tiende usar tu nombre, para acabar yendo por el camino que ellos creen mejor, sin escuchar al resto y justificando que es lo&lt;br&gt;
que tu piensas. Tu silencio, acaba dejando que se salgan con la suya. Otra contra es que los silencios suelen provocar cierto malestar en algunas personas. En lugar de percibirse como una&lt;br&gt;
conversación sincera, se percibe como una conversación tensa o una trampa.&lt;/p&gt;

&lt;p&gt;Si tu forma de escucha es esta, tienes que tomar medidas para mitigar las contras. Especialmente tranquilizar a los que se sienten incómodos por tu estilo. &lt;br&gt;
No seas inescrutable. Para que los demás digan lo que piensan, a veces tienes que decir tú también lo que piensas.&lt;/p&gt;

&lt;p&gt;Un ejemplo de este tipo de líder es Tim Cook, el actual CEO de Apple.&lt;/p&gt;

&lt;h3&gt;
  
  
  Loud listening
&lt;/h3&gt;

&lt;p&gt;La forma opuesta, esta forma de escucha se basa establecer un punto de vista fuerte que provoque una reacción en los demás y les haga hablar. &lt;br&gt;
Se trata de retar al equipo a aportar sus ideas y sobretodo rebatir las expuestas. Obviamente, esto solo puede funcionar con personas que tengan mucha confianza. Esto normalmente no&lt;br&gt;
ocurre, en un equipo donde hay muchos tipos de perfiles, personas más seguras de si mismas, introvertidas, personas que acaban de incorporarse, etc. Todas ellas probablemente tengan un punto&lt;br&gt;
de vista diferente y/o mejor a un problema pero no se atreverán a hablar.&lt;/p&gt;

&lt;p&gt;Si este es el tipo de escucha con la que te identificas, tienes que generar un entorno de confianza y promover la participación de todos. Sea cual sea el tipo de perfil. Si cualquiera desafía las opiniones&lt;br&gt;
del jefe y es escuchado y valorado, aquellos con menos confianza acabarán aportando también. Por supuesto, debes ser capaz de asimilar las críticas porque este tipo de escucha busca el debate&lt;br&gt;
y precisamente lo que buscas es que todo el equipo se sienta suficientemente empoderado para aportar sus ideas, no importa el nivel de expertise o el cargo que tenga. Aquí todos son iguales, tú incluído.&lt;/p&gt;

&lt;p&gt;Un ejemplo de este tipo de líder es Steve Jobs, el fundador de Apple. Este comentario sobre Steve Jobs lo resume muy bien:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;He’s a lion. If he roars at you, you’d better roar back just as loudly — but only if you really are a lion, too. Otherwise, he’ll eat you for lunch.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8imS8m_p--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/josavicente/josavicente-dev/blob/main/src/assets/images/steve_jobs.jpg%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8imS8m_p--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/josavicente/josavicente-dev/blob/main/src/assets/images/steve_jobs.jpg%3Fraw%3Dtrue" alt="Steve Jobs" width="880" height="587"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Crea una cultura de escucha
&lt;/h3&gt;

&lt;p&gt;Hasta ahora hemos hablado de como escuchar desde tu posición de liderazgo. Pero aquí no acaba, hay que promover la escucha entre las personas del equipo.&lt;br&gt;
Se trata de establecer un sistema en el que se puedan aportar ideas y expresar quejas, pero que también permita abordarlas y resolverlas. No tienes porque ser tu, quien las lleve a cabo o las gestione.&lt;/p&gt;

&lt;p&gt;Este feedback debe ser contestado, el tiempo es limitado y por tanto, has de dejar claro que no todo se puede abordar. &lt;br&gt;
Pero debes asegurarte de abordar aquello que aporte un mayor impacto para todos. Aquellas que no se puedan abordar deben ser comunicadas &lt;br&gt;
y en la medida de lo posible bien clarificados los porques.&lt;/p&gt;

&lt;p&gt;Cuando esas ideas se lleven a cabo y generen un impacto, no solo debes reconocer la aportación, es muy valioso que muestres a esa persona y al &lt;br&gt;
equipo el impacto real que ha tenido. Esto fomentará que se sigan aportando ideas y que se siga escuchando las ideas de los demás, creando una cultura de escucha efectiva.&lt;/p&gt;

&lt;p&gt;Otro punto importante es saber gestionar las reuniones de forma adecuada, si siempre hablan los mismos, hay un problema, todos los miembros del equipo deben tener &lt;br&gt;
espacio y se debe incentivar la participación. Tu trabajo es, como dice Jony Ive, dar vos a los silenciosos.&lt;/p&gt;

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

&lt;p&gt;Una cultura que promueva que todo el mundo es escuchado y tiene las mismas oportunidades de aportar y generar impacta propicia las bases de un entorno&lt;br&gt;
de trabajo saludable y productivo, en el que se materializan resultados. Es un trabajo de todos, no solo tuyo como engineer manager. Pero si tú no fomentas la escucha, no se puede esperar que el resto lo haga.&lt;/p&gt;

</description>
      <category>management</category>
      <category>liderazgo</category>
      <category>feedback</category>
      <category>growt</category>
    </item>
    <item>
      <title>Radical Candor II: Rockstars vs. Superstars</title>
      <dc:creator>Josa Vicente</dc:creator>
      <pubDate>Sun, 02 Apr 2023 22:00:00 +0000</pubDate>
      <link>https://forem.com/josavicente/radical-candor-ii-rockstars-vs-superstars-2nkj</link>
      <guid>https://forem.com/josavicente/radical-candor-ii-rockstars-vs-superstars-2nkj</guid>
      <description>&lt;p&gt;Trabajamos en un sector con una alta demanda de talento. Sabemos que si no damos a las personas del equipo lo que necesitan según el momento vital en el que se encuentran, &lt;br&gt;
lo tendrán muy fácil para encontrar otro lugar donde desarrollar su talento y que encaje con sus necesidades. Debemos ser conscientes de que la gente no se queda en &lt;br&gt;
un lugar solo porque le gusta el trabajo, sino porque encaja con sus necesidades personales. Estas necesiades pueden ser económicas, de crecimiento, autonomía, etc.&lt;/p&gt;

&lt;p&gt;En el libro Radical Candor, en lugar de pensar en la personas según su performance, se habla de crecimiento. Utilizando una tabla de crecimiento, se puede ver como cada persona &lt;br&gt;
encaja en el equipo según su momentum de crecimiento. Un equipo debe estar balanceado, sus perfiles deben ser un engranaje perfecto, no únicamente a nivel técnico, sino también&lt;br&gt;
a nivel personal. Si no hay balance, el equipo no funcionará. Y no solo eso, las personas acabaran frustrándose y buscando otro lugar que les encaje mejor.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--B10wGDMv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/josavicente/josavicente-dev/blob/main/src/assets/images/steep_growth_trajectory.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--B10wGDMv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/josavicente/josavicente-dev/blob/main/src/assets/images/steep_growth_trajectory.png%3Fraw%3Dtrue" alt="Steep Growth Trajhectory" width="880" height="595"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Los miembros de un equipo se pueden encontrar en distintas fases de crecimiento, a veces están en modo crecimiento, otras veces busacna estabilidad y en algunas ocasiones ambas cosas. &lt;br&gt;
Pero los dos perfiles que van a mantener el equipo unido y hacerlo funcionar como una maquinaria perfecta son:&lt;/p&gt;
&lt;h3&gt;
  
  
  Rockstars
&lt;/h3&gt;

&lt;p&gt;Estos perfiles son sólidos, tienen unas skills técnicas potentes, han encontrado su sitio y están en total harmonía con su rol actual. &lt;br&gt;
No buscan el siguiente step en su carrera. Estan cómodos como están y en ese momento de su carrera no quieren más. Es importante que los mantengamos en el equipo,&lt;br&gt;
ya que son los que van a generar crecimiento en el equipo compartiendo el suyo y mentorizando. El error&lt;br&gt;
más repetido con este tipo de perfil es promociopnarles a un puesto que no desean y para el que además no están preparados. &lt;/p&gt;

&lt;p&gt;Por desgracia en nuestro sector es común recompensar a los mejores desarrolladores con puestos de management o liderazgo para los que no están preparados y además ni siquiera quieren.&lt;br&gt;
Lo he visto muchas veces, lo he vivido como miembro de un equipo, son excelentes técnicos que ni quieren ni les gusta gestionar y liderar equipos porque eso les aparta de lo que realmente les apasiona, actividades técnicas. &lt;br&gt;
Lo que suele ocurrir:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No ejercen su papel de liderazgo, siguen programando y por tanto su equipo se resiente, provocando una sangría de perfiles que se queman y se van.&lt;/li&gt;
&lt;li&gt;Tratan de ejercer ese papel de liderazgo y management, unas veces acertadamente y otras todo lo contrario. Provocando quemar al equipo y que se vayan. Y además acaban abandonando y buscando un puesto que les devuelva la felicidad.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tu labor como líder en un equipo en el que tengas uno o más rockstars es centrarte en ofrecerles reconocimiento tanto a nivel de equipo como económico. Es muy importante que balancees &lt;br&gt;
los aportes individuales vs colaborar en equipo, tienden a priorizar su propio trabajo sobre el éxito del equipo. Debes fomentar que compartan su conocimiento con el resto del equipo,&lt;br&gt;
que sean mentores y que se involucren en el crecimiento de los demás aportando su conocimiento y experiencia.&lt;/p&gt;

&lt;p&gt;Algunos tips:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No los promociones, es lo peor que podrías hacerles. Si no quieren ser managers, no lo hagas. Si lo haces, acabarás perdiendo a un excelente técnico y a un excelente miembro del equipo.&lt;/li&gt;
&lt;li&gt;No crees una obsesión por la promoción. No es el fin del mundo. La tendencia que el siguiente paso para un desarrollador experimentado es el management cada vez es menos común.&lt;/li&gt;
&lt;li&gt;Buenos bonus y Performance ratings. &lt;/li&gt;
&lt;li&gt;Reconocimiento público. El status de gurú es muy importante para ellos.&lt;/li&gt;
&lt;li&gt;Respeto. Por su trabajo, sus skills y lo que aportan al equipo.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Superstars
&lt;/h3&gt;

&lt;p&gt;En el otro lado tenemos a los Superstars. Son excelentes pero en modo turbo. Buscan el crecimiento constante, nuevos retos y oportunidades. Además lo que les motiva es &lt;br&gt;
que se les rete. No solo generan un gran trabajo, además ayudan a otros a mejorar. Priorizan el éxito del equipo por encima de sus contribuciones individuales. &lt;/p&gt;

&lt;p&gt;Tu labor como líder en un equipo en el que tengas uno o más superstars es centrarte en ofrecerles retos y oportunidades de crecimiento. Son los que verdaderamente impulsan el éxito del equipo &lt;br&gt;
como un todo. Son los que fomentan la comunicación y colaboración en el equipo, lo que lleva a mejores resultados y a un mejor ambiente de trabajo. Crean un sentido de propósito compartido hacia la&lt;br&gt;
misión y visión de la compañía y del equipo.&lt;/p&gt;

&lt;p&gt;Tu labor como líder en un equipo con Superstars es ofrecerles retos y oportunidades de crecimiento. &lt;/p&gt;

&lt;p&gt;Algunos tips:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Retos&lt;/li&gt;
&lt;li&gt;No los frenes, no les pongas límites. Siempre hay más por hacer.&lt;/li&gt;
&lt;li&gt;Define un plan de crecimiento para ellos. No lo dejes al azar.&lt;/li&gt;
&lt;li&gt;Mentorizalos o asignales un mentor que les guíe en su crecimiento.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Encuentra el balance
&lt;/h3&gt;

&lt;p&gt;El objetivo es encontrar el balance entre estos dos perfiles. Si tienes un equipo con muchos rockstars, el equipo se estancará. &lt;br&gt;
Si tienes un equipo con muchos superstars, el equipo se desintegrará.&lt;/p&gt;

&lt;p&gt;Las personas tenemos momentos vitales distintos la que hoy es un rockstar, quizá mañana esté en fase de crecimiento y se convierta en un superstar. Como líder debes estar atento a los cambios &lt;br&gt;
ya que tu rol requiere adaptabilidad. Lo que les has de ofrecer irá cambiando según el momento vital de cada persona. &lt;br&gt;
Por ejemplo, yo mismo he pasado por ambas etapas varias veces, no voy a denominarme ni una cosa ni la otra, pero he pasado por fases en las que quería crecer y otras en las que quería estabilidad.&lt;/p&gt;
&lt;h3&gt;
  
  
  Conclusión
&lt;/h3&gt;

&lt;p&gt;Como líderes debemos ser flexibles y adaptarnos a las necesidades de cada persona. No podemos asumir que todos queremos lo mismo. Y mucho menos pensar que siempre a lo largo de nuestra carrera&lt;br&gt;
buscamos lo mismo. Tu trabajo es identificar cada perfil, entender que es lo que necesitan y dárselo o encontrar las herramientas para dárselo, generando así una cultura positiva de equipo. Con ello&lt;br&gt;
lograrás que tu equipo sea más productivo, más feliz y más comprometido.&lt;/p&gt;

&lt;p&gt;Os dejo la charla de Kim Scott por si la queréis ver:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/3oChxm4eUbM"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>management</category>
      <category>liderazgo</category>
      <category>feedback</category>
      <category>crecimiento</category>
    </item>
    <item>
      <title>Radical Candor: framework</title>
      <dc:creator>Josa Vicente</dc:creator>
      <pubDate>Sun, 02 Apr 2023 10:55:43 +0000</pubDate>
      <link>https://forem.com/josavicente/radical-candor-framework-41c6</link>
      <guid>https://forem.com/josavicente/radical-candor-framework-41c6</guid>
      <description>&lt;p&gt;Radical Candor es un concepto creado por Kim Scott. Yo lo conocí a través de una charla que realizó y que hará un año vi por primera vez. De ahí, me hice con el libro y recientemente me lo he leído. Me ha gustado tanto que no solo lo recomiendo, sino que he decidido hacer varios posts sobre el mismo.&lt;/p&gt;

&lt;p&gt;En esta primera entrada voy a hablar sobre el framework en si. El libro se divide en dos partes. En la primera, Kim Scott explica el concepto de Radical Candor, como focalizarse en el crecimiento del equipo y que las cosas se hagan.  En la segunda, nos da consejos para aplicar todo lo explicado en la primera parte en tu día a día.&lt;/p&gt;

&lt;p&gt;El framework se basa en una disposición en cuadrantes. Algo que debemos tener en cuenta es que este cuadrante no es una forma de etiquetar a las personas, sino que es una brújula o guía para dar y recibir feedback. El objetivo como managers debemos precuparnos por las personas de forma sincera y honesta. Y por otro lado que seamos directos, aunque sea duro, para ayudar a la persona a mejorar.&lt;/p&gt;

&lt;p&gt;Estos 4 cuadrantes tienen los siguientes nombres:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--s7PVTUF_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/josavicente/josavicente-dev/blob/main/src/assets/images/radical_candor_quadrant.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--s7PVTUF_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/josavicente/josavicente-dev/blob/main/src/assets/images/radical_candor_quadrant.png%3Fraw%3Dtrue" alt="Radical Candor" width="880" height="744"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Radical Candor
&lt;/h3&gt;

&lt;p&gt;Se trata de demostrar que te importa personalmente, tanto como para dar una opinión sincera y directa para hacer challenge a la persona. Es ser honesto, cercano y directo. Es el tipo de feedback que tiene una utilidad para el que lo recibe e incluso para el que lo da. Es el tipo de feedback que se debe dar en el día a día. Si dejamos pasar la oportunidad, estamos perdiendo una oportunidad de crecimiento para el que lo recibe y para nosotros mismos. Y es que, si no lo hacemos, no estamos siendo honestos con nosotros mismos.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ruinous Empathy
&lt;/h3&gt;

&lt;p&gt;Es lo que ocurre cundo quieres evitar cualquier sentimiento a corto plazo de alguien, ya sea positivo o negativo, por tanto, no comunicas lo que piensas. Es un feedback no sincero, sin utilidad para quien lo recibe. Si, te estás preocupando por el bienestar de la persona, pero no estás siendo honesto con ella y no la estás desafiando directamente para mejorar. Por tanto, es un feedback que: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Elogios que no son suficientemente específicos para ayudar a la persona a entender lo que ha hecho bien.&lt;/li&gt;
&lt;li&gt;Críticas suavizadas, poco claras que no ayudan a la persona a entender lo que ha hecho mal.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Para ejemplificarlo podrías tomar la situación, que a todos nos ha pasado, en la que estamos comiendo con alguien y tras acabar, tiene los dientes manchados con algún trozo de comida. En lugar de avisarle, no dices nada. Lo que provoca que pase toda la tarde con los dientes manchados exponiéndose a que le digan algo.&lt;/p&gt;

&lt;p&gt;De esta manera, por no ser directo, no estás dando a la persona la oportunidad de mejorar.&lt;/p&gt;

&lt;h3&gt;
  
  
  Obnoxious Aggressiveness
&lt;/h3&gt;

&lt;p&gt;Se podría traducir como agresión odiosa, también llamada honestidad brutal. Aquí estás desafiando a la persona, pero no te importa personalmente. Los elogios no parecen sinceros y las críticas son agresivas, no se hacen con amabilidad. Es decir, no se hace con el objetivo de ayudar a la persona a mejorar, sino con el objetivo de hacerle sentir mal. El tipo de personas que actuan de esta manera, usan la culpabilidad que generan en quien recibe el feedback, como motor para la mejora. Suele confundirse con Radical Candor. &lt;/p&gt;

&lt;h3&gt;
  
  
  Manipulative Insincerity
&lt;/h3&gt;

&lt;p&gt;Aquí ni te preocupas ni desafias a la persona. Puede ser un elogio inespecífico o una crítica vaga. Es una estrategia manipuladora con el objetivo de conseguir algo, ya sea una ventaja estratégica o caer bien a la gente. Con este comportamiento me he topado varias veces, es traicionero, político y pasivo-agresivo. Suele darse en ambientes de trabajo tóxico. Si lo detectas huye.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Radical Candor no es una excusa para ser un gilipollas y tratar mal a tu equipo. Si actuas como un gilipollas, seguirás siendo un gilipollas. Radical Candor se centra en preocuparte de forma honesta y sincera por tu equipo. A la vez que desafías a cada persona de tu equipo para que mejore y desarrolle todo su potencial.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Os dejo la charla de Kim Scott por si la queréis ver.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/yj9GLeNCgm4"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>management</category>
      <category>liderazgo</category>
      <category>feedback</category>
      <category>cultura</category>
    </item>
    <item>
      <title>He vidido un entorno toxico y he sobrevivido. Tú también puedes.</title>
      <dc:creator>Josa Vicente</dc:creator>
      <pubDate>Mon, 05 Dec 2022 14:42:53 +0000</pubDate>
      <link>https://forem.com/josavicente/he-vidido-un-entorno-toxico-y-he-sobrevivido-tu-tambien-puedes-4i4l</link>
      <guid>https://forem.com/josavicente/he-vidido-un-entorno-toxico-y-he-sobrevivido-tu-tambien-puedes-4i4l</guid>
      <description>&lt;p&gt;Lo primero que quiero decir y quiero que sirva de &lt;strong&gt;disclaimer&lt;/strong&gt; antes de que nadie se sienta ofendido es que un ambiente tóxico &lt;br&gt;
puede ser tan global o tan puntual como las circunstancias en una misma empresa. Una empresa no es tóxica, lo es la cultura que se promueve en ella o en parte de ella. Quizá promover&lt;br&gt;
no sería la palabra porque creo sinceramente que &lt;em&gt;casi todas&lt;/em&gt; estas situaciones son totalmente involuntarias, son fruto de la ignorancia de la gente y de como se promociona&lt;br&gt;
en según que organizaciones. Es más lo que para mi puede ser tóxico para otros es lo más normal e incluso lo abrazan. Especialmente gente joven que quiere subir y mejorar&lt;br&gt;
su salario de forma rápida.&lt;/p&gt;

&lt;p&gt;Hay muchas entradas sobre señales de ambientes tóxicos o nocivos, pero yo tan solo voy a enumerar los que he vivido y como han influido en mi carrera. Todo esto es un analisis en perspectiva, teniendo que cuando estás en esos ambientes la mayoría de veces no lo sabes e incluso llegas a participar en algunas de las malas prácticas que aquí enumero. De hecho, estoy seguro que no solo he sido víctima sino verdugo. Pero es cuando sales y vives otros ambientes o culturas, cuando te das cuenta de ello.&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Liderazgo negativo o inexistente ✔
&lt;/h4&gt;

&lt;p&gt;La mayoría de veces esto ocurre porque la persona que debería liderar es alguien técnico que se le premia con una promoción y con unas funciones para las que no está preparado. En mi opinión esto ocurre porque en muchos entornos hay un tope para los perfiles técnicos en su crecimiento que o se pasa a una carrera más de management o te estancas en crecimiento y sueldo.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. No respetar los horarios ✔
&lt;/h4&gt;

&lt;p&gt;Típicas peticiones irracionales al final de la jornada laboral que acaban en trabajo tirado a la basura. Malas miradas de compañeros por irte a tu hora y comentarios cuestionando tu profesionalidad. Trabajar en festivos sin compensación económica, regalándote simplemente flexibilidad de entrada y salida. Llamadas al teléfono personal fuera de horas y otras prácticas del estilo. &lt;/p&gt;

&lt;h4&gt;
  
  
  5. Camarillas, exclusión y comportamientos chismosos ✔
&lt;/h4&gt;

&lt;p&gt;Esto daría para una serie en Netflix.&lt;/p&gt;

&lt;h4&gt;
  
  
  4. Nulo feedback ✔
&lt;/h4&gt;

&lt;p&gt;Con decir que en los últimos 6 años no he recibido feedback, creo que lo digo todo. Demasiado bien he salido creo yo.&lt;/p&gt;

&lt;h4&gt;
  
  
  5. Sientes que no puedes crecer dentro de la empresa ✔
&lt;/h4&gt;

&lt;p&gt;Estacionamiento en el mismo rol a nivel de familia técnica en la empresa y económicamente. Pero asumiendo todo lo que se espera del siguiente rol para ti.&lt;/p&gt;

&lt;h4&gt;
  
  
  6. Mala comunicación ✔
&lt;/h4&gt;

&lt;p&gt;Me remito al punto del feedback, de vez en cuando un mensaje de Teams preguntando que tal el proyecto. Camuflado con hacerte creer que: "es que lo llevas tan bien que es como si no estuviera el proyecto"&lt;/p&gt;

&lt;h4&gt;
  
  
  7. Reprimir el crecimiento ✔
&lt;/h4&gt;

&lt;p&gt;Excusas vagas, patada adelante para las promociones. Esto puede ser en la forma de no poder cambiar de proyecto y/o tecnología usando argumentos tóxicos camuflados con elogios. Como ejemplo, elogiar lo especializado que estás en X, a la vez que hacerte sentir que o haces esto o no eres capaz de otra cosa.&lt;/p&gt;

&lt;h4&gt;
  
  
  8. Equilibrio entre la vida laboral y la personal ✔
&lt;/h4&gt;

&lt;p&gt;He de decir que en este punto, a nivel horario y adaptabilidad a temas parentales, no tuve problemas. Pero el hecho de ser padre presente en casa me ha cerrado muchas puertas. Si yo que soy hombre blanco hetero normativo he sufrido este tipo de mobbing, no quiero ni pensar lo mal que se trata en muchos entornos y como se cortan las carreras de las mujeres, primero por ser mujeres y segundo si además quieren ser madres. Desde mi actual trabajo intento poner mi granito de arena para que de alguna manera esto cambie.&lt;/p&gt;

&lt;h4&gt;
  
  
  9. Ansiedad, dolor corporal, insomnio ✔
&lt;/h4&gt;

&lt;p&gt;Creo que este punto habla por si solo.&lt;/p&gt;

&lt;p&gt;Y ahora un resumen de actitudes que he visto y/o sufrido: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Calentar la silla.&lt;/li&gt;
&lt;li&gt;Camarilla con el manager de turno.&lt;/li&gt;
&lt;li&gt;Apropiación del trabajo ajeno.&lt;/li&gt;
&lt;li&gt;Evaluación por horas extras realizadas (no pagadas) en lugar de por méritos.&lt;/li&gt;
&lt;li&gt;Ignorar tu presencia.&lt;/li&gt;
&lt;li&gt;No recibir ningún tipo de feedback.&lt;/li&gt;
&lt;li&gt;Comentarios hirientes frente al equipo.&lt;/li&gt;
&lt;li&gt;Machismo, esto obviamente lo he visto sobre gente de mi equipo y lo he peleado.&lt;/li&gt;
&lt;li&gt;Menospreciar los méritos por ser mujer joven.&lt;/li&gt;
&lt;li&gt;Menospreciar los méritos por tener gustos o físico considerados no normativos.&lt;/li&gt;
&lt;li&gt;Aprovecharse de la jerarquía.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>leadership</category>
      <category>toxicenvironment</category>
      <category>culture</category>
      <category>management</category>
    </item>
    <item>
      <title>La luz después del burnout</title>
      <dc:creator>Josa Vicente</dc:creator>
      <pubDate>Mon, 05 Dec 2022 14:39:11 +0000</pubDate>
      <link>https://forem.com/josavicente/la-luz-despues-del-burnout-57c2</link>
      <guid>https://forem.com/josavicente/la-luz-despues-del-burnout-57c2</guid>
      <description>&lt;p&gt;Después del bajonero artículo sobre mi experiencia personal pasando por un burnout bastante largo (aunque inicialmente no lo identifiqué así), en esta ocasión quiero contar mi experiencia posterior. Obviamente, todo depende de que, ya sea cambiando de trabajo o cambiando de proyecto en la misma empresa, te encuentres con un entorno que te ayude a superar lo que has dejado atrás.&lt;/p&gt;

&lt;p&gt;En mi caso personal, salí muy desmotivado y hundido de mi trabajo previo. El cambio, fue radical, salí de mi zona de confort, cambié de tipo de negocio, de tipo de entorno, de idioma, de forma de trabajar y para rematar en un equipo y proyecto que empezaba de 0. Ahora llevo un año y un mes y puedo hablar en perspectiva.&lt;/p&gt;

&lt;p&gt;Lo que marcó la diferencia desde el primer minuto fue el equipo. Los compañeros de proyecto confiando en mí. Mi manager, que en nuestro primer 1:1 me transmitió confianza en mis capacidades y en mi capacidad de llevar al equipo. Otra cosa que me ha ayudado infinito es el feedback, sobre todo el feedback de lo que tenía que mejorar. Pasando de ser alguien que quería arriesgarse 0 por miedo al fracaso, a querer aportar y generar el impacto que pueda en lo que hago y en los demás. &lt;strong&gt;Tela&lt;/strong&gt;, es que si no hubiese cambiado tanto, no estaríais leyendo esto.&lt;/p&gt;

&lt;p&gt;El equipo tan solo fue la punta del iceberg, tras unas semanas, lo que me hizo ganar seguridad y confianza fue el entorno global, la comunidad. Tengo la suerte de trabajar en un entorno en el que se anima a tener iniciativa y pensar out of the box. El hecho de tener trainings de distintas índoles cada viernes, poder elegir tu foco en la formación y las sinergias entre equipos hacen que abras la mente y salgas de la tecnología que conoces para abrazar, ya no solo nuevas tecnologías sino nuevas formas de trabajar. Aquí no se trata solo de tu proyecto, las relaciones con los demás proyectos son posibles y tu voz se escucha más allá de tu proyecto.&lt;/p&gt;

&lt;p&gt;No sé cuándo me hizo click, pero empecé a pensar a futuro, no al día a día. Tracé mi propio plan de cómo quiero que sea mi carrera en 2-3 años. Hace unos años ni me hubiese planteado los cursos que he hecho y que tengo en el pipeline para realizar. Ni se me hubiese pasado por la cabeza hacer katas en grupo, en seguida hubiese venido a mi mente que no era capaz, que se me juzgaría. Tenía tan metido en mi cabeza la competitividad y el "mi tesooooro", que no arriesgaba. Toda esta mentalidad al final es una suma de la personalidad introvertida que me caracteriza y los mensajes directos e indirectos que el entorno te lanza.&lt;/p&gt;

&lt;p&gt;Puedo decir que he aprendido más en este año que en los anteriores 6. He dedicado horas a aprender, estudiar y leer sobre múltiples temas, más de las que hubiese dedicado si hubiese seguido sin arriesgarme y aceptando lo que había. Toda esta fuerza viene por la comunidad que me rodea y también, como no de un síndrome del impostor que lleva acompañándome toda mi carrera y que lo único bueno que me aporta es querer seguir aprendiendo para mitigarlo.&lt;/p&gt;

&lt;p&gt;Viniendo del mundo consultoría y SAP, no voy a mentir. Muchos conceptos que leo en twitter nos los conozco o entiendo. He descubierto conceptos este año que no había escuchado o que si había escuchado había sido de pasada. Conceptos por los que ahora siento fascinación. Aunque ahora no puedo aplicarlos en mi día a día, ya que mi parte como IC es muy reducida en este momento, trato de aprender y mejorar por mi cuenta. Y ahora, no tengo miedo a no saber de algo, porque me rodea una comunidad que no juzga que no sepas de algo, todo lo contrario, te tiende la mano para ayudarte a aprenderlo. Y esto, no tiene precio.&lt;/p&gt;

&lt;p&gt;Así que para quien lo lea, gracias, porque probablemente hayas contribuido de alguna manera a que salga de un burnout y a que ahora me muera de curiosidad y de ganas de cumplir el plan que tengo para mí yo de dentro de unos años.&lt;/p&gt;

&lt;p&gt;Si algo puede resumir la etapa anterior y esta es: antes los domingos eran el peor día de la semana, ahora, son otro día más en el que pienso, que aprenderé la próxima semana.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>discuss</category>
    </item>
  </channel>
</rss>
