<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Victor Manuel Pinzon</title>
    <description>The latest articles on DEV Community by Victor Manuel Pinzon (@victorpinzon198).</description>
    <link>https://dev.to/victorpinzon198</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%2F579928%2F07e48749-4d69-4392-a7c3-1653bfc14ebe.jpg</url>
      <title>DEV Community: Victor Manuel Pinzon</title>
      <link>https://dev.to/victorpinzon198</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/victorpinzon198"/>
    <language>en</language>
    <item>
      <title>SOLID: Principio de Segregación de Interfaces</title>
      <dc:creator>Victor Manuel Pinzon</dc:creator>
      <pubDate>Mon, 24 May 2021 18:35:40 +0000</pubDate>
      <link>https://dev.to/victorpinzon198/solid-principio-de-segregacion-de-interfaces-1018</link>
      <guid>https://dev.to/victorpinzon198/solid-principio-de-segregacion-de-interfaces-1018</guid>
      <description>&lt;p&gt;Este principio fue desarrollado por Robert C. Martin mientras trabajaba como consultor en Xerox. Durante su periodo laboral, Martin estuvo a cargo del desarrollo de un nuevo sistema de gestión de impresiones, que permitía realizar diferentes acciones concurrentes en una nueva línea de impresoras.  &lt;/p&gt;

&lt;p&gt;A lo largo del desarrollo notó que pequeñas modificaciones al sistema terminaban en largos despliegues a producción, en muchos casos, en despliegues de módulos fuera del alcance de los cambios. El origen del problema era una interfaz sobrecargada con diferentes firmas de métodos que era utilizada en todas las acciones concurrentes que desempeñaba el sistema. Es decir, si Martin realizaba modificaciones en los módulos de impresión, los cambios se propagaban a los otros módulos, como el de faxeo, escaneo, etc. &lt;/p&gt;

&lt;p&gt;La solución dada por Robert C. Martin a este problema, es lo que hoy conocemos como el Principio de Segregación de Interfaces. &lt;/p&gt;

&lt;p&gt;La definición del principio es la siguiente:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Ningún cliente debe de ser forzado a depender de una interfaz que no utiliza.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;El principio es bien sencillo, ninguna clase debe de ser forzada a implementar métodos de interfaces que no utiliza. El objetivo, al igual que el principio de responsabilidad única, es limitar el alcance de los cambios a futuro.&lt;/p&gt;

&lt;h2&gt;
  
  
  Violación al Principio de Segregación de Interfaces
&lt;/h2&gt;

&lt;p&gt;Supongamos que eres el desarrollador a cargo del sistema de gestión de la nueva línea de impresoras multifuncionales de Xerox. Este nuevo sistema se desarrollará desde cero, por lo tanto estarás a cargo de los futuros desarrollos de las diferentes impresoras que se originen de la nueva línea de multifuncionales. &lt;/p&gt;

&lt;p&gt;Esta nueva línea cuenta con las siguientes capacidades:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Impresión.&lt;/li&gt;
&lt;li&gt;Escaneo.&lt;/li&gt;
&lt;li&gt;Faxeo.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;MultifuncionalLX&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="cm"&gt;/**
     * Método encargado de imprimir el siguiente documento 
     * activo en la cola de impresión.
     * 
     * @return      Retorna boolean indicando el resultado.
     */&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;imprimirDocumento&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

    &lt;span class="cm"&gt;/**
     * Método encargado de escanear el documento cargado
     * en la bandeja de escaneo.
     * 
     * @return      Retorna boolean indicando el resultado.
     */&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;escanearDocumento&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

    &lt;span class="cm"&gt;/**
     * Método encargado de faxear el documento cargado
     * en la bandeja de faxeo.
     * 
     * @return      Retorna boolean indicando el resultado.
     */&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;faxearDocumento&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para llevar a cabo el desarrollo se define la siguiente interfaz. La cual establece los métodos básicos que tendrán las multifuncionales de la nueva línea.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ImpresoraLX8578&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;MultifuncionalLX&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;imprimirDocumento&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;//Lógica de impresión de documentos&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;escanearDocumento&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;//Lógica de escaneo de documentos&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;faxearDocumento&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;//Lógica de faxeo de documentos&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Para facilitar la compresión del ejemplo, se omitió la implementación especifica de cada método.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Durante varios meses se lanzan diferentes versiones de la multifuncional, las cuales utilizan la misma interfaz para definir sus funcionalidades principales. &lt;/p&gt;

&lt;p&gt;Gracias a la aceptación de la nueva línea de impresoras. Gerencia, te solicita la integración de l sistema de gestión de impresiones a una nueva impresora económica, que será lanzada bajo la línea de impresoras que esta bajo tu responsabilidad. La diferencia es que esta nueva impresora no contará con la capacidad de enviar faxes, únicamente impresión y escaneo.&lt;/p&gt;

&lt;p&gt;Tomando en cuenta que esta nueva impresora pertenece a la misma línea que las impresoras anteriores y también es categorizada como multifuncional, decides utilizar la interfaz definida para dicha línea.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ImpresoraLX8590&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;MultifuncionalLX&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;imprimirDocumento&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;//Lógica de impresión de documentos&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;escanearDocumento&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;//Lógica de escaneo de documentos&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;faxearDocumento&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;UnsupportedOperationException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Impresora no cuenta con la capacidad de faxeo."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; 
    &lt;span class="o"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;En este punto es donde se da la violación al Principio de Segregación de Interfaces, debido a que la impresora &lt;strong&gt;ImpresoraLX8590&lt;/strong&gt;  es forzada a depender de métodos que no utiliza.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementación del Principio de Segregación de Interfaces
&lt;/h2&gt;

&lt;p&gt;La solución al ejemplo anterior, es la segregación de la interfaz que agrupa todos los métodos en diferentes interfaces especializadas. Por lo tanto, la interfaz &lt;strong&gt;MultifuncionalLX&lt;/strong&gt; se convertirá en las interfaces:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;MultifuncionalLXImpresion&lt;/li&gt;
&lt;li&gt;MultifuncionalLXEscaneo&lt;/li&gt;
&lt;li&gt;MultifuncionalLXFaxeo
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;MultifuncionalLXEscaneo&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="cm"&gt;/**
     * Método encargado de escanear el documento cargado
     * en la bandeja de escaneo.
     * 
     * @return      Retorna boolean indicando el resultado.
     */&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;escanearDocumento&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;MultifuncionalLXFaxeo&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="cm"&gt;/**
     * Método encargado de faxear el documento cargado
     * en la bandeja de faxeo.
     * 
     * @return      Retorna boolean indicando el resultado.
     */&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;faxearDocumento&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;MultifuncionalLXImpresion&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="cm"&gt;/**
     * Método encargado de imprimir el siguiente documento 
     * activo en la cola de impresión.
     * 
     * @return      Retorna boolean indicando el resultado.
     */&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;imprimirDocumento&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se modifican las clases de las impresoras anteriores para que utilice las interfaces especializadas.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ImpresoraLX8578&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;MultifuncionalLXEscaneo&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; 
        &lt;span class="nc"&gt;MultifuncionalLXFaxeo&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
        &lt;span class="nc"&gt;MultifuncionalLXImpresion&lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;imprimirDocumento&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;//Lógica de impresión de documentos&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;escanearDocumento&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;//Lógica de escaneo de documentos&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;faxearDocumento&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;//Lógica de faxeol de documentos&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Se define la clase &lt;strong&gt;ImpresoraLX8590&lt;/strong&gt; únicamente con las interfaces de escaneo e impresión.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ImpresoraLX8590&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;MultifuncionalLXEscaneo&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; 
        &lt;span class="nc"&gt;MultifuncionalLXImpresion&lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;imprimirDocumento&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;//Lógica de impresión de documentos&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;escanearDocumento&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;//Lógica de escaneo de documentos&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Las modificaciones realizadas permiten que el código se encuentre en cumplimiento con el Principio de Segregación de Interfaces.&lt;/p&gt;

&lt;h2&gt;
  
  
  Diferencia entre el Principio de Segregación de Interfaces y el Principio de Sustitución de Liskov
&lt;/h2&gt;

&lt;p&gt;Algunos desarrolladores pueden confundir estos dos principios SOLID. Sin embargo, ambos se enfocan en diferentes aspectos puntuales en el diseño de la programación orientada a objetos.&lt;/p&gt;

&lt;p&gt;El Principio de Sustitución de Liskov se enfoca en subtipos y herencia, se enfoca en que los subtipos de una clase cumplan con el contrato especificado en la clase abstracta. Por otro lado, el Principio de Segregación de Interfaces se enfoca en segregar interfaces grandes en interfaces especializadas, así las clases que implementen dichas interfaces no dependan de interfaces y métodos que no utilizan.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cuando utilizar el Principio de Segregación de Interfaces
&lt;/h2&gt;

&lt;p&gt;Este principio, al igual que el principio de responsabilidad única, es clave para limitar el alcance de los cambios futuros en el diseño de las aplicaciones. Sin embargo, es muy difícil detectar estas violaciones durante las primeras iteraciones de la solución. Lo mejor es permitir que la solución evolucione para poder identificar los puntos claves en donde se puede aplicar este principio.&lt;/p&gt;

&lt;p&gt;Si deseas ampliar tu conocimiento acerca del Principio de Segragación de Interfaces, puedes consultar el blog de &lt;a href="https://blog.cleancoder.com/uncle-bob/2020/10/18/Solid-Relevance.html"&gt;Robert C. Martin&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;En la próxima publicación discutiremos acerca del último principio SOLID, el Principio de Inversión de Dependencias.&lt;/p&gt;

</description>
      <category>oop</category>
      <category>spanish</category>
      <category>solid</category>
      <category>architecture</category>
    </item>
    <item>
      <title>SOLID: Principio de Sustitución de Liskov</title>
      <dc:creator>Victor Manuel Pinzon</dc:creator>
      <pubDate>Mon, 26 Apr 2021 18:21:16 +0000</pubDate>
      <link>https://dev.to/victorpinzon198/solid-principio-de-sustitucion-de-liskov-4hne</link>
      <guid>https://dev.to/victorpinzon198/solid-principio-de-sustitucion-de-liskov-4hne</guid>
      <description>&lt;p&gt;&lt;em&gt;Esta es una continuación a la serie de &lt;a href="https://dev.to/victorpinzon198/solid-principio-de-responsabilidad-unica-5ffo"&gt;principios SOLID&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;El principio de sustitución de Liskov es el principio más técnico de los cinco principios SOLID. Es el que más ayuda a escribir aplicaciones desacopladas, lo cual es elemental en el diseño de componentes reutilizables.&lt;/p&gt;

&lt;p&gt;El tercer principio SOLID fue definido por Barbara Liskov de la siguiente manera:&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;La definición dada por Liskov esta basada en el concepto de contrato e implementación definido por Bertrand Meyer, el cual establece los siguientes tres principios básicos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Un contrato y una implementación deben de definir de antemano una pre-condición, la cual es una condición que debe de ser garantizada siempre en la llamada de una rutina del contrato establecido.&lt;/li&gt;
&lt;li&gt;Un contrato y una implementación deben de definir de antemano una post-condición, la cual es una condición de salida de la rutina.&lt;/li&gt;
&lt;li&gt;Mantener una determinada propiedad, asumida a la entrada y garantizada a la salida.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;El concepto de contrato e implementación son los fundamentos de herencia y polimorfismo en los lenguajes de programación orientados a objetos.&lt;/p&gt;

&lt;p&gt;En 1996, Robert C. Martin redefinió el concepto dado por Liskov de la siguiente forma:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Funciones que usan punteros de referencia a clases base deben de poder usar objetos de clases derivadas sin saberlo.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;La redefinición dada por Bob Martin ayudó a simplificar el concepto y a su adopción por parte de los desarrolladores. &lt;/p&gt;

&lt;p&gt;Para facilitar la comprensión de este principio veamos el siguiente ejemplo donde una estructura de clases viola el principio de sustitución.&lt;/p&gt;

&lt;h2&gt;
  
  
  Violación del principio de sustitución de Liskov
&lt;/h2&gt;

&lt;p&gt;Como desarrollador de una entidad bancaria se te solicita implementar el sistema de manejo de cuentas bancarias. El cual, en la primer fase, se implementará la cuenta básica y la premium. La diferencia entre ambas es que las cuentas premium generan acumulación de puntos prefiero cada vez que se realiza un depósito. &lt;/p&gt;

&lt;p&gt;Para llevar a cabo este desarrollo, defines la siguiente clase abstracta:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;abstract&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CuentaBancaria&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="cm"&gt;/**
     * Método encargado de realizar los depositos monetarios.
     * @param monto         Monto a depositar.
     */&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;abstract&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;depositar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;monto&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="cm"&gt;/**
     * Método encargado de retirar el monto especificado.
     * @param monto         Monto a retirar.
     * @return              Retorna verdadero en casos exitosos,
     *                      falso en caso contrario.
     */&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;abstract&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;retirar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;monto&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La clase abstracta define la obligatoriedad en las clases derivadas de definir el funcionamiento de los métodos abstractos de depositar y retirar.&lt;/p&gt;

&lt;p&gt;Para el manejo de las cuentas bancarias básicas y premium, se definen las siguientes clases:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CuentaBancariaBasica&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;CuentaBancaria&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;saldo&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;depositar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;monto&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;saldo&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;monto&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;retirar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;monto&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;saldo&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;monto&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;saldo&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="n"&gt;monto&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="o"&gt;}&lt;/span&gt;

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

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CuentaBancariaPremium&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;CuentaBancaria&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;saldo&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;puntosPrefiero&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;depositar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;monto&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;saldo&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;monto&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;incrementarPuntosPrefiero&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;retirar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;monto&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
         &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;saldo&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;monto&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;saldo&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="n"&gt;monto&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
            &lt;span class="n"&gt;incrementarPuntosPrefiero&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;incrementarPuntosPrefiero&lt;/span&gt;&lt;span class="o"&gt;(){&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;puntosPrefiero&lt;/span&gt;&lt;span class="o"&gt;++;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Por favor, tomar en cuenta que las clases definidas en este ejemplo están muy lejanas a incluir todo lo necesario de una implementación real.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A las cuentas basicas y premium se les realiza un cobro administrativo anual de $25.00. Para implementar esta politica se implementa la clase de servicio de retiros.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.ArrayList&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.List&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ServicioRetiros&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="no"&gt;MONTO_GASTO_ADMON&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;25.00&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;cargarDebitarCuentas&lt;/span&gt;&lt;span class="o"&gt;(){&lt;/span&gt;

        &lt;span class="nc"&gt;CuentaBancaria&lt;/span&gt; &lt;span class="n"&gt;ctaBasica&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CuentaBancariaBasica&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;ctaBasica&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;depositar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;100.00&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="nc"&gt;CuentaBancaria&lt;/span&gt; &lt;span class="n"&gt;ctaPremium&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CuentaBancariaPremium&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;ctaPremium&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;depositar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;200.00&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;CuentaBancaria&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;cuentas&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="n"&gt;cuentas&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctaBasica&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;cuentas&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctaPremium&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;debitarGastosAdmon&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cuentas&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;debitarGastosAdmon&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;CuentaBancaria&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;cuentas&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;
        &lt;span class="n"&gt;cuentas&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;forEach&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cuenta&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;cuenta&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;retirar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ServicioRetiros&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;MONTO_GASTO_ADMON&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Una vez finalizada la implementación de las cuentas básicas y premium, se te solicita la implementación de las cuentas a largo plazo. Las características de este tipo de cuentas son las siguientes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Las cuentas bancarias de deposito a largo plazo están exentas de cobros administrativos.&lt;/li&gt;
&lt;li&gt;Las cuentas bancarias de deposito a largo plazo no permiten retiros manuales. Si un cliente desea retirar lo abonado a su cuenta, lo debe de realizar mediante una gestión diferente en las sucursales del banco.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Como desarrollador encargado del sistema de cuentas bancarias, decides utilizar la misma clase abstracta definida en los ejemplos anteriores.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CuentaLargoPlazo&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;CuentaBancaria&lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;saldo&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;depositar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;monto&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;saldo&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;monto&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;retirar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;monto&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;UnsupportedOperationException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"No permite la operación de debito"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;   
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En este punto es donde resalta la violación al principio de sustitución de Liskov, ya que las cuentas a largo plazo no deben de extender el funcionamiento de la operación retirar. Esto significa que si intentamos forzar la extensión de la clase debemos de dejar el método retirar como un método vacio o que lance una excepción de método no soportado. Además, se generaría un problema en el servicio de debito de gastos administrativos, ya que si por error se incluyera una cuenta a largo plazo se daría una excepción de ejecución.&lt;/p&gt;

&lt;p&gt;Se le podría dar la vuelta al error e incluir una condicional en el método de "debitarGastosAdmon" para que ignore a las cuentas a largo plazo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;debitarGastosAdmon&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;CuentaBancaria&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;cuentas&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;CuentaBancaria&lt;/span&gt; &lt;span class="n"&gt;cuenta&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;cuentas&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cuenta&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nc"&gt;CuentaLargoPlazo&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;else&lt;/span&gt;
                &lt;span class="n"&gt;cuenta&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;retirar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ServicioRetiros&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;MONTO_GASTO_ADMON&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sin embargo, la inclusión de la condicional viola el &lt;a href="https://dev.to/victorpinzon198/solid-principio-de-abierto-cerrado-2mjp"&gt;principio de abierto/cerrado&lt;/a&gt; debido a que cada vez que se incluya una cuenta bancaria con diferente funcionamiento, habrá que modificar el código para condicionarlo acorde a la clase.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementación del Principio de Sustitución de Liskov
&lt;/h2&gt;

&lt;p&gt;El problema integral del ejemplo anterior es que la cuenta bancaria a largo plazo no es una cuenta regular, al menos no del tipo que se definió en la clase abstracta. Existe una prueba de razonamiento inductivo que se puede utilizar en estos casos &lt;em&gt;"Si grazna como un pato, camina como un pato y se comporta como un pato, entonces, ¡seguramente es un pato!"&lt;/em&gt;. La prueba del pato es importante bajo el concepto del principio de sustitución de Liskov debido a que la cuenta bancaria a largo plazo, luce como una cuenta bancaria regular, pero no se comporta como una cuenta regular, ya que no permite retiros. Por lo que inferimos que las cuentas a largo plazo no son cuentas bancarias regulares.&lt;/p&gt;

&lt;p&gt;Para cumplir con el principio de sustitución de Liskov se deben de tomar en cuenta&lt;br&gt;
 las siguientes consideraciones:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Los tres tipos de cuentas permiten la acción de depósito.&lt;/li&gt;
&lt;li&gt;Únicamente se permite realizar retiros en cuentas bancarias básicas y premium. Esto significa que existen dos tipos de cuentas, las cuentas bancarias retirables y las no retirables.&lt;/li&gt;
&lt;li&gt;Se define una clase abstracta con el único método de depositar.&lt;/li&gt;
&lt;li&gt;Se definirá una segunda clase abstracta que extenderá el comportamiento de la primera clase abstracta e incluirá la acción de retirar.&lt;/li&gt;
&lt;li&gt;Las cuentas bancarias del tipo básico y premium serán del tipo de cuenta bancaria retirable. Mientras que las cuentas bancarias a largo plazo seran del tipo cuenta bancaria, la cual únicamente permite la acción de depósito.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Para llevar a cabo los cambios de estructura se define la clase abstracta CuentaBancaria, la cual es la clase básica para todas las cuentas y tiene un único método para realizar la acción de deposito.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;abstract&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CuentaBancaria&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="cm"&gt;/**
     * Método encargado de realizar los depositos monetarios.
     * @param monto         Monto a depositar.
     */&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;abstract&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;depositar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;monto&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se extiende el funcionamiento de la clase de CuentaBancaria para definir el comportamiento de las cuentas bancarias que permiten retiros. La clase CuentaBancariaRetirable es también una clase abstracta que define el método retirar.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;abstract&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CuentaBancariaRetirable&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;CuentaBancaria&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="cm"&gt;/**
     * Método encargado de retirar el monto especificado.
     * @param monto         Monto a retirar.
     * @return              Retorna verdadero en casos exitosos,
     *                      falso en caso contrario.
     */&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;abstract&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;retirar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;monto&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Las cuentas bancarias básicas y premium extenderán el uso de la clase de CuentaBancariaRetirable, la que a su vez extiende la clase CuentaBancaria. Esto permite que las clases de cuentas básicas y premium tengan las acciones de deposito y retiro.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CuentaBancariaBasica&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;CuentaBancariaRetirable&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;saldo&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;depositar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;monto&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;saldo&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;monto&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;retirar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;monto&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;saldo&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;monto&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;saldo&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="n"&gt;monto&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="o"&gt;}&lt;/span&gt;

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

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CuentaBancariaPremium&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;CuentaBancariaRetirable&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;saldo&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;puntosPrefiero&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;depositar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;monto&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;saldo&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;monto&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;incrementarPuntosPrefiero&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;retirar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;monto&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
         &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;saldo&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;monto&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;saldo&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="n"&gt;monto&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
            &lt;span class="n"&gt;incrementarPuntosPrefiero&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;incrementarPuntosPrefiero&lt;/span&gt;&lt;span class="o"&gt;(){&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;puntosPrefiero&lt;/span&gt;&lt;span class="o"&gt;++;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Debido a que las cuentas a largo plazo únicamente permiten depósitos, se extenderá el uso de la clase CuentaBancaria.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CuentaBancariaLargoPlazo&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;CuentaBancaria&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;saldo&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;depositar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;monto&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;saldo&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;monto&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;La clase encargada de proveer el servicio de retiros utilizará únicamente las clases que extiendan el funcionamiento de CuentaBancariaRetirable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.ArrayList&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.List&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ServicioRetiros&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="no"&gt;MONTO_GASTO_ADMON&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;25.00&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;cargarDebitarCuentas&lt;/span&gt;&lt;span class="o"&gt;(){&lt;/span&gt;

        &lt;span class="nc"&gt;CuentaBancariaRetirable&lt;/span&gt; &lt;span class="n"&gt;ctaBasica&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CuentaBancariaBasica&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;ctaBasica&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;depositar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;100.00&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="nc"&gt;CuentaBancariaRetirable&lt;/span&gt; &lt;span class="n"&gt;ctaPremium&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CuentaBancariaPremium&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;ctaPremium&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;depositar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;200.00&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;CuentaBancariaRetirable&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;cuentas&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="n"&gt;cuentas&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctaBasica&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;cuentas&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctaPremium&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;debitarGastosAdmon&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cuentas&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;debitarGastosAdmon&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;CuentaBancariaRetirable&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;cuentas&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;
        &lt;span class="n"&gt;cuentas&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;forEach&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cuenta&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;cuenta&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;retirar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ServicioRetiros&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;MONTO_GASTO_ADMON&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;El método encargado de debitar los gastos administrativos ahora recibe un listado de objetos que extienden el funcionamiento de la clase CuentaBancariaRetirable. Es decir, nosotros podemos sustituir los objetos de CuentaBancariaRetirable por cuentas básicas o premium, siempre y cuando estas extiendan el uso de la clase abstracta CuentaBancariaRetirable, pero no podemos hacer la sustitución por objetos que solo extienden la clase CuentaBancaria, tal como el caso de las cuentas a largo plazo.&lt;/p&gt;

&lt;p&gt;El diseño de la estructura de nuestras clases también refuerza los requerimientos funcionales dados por el cliente. Ya que las cuentas a largo plazo, al extender el funcionamiento de la clase CuentaBancaria permiten que únicamente se pueda realizar depositos en este tipo de cuentas.&lt;/p&gt;

&lt;h2&gt;
  
  
  Importancia del Principio de Sustitución de Liskov
&lt;/h2&gt;

&lt;p&gt;El principio de sustitución de Liskov nos permite identificar generalizaciones incorrectas realizadas durante las primeras fases del desarrollo. El principio de Liskov, al igual que el principio de inversión de dependencia, son fundamentos del concepto de inyección de dependencias, el cual es utilizado ampliamente en muchos frameworks actuales.&lt;/p&gt;

&lt;p&gt;Las violaciones al principio de Liskov son fáciles de detectar, como regla general puedes utilizar las siguientes pistas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Se está violando el principio de Liskov cuando se introducen condicionales acorde al tipo del objeto, tal como se mostró en el ejemplo del condicional instanceof.&lt;/li&gt;
&lt;li&gt;Una estructura de clases no se encuentra en cumplimiento con el principio si al extender el comportamiento de una clase abstracta se definen métodos vacíos o métodos que lancen excepciones por no tener implementación.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Si deseas ampliar tu conocimiento acerca del principio de sustitución de Liskov, puedes consultar el blog de &lt;a href="https://blog.cleancoder.com/uncle-bob/2020/10/18/Solid-Relevance.html"&gt;Robert C. Martin&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;En la próxima publicación discutiremos acerca del Principio de Segregación de Interfaces.&lt;/p&gt;

</description>
      <category>oop</category>
      <category>solid</category>
      <category>spanish</category>
      <category>architecture</category>
    </item>
    <item>
      <title>SOLID: Principio de Abierto/Cerrado</title>
      <dc:creator>Victor Manuel Pinzon</dc:creator>
      <pubDate>Thu, 08 Apr 2021 03:13:26 +0000</pubDate>
      <link>https://dev.to/victorpinzon198/solid-principio-de-abierto-cerrado-2mjp</link>
      <guid>https://dev.to/victorpinzon198/solid-principio-de-abierto-cerrado-2mjp</guid>
      <description>&lt;p&gt;&lt;em&gt;&lt;em&gt;Este articulo es una continuación a la publicación de &lt;a href="https://dev.to/victorpinzon198/solid-principio-de-responsabilidad-unica-5ffo"&gt;principios SOLID&lt;/a&gt;.&lt;/em&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;El segundo principio SOLID es probablemente el más importante de todos, pero el menos utilizado. La poca inclusión de este principio se ha debido a su débil y confusa definición.&lt;/p&gt;

&lt;p&gt;El principio de abierto/cerrado fue acuñado por Bertrand Meyer en su libro &lt;em&gt;&lt;a href="https://en.wikipedia.org/wiki/Object-Oriented_Software_Construction"&gt;Object Oriented Software Construction&lt;/a&gt;&lt;/em&gt;, quien lo definió de la siguiente manera:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Las entidades de software (clases, módulos, funciones, etc) deben de estar abierta para su extensión, pero cerradas para su modificación.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;La definición original por Meyer es ambigua y poco aplicable en la practica, lo que ocasionó que muchos desarrolladores de la época ignoraran la aplicación de dicho principio. Años despues, Bob Martin amplió la definición de la siguiente manera:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;El comportamiento de un sistema debería de ser capaz de ser extendido sin necesidad de modificar dicho sistema.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;La explicación dada por Bob Martin es más clara y es compatible con la arquitectura de Plugin, la cual estaba en su apogeo en esa época. Esta arquitectura indica que un sistema de software debería de ser construido con la capacidad de agregar plugins a ciertos componentes, sin que estos sepan los detalles de la implementación de los mismos. &lt;/p&gt;

&lt;p&gt;Por ejemplo, un sistema integrado de desarrollo (IDE) permite ampliar su funcionamiento mediante plugins, tales como: Lite Server, Remote SSH, etc., esto sin afectar el funcionamiento del mismo. El IDE permite agregar plugins siempre y cuando cada extensión siga las reglas definidas para su implementación. Es decir, el sistema se encuentra abierto para su extensión mediante plugins pero no para la modificación de las funciones centrales del IDE.&lt;/p&gt;

&lt;p&gt;Otro ejemplo del principio de abierto/cerrado son las librerías de software. Estas se desarrollan con el objetivo que sean utilizadas en diferentes contextos e implementadas en todos los casos posibles, es decir, las librerías por naturaleza deben de estar abiertas para su extensión. Sin embargo, un cambio en el core de la librería podría significar cambios en todos los puntos y contextos donde dicha librería ha sido utilizada, en otras palabras, las librerías por naturaleza deben de estar cerradas para modificaciones.&lt;/p&gt;

&lt;p&gt;Veamos un ejemplo a nivel de código. Actualmente laboras en una empresa de desarrollo de juegos de PC. Tu jefe, como parte del próximo proyecto, te solicita implementar una librería que permita el cálculo del área de rectángulos. Esta será útil para la maquetación de los personajes del juego. &lt;/p&gt;

&lt;p&gt;Para llevar a cabo esta tarea defines las siguientes clases:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Rectangulo&lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;altura&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Rectangulo&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;altura&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;base&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; 
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;altura&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;altura&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="cm"&gt;/*Getters / Setters*/&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La clase &lt;strong&gt;Rectangulo&lt;/strong&gt; almacena la base y altura de la figura geométrica.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CalculadorArea&lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="nf"&gt;calcularArea&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Rectangulo&lt;/span&gt; &lt;span class="n"&gt;rectangulo&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;rectangulo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getBase&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;rectangulo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getAltura&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;   
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La clase &lt;strong&gt;CalculadorArea&lt;/strong&gt; define el método encargado de calcular el área del rectángulo, el cual se realiza mediante la multiplicación de la base por la altura.&lt;/p&gt;

&lt;p&gt;El calculador de areas se utiliza de la siguiente forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.yourregulardeveloper.main&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;App&lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;

        &lt;span class="nc"&gt;CalculadorArea&lt;/span&gt; &lt;span class="n"&gt;calcArea&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CalculadorArea&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="nc"&gt;Rectangulo&lt;/span&gt; &lt;span class="n"&gt;rec1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Rectangulo&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;13.5&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="nc"&gt;Rectangulo&lt;/span&gt; &lt;span class="n"&gt;rec2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Rectangulo&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;7.89&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;9.85&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Calculo de rectangulo 1: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;calcArea&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;calcularArea&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rec1&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Calculo de rectangulo 2: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;calcArea&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;calcularArea&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rec2&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tu librería termina siendo un éxito y es utilizada en varios proyectos adicionales que está llevando a cabo la empresa. Meses después tu jefe te solicita que la librería también calcule el área de cuadrados. &lt;/p&gt;

&lt;p&gt;Al momento de empezar a diseñar tu implementación te das cuenta de dos factores:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;El cuadrado es un caso especial de rectángulo.&lt;/li&gt;
&lt;li&gt;El área del cuadrado se calcula de forma diferente al rectángulo tradicional. Está se calcula elevando el tamaño de sus lados al cuadrado.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Estos factores resaltan que el código de tu librería no cumple con el principio de abierto/cerrado. Por supuesto que podrías debatir que en la clase &lt;strong&gt;Rectangulo&lt;/strong&gt; se puede asignar el mismo valor para la base/altura y se obtendría el mismo funcionamiento para las figuras de tipo cuadrado ¿Pero qué sucede si en futuros requerimientos se solicita el cálculo del área de un circulo o de cualquier otra figura geométrica? &lt;/p&gt;

&lt;p&gt;La respuesta es la implementación del principio abierto/cerrado.&lt;/p&gt;

&lt;h2&gt;
  
  
  Aplicación del principio de abierto/cerrado
&lt;/h2&gt;

&lt;p&gt;El caso anterior nos ejemplifica los problemas que se pueden generar al momento de diseñar aplicaciones que no tomen en cuenta los cambios que se pueden dar en ciertos módulos. El objetivo principal del principio de abierto/cerrado es exactamente ese, diseñar soluciones que tomen en cuenta los cambios que se puedan dar en el futuro y estructurar las soluciones para que se puedan agregar dichos cambios sin afectar el código existente.&lt;/p&gt;

&lt;p&gt;Por ejemplo, para solucionar el caso de los rectángulos nos vamos ayudar del uso de interfaces. Una interfaz es un conjunto de métodos que definen el funcionamiento de una clase, pero no su implementación. Por lo tanto, podemos definir una interfaz genérica para cualquier figura geométrica y que tenga la definición de un método para el cálculo del área. Luego, que cada figura geométrica defina la implementación propia de cada cálculo de área. &lt;/p&gt;

&lt;p&gt;Tomar en cuenta la siguiente interfaz:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;FiguraGeometrica&lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="nf"&gt;calcularArea&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Luego se crean las clases de cada figura geométrica que se utilizará en la librería. Cada clase del tipo &lt;strong&gt;FiguraGeometrica&lt;/strong&gt; implementa su propia forma de calcular el área.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Rectangulo&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;FiguraGeometrica&lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;altura&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Rectangulo&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;altura&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;base&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;altura&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;altura&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="nf"&gt;calcularArea&lt;/span&gt;&lt;span class="o"&gt;(){&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;base&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;altura&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Cuadrado&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;FiguraGeometrica&lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;lado&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Cuadrado&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;lado&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;lado&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lado&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="nf"&gt;calcularArea&lt;/span&gt;&lt;span class="o"&gt;(){&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;lado&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;lado&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Circulo&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;FiguraGeometrica&lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="no"&gt;PI&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;3.1416&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;radio&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Circulo&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;radio&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;radio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;radio&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="nf"&gt;calcularArea&lt;/span&gt;&lt;span class="o"&gt;(){&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Circulo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;PI&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;radio&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;radio&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se modifica la clase CalculadorArea para que reciba un objeto del tipo FiguraGeometrica y con este calcula el área de la figura, sin importar de cual se trata.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CalculadorArea&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="nf"&gt;calcularArea&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;FiguraGeometrica&lt;/span&gt; &lt;span class="n"&gt;figura&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;figura&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;calcularArea&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;    
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La ejecución de la librería se puede realizar de la siguiente forma.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

        &lt;span class="nc"&gt;CalculadorArea&lt;/span&gt; &lt;span class="n"&gt;calcArea&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CalculadorArea&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="nc"&gt;Cuadrado&lt;/span&gt; &lt;span class="n"&gt;cuadrado&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Cuadrado&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;3.15&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="nc"&gt;Rectangulo&lt;/span&gt; &lt;span class="n"&gt;rectangulo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Rectangulo&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;7.85&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;10.85&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="nc"&gt;Circulo&lt;/span&gt; &lt;span class="n"&gt;circulo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Circulo&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;7.98&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Calculo de figura: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;calcArea&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;calcularArea&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cuadrado&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Calculo de figura: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;calcArea&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;calcularArea&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rectangulo&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Calculo de figura: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;calcArea&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;calcularArea&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;circulo&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La nueva estructura de la librería cumple con el principio de abierto/cerrado, ya que se pueden agregar más figuras geométricas sin modificar el código actual, siempre y cuando las nuevas figuras implementen la interfaz FiguraGeometrica.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Cuando se puede aplicar el principio de abierto/cerrado?
&lt;/h2&gt;

&lt;p&gt;El principio abierto/cerrado no debe de ser una regla inamovible en el diseño de soluciones de software. El problema con este principio, al igual que con el de la responsabilidad única, es que el desarrollador debe de predecir los posibles futuros requerimientos que generaran cambios en el código actual. &lt;/p&gt;

&lt;p&gt;Esto puede ser más sencillo para desarrolladores senior o semi-senior, pero para desarrolladores junior puede ser una receta para el desastre. La incorrecta aplicación del principio de abierto/cerrado puede complicar innecesariamente el diseño del código. Esto en lugar ayudar a que la aplicación sea más mantenible y escalable, logra exactamente lo opuesto.&lt;/p&gt;

&lt;p&gt;Mi recomendación personal es siempre escribir código que sea fácilmente entendible por otros desarrolladores y fácil de modificar cuando cambien los requerimientos. En relación con el principio de abierto/cerrado es mejor esperar la primera iteración de cambios para poder prever los puntos en donde el diseño cambiará y así poder aplicar el principio.&lt;/p&gt;

&lt;p&gt;Si deseas ampliar tu conocimiento acerca del principio de abierto/cerrado, puedes leer el &lt;a href="http://blog.cleancoder.com/uncle-bob/2014/05/12/TheOpenClosedPrinciple.html"&gt;blog de Robert C. Martin.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;En una proxima publicación ahondaremos en el principio de sustitución de Liskov.&lt;/p&gt;

</description>
      <category>oop</category>
      <category>solid</category>
      <category>spanish</category>
      <category>architecture</category>
    </item>
    <item>
      <title>SOLID: Principio de Responsabilidad Única</title>
      <dc:creator>Victor Manuel Pinzon</dc:creator>
      <pubDate>Tue, 30 Mar 2021 04:18:09 +0000</pubDate>
      <link>https://dev.to/victorpinzon198/solid-principio-de-responsabilidad-unica-5ffo</link>
      <guid>https://dev.to/victorpinzon198/solid-principio-de-responsabilidad-unica-5ffo</guid>
      <description>&lt;p&gt;La calidad de código es una pieza angular en el desarrollo de software, sin embargo, es una de las más descuidadas. Hoy en día, muchos desarrolladores se enfocan en el aprendizaje de nuevos lenguajes de programación y dejan a un lado las buenas practicas en el diseño de sus aplicaciones. Esto causa que sus aplicaciones, aunque funcionales, no sean lo suficientemente robustas para ser escalables y mantenibes a largo plazo. Los principios SOLID son los cimientos de la calidad de código en la programación orientada a objetos. Dichos principios dictan las reglas básicas para que podamos diseñar aplicaciones mantenibles, escalables y robustas.&lt;/p&gt;

&lt;p&gt;Lamentablemente, es común toparnos con desarrolladores, que con varios años de experiencia en el desarrollo de aplicaciones, desconocen estos principios. Por supuesto, yo no fui la excepción. Mi pasión por el desarrollo de software inició en el año 2004, desarrollando programas básicos en Pascal, que sumaban números y otros que los restaban. En el transcurso de los años aprendí varios lenguajes, entre ellos: C, C++, Visual Basic, Visual Fox Pro, etc. En el año 2008 me tope con Java y su paradigma de programación orientada a objetos. Este paradigma permite abstraer los objetos de la vida real a entidades de código con atributos y comportamientos específicos. En el año 2014, 6 años después de iniciar mi carrera profesional como desarrollador, me topé con el libro Clean Code de Robert C. Martin y sus famosos principios SOLID.&lt;/p&gt;

&lt;p&gt;Transcurrieron 6 años de desarrollo profesional en donde diseñe aplicaciones sin saber que existían los principios SOLID. Para ser sincero, desde que aprendí a aplicarlos ha mejorado por mucho la calidad de mi código. Ha permitido que mis aplicaciones sean sencillas de mantener y robustas en su implementación.&lt;/p&gt;

&lt;p&gt;Creyendo que nunca es tarde para aprender, revisaremos cada uno de los principios SOLID y su aplicación.&lt;/p&gt;

&lt;h2&gt;
  
  
  Principios SOLID
&lt;/h2&gt;

&lt;p&gt;Los principios SOLID son 5 principios básicos de la programación orientada a objetos. Estos fueron desarrollados por Robert C. Martin (Uncle Bob) en el año 2000. Los principios SOLID tienen como objetivo eliminar las malas practicas en el diseño y desarrollo de software. La aplicación de estos principios ayudan al desarrollador a escribir un código mantenible, escalable y robusto.&lt;/p&gt;

&lt;p&gt;Los principios SOLID son:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;S&lt;/strong&gt;ingle Responsibility Principle (Principio de responsabilidad única).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;O&lt;/strong&gt;pen/Closed Principle (Principio de abierto/cerrado).
Liskov Substitution Principle (Principio de sustitución de Liskov).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;I&lt;/strong&gt;nterface Segregation Principle (Principio de segregación de interfaces).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;D&lt;/strong&gt;ependency Inversion Principle (Principio de inversión de dependencia).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;El termino SOLID es un acrónimo de los 5 principios.&lt;/p&gt;

&lt;h2&gt;
  
  
  Principio de Responsabilidad Única
&lt;/h2&gt;

&lt;p&gt;SRP o Principio de responsabilidad única se refiere a que una clase, método o modulo debería de tener solamente una responsabilidad, es decir, solamente una razón para cambiar. En ocasiones sucede que codificamos clases/métodos/módulos que hacen muchas cosas a la vez, por ejemplo, se encargan de la lógica de negocio, de la persistencia de datos, del registro en el log, etc. El principio de responsabilidad única nos ayuda a refactorizar este código y separar la responsabilidades de clases/métodos/módulos para que tengan solo una responsabilidad.&lt;/p&gt;

&lt;p&gt;La desventaja de que una unidad de código tenga más de una responsabilidad, es que cuando se introduce un cambio para alguna de las responsabilidades se puede afectar el funcionamiento de las otras. El objetivo de SRP es la separación de responsabilidades y evitar que otras responsabilidades se vean afectadas por cambios ajenas a ellas.&lt;/p&gt;

&lt;p&gt;Vamos a ver el siguiente ejemplo. A continuación se presenta la clase Cliente.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.yourregulardeveloper.entidades&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.math.BigDecimal&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.List&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Cliente&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;idEmpleado&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;nombre&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;apellido&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Cliente&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;idEmpleado&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;nombre&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;apellido&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;idEmpleado&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;idEmpleado&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;nombre&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;nombre&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;apellido&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;apellido&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="cm"&gt;/**
     * Método encargado de calcular el subtotal de la factura.
     * @param articulos         Listado de articulos que el cliente desea comprar.
     * @return                  Subtotal de la factura
     */&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;BigDecimal&lt;/span&gt; &lt;span class="nf"&gt;calcularSubtotalFactura&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Articulo&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;articulos&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;articulos&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;articulo&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;articulo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getPrecioUnitario&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;multiply&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;BigDecimal&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;articulo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getCantidad&lt;/span&gt;&lt;span class="o"&gt;())))&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;reduce&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;BigDecimal&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ZERO&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;BigDecimal:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="cm"&gt;/**
     * Calcula el total de factura en base al impuesto
     * @param subtotal                  Subtotal de factura
     * @param porcentajeImpuesto        Porcentaje del impuesto
     * @return                          Gran total de la factura
     */&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;BigDecimal&lt;/span&gt; &lt;span class="nf"&gt;calcularTotalFactura&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;BigDecimal&lt;/span&gt; &lt;span class="n"&gt;subtotal&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;BigDecimal&lt;/span&gt; &lt;span class="n"&gt;porcentajeImpuesto&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;subtotal&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;subtotal&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;multiply&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;porcentajeImpuesto&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getIdEmpleado&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;idEmpleado&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setIdEmpleado&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;idEmpleado&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;idEmpleado&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;idEmpleado&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getNombre&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;nombre&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setNombre&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;nombre&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;nombre&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;nombre&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getApellido&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;apellido&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setApellido&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;apellido&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;apellido&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;apellido&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tras un breve análisis de la clase, nos podemos dar cuenta que la entidad “Cliente” representa una violación al principio de responsabilidad única. Debido a que la clase tiene dos responsabilidades, las cuales son:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;El manejo de la entidad cliente en el transcurso de la aplicación. Esta responsabilidad es dada por los atributos y los métodos relacionados a la información del cliente.&lt;/li&gt;
&lt;li&gt;Calculador de totales de factura. Esta responsabilidad es dada por los métodos de calcularSubtotalFactura() y calcularTotalFactura().&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Claramente la responsabilidad principal de la clase es el manejo de la entidad tipo Cliente. Un mal diseño de la clase permitió que introdujéramos la segunda responsabilidad de calculador de totales. Para solucionar este mal diseño debemos de separar las dos responsabilidades en dos clases diferentes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.yourregulardeveloper.srp&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/**
 *
 * @author desarrollo
 */&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Cliente&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;idEmpleado&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;nombre&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;apellido&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Cliente&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;idEmpleado&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;nombre&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;apellido&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;idEmpleado&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;idEmpleado&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;nombre&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;nombre&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;apellido&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;apellido&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getIdEmpleado&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;idEmpleado&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setIdEmpleado&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;idEmpleado&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;idEmpleado&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;idEmpleado&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getNombre&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;nombre&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setNombre&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;nombre&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;nombre&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;nombre&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getApellido&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;apellido&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setApellido&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;apellido&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;apellido&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;apellido&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.yourregulardeveloper.srp&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.math.BigDecimal&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.List&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/**
 *
 * @author desarrollo
 */&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Facturador&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="cm"&gt;/**
     * Método encargado de calcular el subtotal de la factura.
     * @param articulos         Listado de articulos que el cliente desea comprar.
     * @return                  Subtotal de la factura
     */&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;BigDecimal&lt;/span&gt; &lt;span class="nf"&gt;calcularSubtotalFactura&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Articulo&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;articulos&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;articulos&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;articulo&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;articulo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getPrecioUnitario&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;multiply&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;BigDecimal&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;articulo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getCantidad&lt;/span&gt;&lt;span class="o"&gt;())))&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;reduce&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;BigDecimal&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ZERO&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;BigDecimal:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="cm"&gt;/**
     * Calcula el total de factura en base al impuesto
     * @param subtotal                  Subtotal de factura
     * @param porcentajeImpuesto        Porcentaje del impuesto
     * @return                          Gran total de la factura
     */&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;BigDecimal&lt;/span&gt; &lt;span class="nf"&gt;calcularTotalFactura&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;BigDecimal&lt;/span&gt; &lt;span class="n"&gt;subtotal&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;BigDecimal&lt;/span&gt; &lt;span class="n"&gt;porcentajeImpuesto&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;subtotal&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;subtotal&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;multiply&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;porcentajeImpuesto&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La separación de las clases de Cliente y Facturador permite que cada clase tenga solo una responsabilidad o una sola razón para cambiar. La separación de responsabilidades permite que las dos clases sean mantenibles, escalables y fáciles de entender.&lt;/p&gt;

&lt;h3&gt;
  
  
  Principio de Responsabilidad Única a Nivel de Método
&lt;/h3&gt;

&lt;p&gt;Es importante hacer énfasis que el principio de responsabilidad única se refiere a una unidad de código, el cual puede ser a nivel de modulo, clase o método. Hago énfasis en este punto porque es muy común ver métodos que realizan varias acciones, incluso he visto métodos de 500 líneas de código. Por ejemplo, he visto métodos que se encargan de registrar los parámetros en el log, realizar los cálculos correspondientes a la función y, por último, guardar el resultado en la base de datos. El problema de estos métodos es que, además de ser poco escalables y difíciles de mantener, no se pueden probar correctamente mediante pruebas unitarias. La aplicación del principio de responsabilidad única a nivel de método permite que podamos escribir métodos pequeños, con una sola responsabilidad, escalables, mantenibles y fáciles probar mediante pruebas unitarias.&lt;/p&gt;

&lt;h3&gt;
  
  
  Malas Practicas en la Aplicación del Principio de Responsabilidad Única
&lt;/h3&gt;

&lt;p&gt;En muchas ocasiones he visto el principio de responsabilidad única incorrectamente aplicado. Esto sucede cuando se realiza una separación exagerada de las responsabilidades de las clases. Por ejemplo, cuando el principio está incorrectamente aplicado es común ver clases con un solo método, lo cual definitivamente es incorrecto. Debemos de recordar que el principio habla acerca de que una unidad de código debe de cambiar por solo una razón, no habla nada acerca de la cantidad de métodos y atributos que debe de tener dicha clase.&lt;/p&gt;

&lt;p&gt;Es importante tambien recordar que se deben de agrupar todos los métodos que tienen una misma razón para cambiar en una sola clase. Por ejemplo, la clase Facturador agrupa dos métodos, calcularSubtotalFactura() y calcularTotalFactura(), en una sola clase. Debemos de recordar que el principio de responsabilidad única habla acerca de la separación de responsabilidad y la agrupación de unidades de código que tienen la misma responsabilidad, no acerca de la cantidad de métodos que debe de tener una clase o la longitud de un método.&lt;/p&gt;

&lt;p&gt;El principio de responsabilidad única es clave en el diseño de código escalable y mantenible. Permite eliminar aquellas clases que hacen mil cosas y eliminar los métodos que realizan como cien acciones en una sola unidad de código. La separación de responsabilidades permite que nuestro código sea fácil de mantener en el futuro y que pueda ser escalable por otros desarrolladores. Recordemos, escribir código complicado de entender, no te hace un mejor desarrollador, lo contrario, te convierte en un desarrollador que escribe código espagueti y poco robusto.&lt;/p&gt;

&lt;p&gt;Si desean ampliar su conocimiento acerca del principio de responsabilidad única, les recomiendo leer el &lt;a href="https://blog.cleancoder.com/uncle-bob/2014/05/08/SingleReponsibilityPrinciple.html"&gt;blog de Robert C. Martin.&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;En una siguiente publicación hablaremos acerca del principio abierto-cerrado.&lt;/p&gt;

</description>
      <category>oop</category>
      <category>solid</category>
      <category>spanish</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Un vistazo a Java Virtual Machine (JVM)</title>
      <dc:creator>Victor Manuel Pinzon</dc:creator>
      <pubDate>Tue, 30 Mar 2021 03:48:35 +0000</pubDate>
      <link>https://dev.to/victorpinzon198/un-vistazo-a-java-virtual-machine-jvm-1k8</link>
      <guid>https://dev.to/victorpinzon198/un-vistazo-a-java-virtual-machine-jvm-1k8</guid>
      <description>&lt;p&gt;Java Virtual Machine (JVM) es uno de aquellos términos que pasa por desapercibido para la mayoría que incursiona en el mundo de Java. Incluso he conocido a desarrolladores que llevan años programando en Java con un escaso a nulo conocimiento de Java Virtual Machine (JVM). En los cursos de introducción a Java regularmente se enseña que la JVM es una maquina virtual que se utiliza para ejecutar los programas desarrollados en Java… y eso es todo! Prácticamente esa es toda la información que los tutores/catedráticos brindan acerca de un elemento tan importante, como crucial, del ecosistema de Java.&lt;/p&gt;

&lt;p&gt;En base a lo anterior nos podemos preguntar ¿Si muchos pueden desarrollar en Java sin conocer el funcionamiento de la JVM, entonces es realmente es necesario saber el funcionamiento de esta?. Si deseas ser un mejor desarrollador Java, si deseas conocer la diferencia entre Java y otros lenguajes como Python o Javascript, si deseas conocer la razón por la cual Java se considera como un lenguaje “lento”, entonces la respuesta a la pregunta es un rotundo SI.&lt;/p&gt;

&lt;p&gt;A continuación intentaré explicarte brevemente el funcionamiento de la Java Virtual Machine (JVM) y el impacto que esta tiene en el desempeño de sus aplicaciones. Además aprenderás conceptos básicos como: ClassLoader, JIT, Heap Space, etc. El objetivo es brindarte los fundamentos básicos del funcionamiento de la JVM para que en futuras publicaciones podamos ahondar en las buenas practicas que debes de seguir para obtener el mejor desempeño en tus proyectos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Java Virtual Machine (JVM)
&lt;/h2&gt;

&lt;p&gt;Es la abstracción de una maquina virtual que es capaz de analizar bytecode, interpretarlo y ejecutarlo en lenguaje maquina. La JVM fue implementada por Sun Microsystems bajo el concepto WORA (Write Once Run Anywhere) o (Escribelo una vez y ejecútalo en cualquier lado). El concepto WORA pretendía brindar la capacidad única, en su momento, de ser independiente de la plataforma.&lt;/p&gt;

&lt;p&gt;Idealmente, se podía escribir un programa en Java y ejecutarlo en cualquier plataforma, siempre y cuando esta contará con una implementación de la JVM. Este era un gran cambio en la época, en donde escribir un programa en C/C++ significaba compilar para cada plataforma y condicionar el código para la carga de librerías propias de cada plataforma. El desarrollo de la JVM bajo el concepto de WORA desligaba a los desarrolladores de preocuparse en desarrollar sus programas teniendo la plataforma en mente y enfocarse únicamente en la solución de sus desarrollos.&lt;/p&gt;

&lt;p&gt;Es importante resaltar que Java Virtual Machine (JVM) no tiene ningún conocimiento del lenguaje de programación Java, sino únicamente entiende el bytecode generado por el compilador javac o cualquier otro compilador de bytecode. Esto permite que se pueda desarrollar en más de un lenguaje, entre los cuales se encuentran:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Java&lt;/li&gt;
&lt;li&gt;Clojure&lt;/li&gt;
&lt;li&gt;Groovy&lt;/li&gt;
&lt;li&gt;JRuby&lt;/li&gt;
&lt;li&gt;Jython&lt;/li&gt;
&lt;li&gt;Kotlin&lt;/li&gt;
&lt;li&gt;Scala&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Componentes de JVM
&lt;/h2&gt;

&lt;p&gt;La maquina virtual de Java se puede dividir en tres componentes principales:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;ClassLoader System (Sistema de carga de clases):&lt;/strong&gt; Componente  encargado en la carga, enlace e inicialización de las clases.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Runtime Data Area (Área de memoria de ejecución):&lt;/strong&gt; Componente donde se encuentra el área de memoria de ejecución del programa. Dentro de este componente se encuentran los subcomponentes como: Heap Memory, PC Registers, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Execution Engine (Motor de ejecución):&lt;/strong&gt; Componente encargado en la interpretación y ejecución del clases bytecode. Dentro de este componente se encuentran los subcomponentes como: el interpretador, compilador JIT y Garbage Collector.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;h3&gt;
  
  
  1. ClassLoader System (Sistema de Carga de Clases)
&lt;/h3&gt;

&lt;p&gt;El sistema de carga de clases se encarga, tal como su nombre lo indica, de cargar dinámicamente las clases, enlazarlas e iniciarlas para su ejecución.&lt;/p&gt;

&lt;h4&gt;
  
  
  1.1 Loading (Fase de Carga)
&lt;/h4&gt;

&lt;p&gt;Esta fase se encarga de realizar la carga dinámica de los archivos .class al ClassLoader. La Java Virtual Machine (JVM) cuenta con tres diferentes tipos de ClassLoaders, los cuales son:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Bootstrap ClassLoader:&lt;/strong&gt; Es el ClassLoader principal, encargado de cargar el jar de ejecución o también llamado rt.jar. Este jar contiene todas las clases de inicialización de las API principales de Java. El Bootstrap ClassLoader está escrito en código nativo, por lo tanto, diferentes plataformas tendrán diferente implementación del mismo.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Extension ClassLoader:&lt;/strong&gt; Es el segundo componente en la jerarquía de ClassLoaders. Este era el encargado de cargar los archivos .class del folder “jre/lib/ext”. Sin embargo, en la versión de Java 9 se renombró a “Platform ClassLoader” y ahora se encarga de cargar todas las librerías de plataforma de Java SE.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Application ClassLoader:&lt;/strong&gt; Es el tercer componente en la jerarquía de ClassLoaders. El Application ClassLoader se encarga de cargar los archivos .class propios de la aplicación, los cuales se encuentran el classpath de la aplicación.&lt;br&gt;
Es importante resaltar que la carga de clases no se realiza en un solo momento al arranque de la aplicación. En cambio, se cargan dinámicamente bajo demanda por la aplicación.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Proceso de Carga de Clases&lt;/strong&gt;&lt;br&gt;
Los sistemas de carga de clases funcionan bajo un algoritmo de delegación de jerarquía de clases, el cual se resume en los siguientes pasos:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Cuando la aplicación requiere a la JVM un archivo .class, primero se verifica si el archivo ya esta cargado en memoria. Si dicho archivo existiera, entonces se procede a la ejecución. En caso contrario, se envía una solicitud de carga al sistema de ClassLoaders.&lt;/li&gt;
&lt;li&gt;El sistema de carga de clases recibe la solicitud y se delega al Application ClassLoader, el cual lo delega al Extension/Platform ClassLoader y el cual, por último, lo delega al Bootstrap ClassLoader.&lt;/li&gt;
&lt;li&gt;El Bootstrap ClasslLoader se encarga de buscar el archivo dentro de las clases principales de Java. Si la clase no se encontrará en el rt.jar, se delega la carga al Extension/Platform ClassLoader.&lt;/li&gt;
&lt;li&gt;El Extension/Platform ClassLoader se encarga de buscar el archivo en la ruta (jre/lib/ext). A partir de Java 9, se busca en las librerías de plataforma de Java, si la clase no se encontrará en esa ubicación entonces se delega la carga al Application ClassLoader.&lt;/li&gt;
&lt;li&gt;El Application ClassLoader busca el archivo dentro del classpath de la aplicación, sino se encuentra entonces se genera la excepción ClassNotFoundException.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  1.2 Linking (Fase de Enlace)
&lt;/h4&gt;

&lt;p&gt;Esta fase se ejecuta después de haber cargado la clase mediante el sistema de ClassLoaders. La fase de enlace se encarga de verificar que el archivo .class este formado correctamente bajo los estándares de la JVM y que su ejecución no comprometa la integridad de la JVM. La fase de enlace se divide en tres pasos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Verify (Verificar):&lt;/strong&gt; Este paso se encarga de validar que el archivo .class este formado correctamente y sea adecuado para el uso en la JVM.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prepare (Preparación):&lt;/strong&gt; Este paso se encarga de definir un espacio de memoria para las variables de clase (estáticas). Además, se le asigna a cada variable su valor por defecto.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resolve (Resolución):&lt;/strong&gt; Este proceso se encarga de determinar los valores concretos de las referencias simbólicas del pool de referencias del Method Area. Quiere decir, que los nombres de las clases que se utilizan en el programa se almacenan en el pool de constantes y durante la fase de resolución, se sustituyen los nombres de dichas clases por referencias al Method Area.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  1.3 Initialization (Fase de Inicialización)
&lt;/h4&gt;

&lt;p&gt;Esta es la fase final del sistema de carga de clases, durante este paso se asignan los valores originales a las variables estáticas y se ejecutan los bloques estáticos de cada clase.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Runtime Data Area (Área de Memoria de Ejecución)
&lt;/h3&gt;

&lt;p&gt;El área de memoria de ejecución es el componente de Java Virtual Machine (JVM), donde se administran los espacios de memoria utilizados en la ejecución de programas. Esta área se divide en 5 diferentes secciones que tienen diferentes objetivos durante la ejecución, las cuales son:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;PC Register (Registros de PC o Contadores):&lt;/strong&gt; Es el espacio de memoria que contiene la dirección de la instrucción que se esta ejecutando en ese momento y la dirección de memoria de la siguiente instrucción por ejecutarse. Este espacio de memoria es pequeño y tiene un tamaño fijo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Java Virtual Machine Stack (Pila de ejecución):&lt;/strong&gt; Este espacio de memoria almacena los punteros de las variables locales, así como la información relacionada a la invocación y resultado de métodos. Esta pila trabaja mediante marcos de trabajo, los cuales se van apilando para la ejecución de cada uno de ellos. Cada marco de trabajo almacena la información relacionada a variables locales y métodos, así como la referencia a los objetos creados en el heap. Al finalizar la ejecución de cada método, se retira el marco de la pila de ejecución y se libera el espacio de memoria. En este componente es donde se genera el error de ejecución StackOverflowError, el cual se da cuando la pila ya no tiene espacio para almacenar más marcos de ejecución.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Heap Memory (Memoria Heap):&lt;/strong&gt; Este espacio de memoria se comparte por todos los hilos de ejecución y se encarga de almacenar dinámicamente todas las instancias de clases (objetos) y arreglos que la aplicación necesita. En este componente es donde se generan los errores de OutOfMemoryError, el cual se da cuando ya no existe más espacio en el Heap para asignárselo a un objeto nuevo. Este error regularmente se da cuando se crean muchos objetos y el recolector de basura (Garbage Collector) no es capaz de liberar el espacio a tiempo o cuando el Heap se configura con un espacio muy reducido.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Method Area (Área de método):&lt;/strong&gt; En este espacio de memoria se almacena la información a nivel de clase, tal como: información acerca de los métodos, variable estáticas, pool de constantes, etc. Este espacio de memoria se comparte por todos los hilos de ejecución.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Native Method Stack (Pila de métodos nativos):&lt;/strong&gt; En este espacio se guarda la información acerca de los métodos nativos llamados por los hilos de ejecución.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cada una de estas secciones de memorias se dividen en dos diferentes categorías:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Memorias compartidas por hilos:&lt;/strong&gt; Las cuales son aquellas que se inicializan durante el arranque de la JVM. Este espacio de memoria es compartido por todos los hilos. Las áreas de memoria que pertenecen a esta categoria son: Method Area, Heap Memory y el Pool de constantes de ejecución.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memorias asignadas a cada hilo de ejecución:&lt;/strong&gt; Las cuales son aquellas que se inicializan durante la creación de cada hilo. Este espacio de memoria es independiente para cada hilo. Las áreas de memoria que pertenece a esta categoria son: PC Register, JVM Stack y Native Method Stack.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Es común que muchos desarrolladores sientan confusión acerca si los objetos se instancian en el Heap Memory o en el Stack. Esto debido a que JVM divide la creación de un objeto entre estos dos espacios de memoria. Al momento que se instancia un objeto, la JVM asigna un espacio de memoria en el Heap, lo que permite que pueda ser referenciado globalmente. Al mismo momento se crea una referencia a dicho objeto en el stack. Es decir, la pila de ejecución (Stack) almacena las variables locales primitivas y la dirección de memoria de los objetos que se encuentran en el heap.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Execution Engine (Motor de Ejecución)
&lt;/h3&gt;

&lt;p&gt;Este componente se encarga de interpretar el bytecode, ejecutarlo en código maquina, analizar que partes del código se pueden mejorar en su desempeño compilandolas a código maquina mediante el compilador JIT y liberar memoria mediante el Garbage Collector.&lt;/p&gt;

&lt;h4&gt;
  
  
  3.1 Interprete
&lt;/h4&gt;

&lt;p&gt;Cuando se compila un programa en Java se generan uno o más archivos .class. Estos archivos son llamados bytecode y no pueden ser ejecutados directamente debido a que no están compilados a código maquina. Bytecode únicamente puede ser ejecutado en una JVM, la cual interpretará cada instrucción y la ejecutará en instrucciones entendibles por el computador. Este procedimiento permite que Java pueda ser WORA (Write once Run Anywhere), debido a que el desarrollador no se debe de preocupar de compilar su código dependiente a cada plataforma como se realizaba en programas desarrollados en C/C++, sino compilarlo a bytecode. Una vez compilado a bytecode, se puede ejecutar en cualquier JVM sin importar la plataforma la que esta se encuentre ejecutandose.&lt;/p&gt;

&lt;h4&gt;
  
  
  3.2 JIT Compiler (Compilador JIT)
&lt;/h4&gt;

&lt;p&gt;El interprete claramente representa una desventaja cuando se ejecuta múltiples veces una misma sección de código. Esto debido a que se debe de interpretar cada instrucción en cada iteración, sin importar si ya fue ejecutado anteriormente. Para solucionar esta lentitud ocasionada por el interprete, la JVM monitorea constantemente las secciones del código que se repiten en su ejecución y procede a compilarlas a código maquina. Es decir, en lugar de que el interprete ejecute cada línea del método en cada iteración, se traduce el bloque de bytecode completo a código maquina. Esto permite que en próximas iteraciones se ejecute el bloque completo sin interpretar linea por linea.&lt;/p&gt;

&lt;p&gt;El compilador JIT (Just In Time) además de compilar el bytecode a código maquina, también realiza una optimización de código, lo cual ayuda al desempeño del programa en general.&lt;/p&gt;

&lt;h4&gt;
  
  
  3.3 Garbage Collector (Recolector de Basura)
&lt;/h4&gt;

&lt;p&gt;El Garbage Collector es un tema tan amplio como la misma JVM. Este componente fue un hito en la historia de la programación. No es un componente propio de la JVM sino fue desarrollado originalmente para Lisp y la gestión manual de memoria.&lt;/p&gt;

&lt;p&gt;En los desarrollos con lenguajes como C/C++, el desarrollador era el encargado de realizar las rutinas para la liberación de memoria, si esto no era realizado adecuadamente entonces se generaba un error de memoria. En Java Virtual Machine (JVM) no es necesario que el desarrollador lleve a cargo las tareas de liberación de memoria debido a que estas son llevadas a cabo automáticamente. La JVM es la encargada de monitorear mediante diferentes algoritmos, a aquellos objetos que ya no son referenciados por la aplicación y procede a liberar el espacio de memoria asignado a ellos.&lt;/p&gt;

&lt;p&gt;El Garbage Collector cuenta con diferentes estrategias para la liberación de memoria y diferentes terminologias utilizadas durante el ciclo de vida de los objetos. Con el objetivo de mantener esta publicación como una introducción, no se estará ahondando en este tema hasta en futuras publicaciones.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Es Java un lenguaje compilado o interpretado?
&lt;/h2&gt;

&lt;p&gt;Lo anterior nos lleva a preguntarnos ¿Es Java un lenguaje compilado o interpretado? La respuesta es ambos. Java claramente esta escrito en archivos .java, los cuales se compilan mediante javac a archivos .class. Sin embargo, a diferencia de lenguajes como C o C++ en los cuales el compilador los traduce directamente a código maquina para su ejecución. Java necesita de la JVM para que su código sea interpretado de bytecode a código maquina. Además, durante la ejecución del programa, se realiza una compilación a código maquina mediante el compilador JIT. Esta compilación únicamente se realiza bajo demanda, cuando la JVM defina que un bloque de código se ejecutará N veces y que su compilación mejorará el desempeño de la aplicación.&lt;/p&gt;

&lt;p&gt;En base a lo anterior se define que Java es un lenguaje compilado e interpretado. Compilado porque se realiza una pseudo compilación a bytecode e interpretado porque se necesita que la Java Virtual Machine(JVM) interprete cada linea de bytecode a código maquina.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Es Java más lento que los lenguajes compilados?
&lt;/h2&gt;

&lt;p&gt;Muchos detractrores de Java tachan al lenguaje como un lenguaje lento en comparación a programas desarrollados en C/C++. Para contestar correctamente esta pregunta es necesario que tengas en cuenta las fases de intepretación y compilación que realiza la JVM. Por lo tanto, si se compara por la cantidad de tiempo que realiza una misma tarea entonces lo más probable es que el programa desarrollado en C/C++ tenga una ventaja. La ventaja se obtiene debido a que Java debe de cargar, interpretar, compilar y ejecutar bajo demanda, lo cual no sucede en el programa de C/C++, el cual fue compilado directamente a código maquina. Es tambien importante tomar en cuenta que esta diferencia era más notoria en las primeras versiones de Java y JVM, sin embargo, con las mejoras realizadas en las últimas versiones, esta diferencia entre lenguajes es NO significativa.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Es Java mejor que los lenguajes compilados?
&lt;/h2&gt;

&lt;p&gt;Primero es necesario que aclaremos no existen lenguajes de programación malos, sino existe un lenguaje ideal para cada solución. Si se toman en cuenta las condiciones actuales del mercado, es indiscutible negar el predominio que tiene Java en sistemas corporativos. Así como también es indiscutible el predominio de C/C++ en sistemas embebidos, el predominio de Python en Data Science y el de Javascript en el desarrollo web. Cada lenguaje de programación tiene su propio enfoque y es necesario que como especialista de software conozcas las diferencias de cada uno los lenguajes, pero sobretodo es importante que conozcas el ecosistema en el que se desarrolla y se ejecuta el lenguaje seleccionado para tus proyectos.&lt;/p&gt;

&lt;p&gt;El tema de la JVM es extenso y puede ser un poco abrumador para los desarrolladores principiantes. Sin embargo, el aprendizaje de su funcionamiento básico te permitirá ser un mejor desarrollor, no solo en Java sino en cualquier lenguaje de bytecode. Si deseas expandir tu conocimiento acerca de Java Virtual Machine (JVM), se recomienda la lectura de la &lt;a href="https://docs.oracle.com/javase/9/vm/java-virtual-machine-technology-overview.htm#JSJVM-GUID-982B244A-9B01-479A-8651-CB6475019281"&gt;documentación oficial de Oracle&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>spanish</category>
      <category>java</category>
      <category>jvm</category>
      <category>scala</category>
    </item>
  </channel>
</rss>
