{"id":60,"date":"2023-09-15T11:28:37","date_gmt":"2023-09-15T14:28:37","guid":{"rendered":"https:\/\/mauriciobeltran.cl\/?p=60"},"modified":"2023-09-15T11:28:38","modified_gmt":"2023-09-15T14:28:38","slug":"solid-principio-de-sustitucion-de-liskov","status":"publish","type":"post","link":"https:\/\/mauriciobeltran.cl\/index.php\/2023\/09\/15\/solid-principio-de-sustitucion-de-liskov\/","title":{"rendered":"SOLID \u2014 Principio de sustituci\u00f3n de liskov"},"content":{"rendered":"\n<p>Creo que este debe ser el principio SOLID m\u00e1s complejo de interiorizar. En concreto este principio dice que:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>Si por cada objeto <strong>O<sub>1<\/sub><\/strong> de tipo <strong>S<\/strong> hay un objeto <strong>O<sub>2<\/sub><\/strong> de tipo <strong>T<\/strong> tal que para todos los programas <strong>P<\/strong> definidos en t\u00e9rminos de <strong>T<\/strong>, el comportamiento de <strong>P<\/strong> no se ve alterado cuando <strong>O<sub>1<\/sub><\/strong> es sustituido por <strong>O<sub>2<\/sub><\/strong> entonces <strong>S<\/strong> es un subtipo de <strong>T<\/strong>.  <\/p>\n<cite>Barbara Liskov &#8211; 1988<\/cite><\/blockquote>\n\n\n\n<p>Existe otra definici\u00f3n un poco menos tortuosa de entender que dice <\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>si <strong>S<\/strong> es un subtipo de <strong>T<\/strong>, entonces los objetos de tipo <strong>T<\/strong> pueden ser sustituidos por objetos de tipo <strong>S<\/strong><\/p>\n<cite>Wikipedia.org &#8211; 2023<\/cite><\/blockquote>\n\n\n\n<p>!We\u00f3n!, que chucha este concepto; se preguntar\u00e1n. Pero analic\u00e9moslo en consecuencia para aclarar dudas. Lo primero que hay que entender, es que ac\u00e1, particularmente ac\u00e1, hablamos de <strong>herencia<\/strong>.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Nos dice, S es un subtipo de T. o sea:<\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/mauriciobeltran.cl\/wp-content\/uploads\/2023\/09\/image-1.png\" alt=\"\" class=\"wp-image-88\" style=\"width:211px;height:301px\" width=\"211\" height=\"301\" srcset=\"https:\/\/mauriciobeltran.cl\/wp-content\/uploads\/2023\/09\/image-1.png 564w, https:\/\/mauriciobeltran.cl\/wp-content\/uploads\/2023\/09\/image-1-210x300.png 210w\" sizes=\"auto, (max-width: 211px) 100vw, 211px\" \/><figcaption class=\"wp-element-caption\"><em>S es una clase hija de T<\/em><\/figcaption><\/figure>\n\n\n\n<p>2. Luego, nos dice que todos los objetos de tipo T, pueden eventualmente ser reemplazados por S sin alterar el correcto funcionamiento del programa. O sea:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/mauriciobeltran.cl\/wp-content\/uploads\/2023\/09\/image-3-1024x540.png\" alt=\"\" class=\"wp-image-90\" style=\"width:522px;height:275px\" width=\"522\" height=\"275\" srcset=\"https:\/\/mauriciobeltran.cl\/wp-content\/uploads\/2023\/09\/image-3-1024x540.png 1024w, https:\/\/mauriciobeltran.cl\/wp-content\/uploads\/2023\/09\/image-3-300x158.png 300w, https:\/\/mauriciobeltran.cl\/wp-content\/uploads\/2023\/09\/image-3-768x405.png 768w, https:\/\/mauriciobeltran.cl\/wp-content\/uploads\/2023\/09\/image-3.png 1524w\" sizes=\"auto, (max-width: 522px) 100vw, 522px\" \/><figcaption class=\"wp-element-caption\"><em>Programa P puede usar objetos de tipo T<\/em><\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/mauriciobeltran.cl\/wp-content\/uploads\/2023\/09\/image-4-1024x540.png\" alt=\"\" class=\"wp-image-91\" style=\"width:534px;height:282px\" width=\"534\" height=\"282\" srcset=\"https:\/\/mauriciobeltran.cl\/wp-content\/uploads\/2023\/09\/image-4-1024x540.png 1024w, https:\/\/mauriciobeltran.cl\/wp-content\/uploads\/2023\/09\/image-4-300x158.png 300w, https:\/\/mauriciobeltran.cl\/wp-content\/uploads\/2023\/09\/image-4-768x405.png 768w, https:\/\/mauriciobeltran.cl\/wp-content\/uploads\/2023\/09\/image-4.png 1524w\" sizes=\"auto, (max-width: 534px) 100vw, 534px\" \/><figcaption class=\"wp-element-caption\"><em>Programa P puede usar objetos de tipo S<\/em><\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Ejemplo pr\u00e1ctico<\/h2>\n\n\n\n<p>Veamos entonces un ejemplo concreto. Lo llamar\u00e9, el dilema del pollito.<\/p>\n\n\n\n<p>Todos sabemos que un ave tiene distintos atributos y acciones como por ejemplo:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Graznar<\/li>\n\n\n\n<li>Caminar<\/li>\n\n\n\n<li>Volar<\/li>\n<\/ol>\n\n\n\n<p>Si lo pudi\u00e9ramos modelar ser\u00eda algo mas menos as\u00ed:<\/p>\n\n\n\n<p>Supongamos entonces que vamos a crear una nueva clase llamada Urraca, est\u00e1 heredar\u00e1 de ave, por lo que tendr\u00edamos que el urraca:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Grazna<\/li>\n\n\n\n<li>Camina<\/li>\n\n\n\n<li>Vuela<\/li>\n<\/ol>\n\n\n\n<p>\u00bfCierto?, perfecto; entonces eventualmente si yo hago<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/mauriciobeltran.cl\/wp-content\/uploads\/2023\/09\/image-16-1024x638.png\" alt=\"\" class=\"wp-image-174\" style=\"width:470px;height:293px\" width=\"470\" height=\"293\" srcset=\"https:\/\/mauriciobeltran.cl\/wp-content\/uploads\/2023\/09\/image-16-1024x638.png 1024w, https:\/\/mauriciobeltran.cl\/wp-content\/uploads\/2023\/09\/image-16-300x187.png 300w, https:\/\/mauriciobeltran.cl\/wp-content\/uploads\/2023\/09\/image-16-768x478.png 768w, https:\/\/mauriciobeltran.cl\/wp-content\/uploads\/2023\/09\/image-16.png 1484w\" sizes=\"auto, (max-width: 470px) 100vw, 470px\" \/><\/figure>\n\n\n\n<p>Puedo reemplazarlo perfectamente por:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/mauriciobeltran.cl\/wp-content\/uploads\/2023\/09\/image-17-1024x621.png\" alt=\"\" class=\"wp-image-175\" style=\"width:475px;height:288px\" width=\"475\" height=\"288\" srcset=\"https:\/\/mauriciobeltran.cl\/wp-content\/uploads\/2023\/09\/image-17-1024x621.png 1024w, https:\/\/mauriciobeltran.cl\/wp-content\/uploads\/2023\/09\/image-17-300x182.png 300w, https:\/\/mauriciobeltran.cl\/wp-content\/uploads\/2023\/09\/image-17-768x466.png 768w, https:\/\/mauriciobeltran.cl\/wp-content\/uploads\/2023\/09\/image-17.png 1524w\" sizes=\"auto, (max-width: 475px) 100vw, 475px\" \/><\/figure>\n\n\n\n<p>Ya que si creo un ave Ave o un ave Urraca, ambos pueden graznar, caminar y volar. Si reemplazo ave por Urraca entonces no afecta la funcionalidad del programa, ergo, estamos respetando el principio.<\/p>\n\n\n\n<p>Pero que pasa si ahora quiero crear otra ave, Pollito. en estricto rigor es un ave&#8230; \u00bfno?. Entonces lo l\u00f3gico es que herede de Ave, quedando algo as\u00ed.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/mauriciobeltran.cl\/wp-content\/uploads\/2023\/09\/image-18-1024x503.png\" alt=\"\" class=\"wp-image-176\" style=\"width:585px;height:287px\" width=\"585\" height=\"287\" srcset=\"https:\/\/mauriciobeltran.cl\/wp-content\/uploads\/2023\/09\/image-18-1024x503.png 1024w, https:\/\/mauriciobeltran.cl\/wp-content\/uploads\/2023\/09\/image-18-300x147.png 300w, https:\/\/mauriciobeltran.cl\/wp-content\/uploads\/2023\/09\/image-18-768x377.png 768w, https:\/\/mauriciobeltran.cl\/wp-content\/uploads\/2023\/09\/image-18-1536x754.png 1536w, https:\/\/mauriciobeltran.cl\/wp-content\/uploads\/2023\/09\/image-18.png 1964w\" sizes=\"auto, (max-width: 585px) 100vw, 585px\" \/><\/figure>\n\n\n\n<p>Pero hay algo que no cuaja, los pollitos no vuelan.<\/p>\n\n\n\n<p>Eventualmente si yo instancia de Ave o Pollito, existir\u00eda una diferencia y el Pollito colapsar\u00eda cuando le pida volar.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/mauriciobeltran.cl\/wp-content\/uploads\/2023\/09\/image-19-1024x448.png\" alt=\"\" class=\"wp-image-178\" style=\"width:653px;height:286px\" width=\"653\" height=\"286\" srcset=\"https:\/\/mauriciobeltran.cl\/wp-content\/uploads\/2023\/09\/image-19-1024x448.png 1024w, https:\/\/mauriciobeltran.cl\/wp-content\/uploads\/2023\/09\/image-19-300x131.png 300w, https:\/\/mauriciobeltran.cl\/wp-content\/uploads\/2023\/09\/image-19-768x336.png 768w, https:\/\/mauriciobeltran.cl\/wp-content\/uploads\/2023\/09\/image-19-1536x672.png 1536w, https:\/\/mauriciobeltran.cl\/wp-content\/uploads\/2023\/09\/image-19-2048x896.png 2048w\" sizes=\"auto, (max-width: 653px) 100vw, 653px\" \/><\/figure>\n\n\n\n<p>\u00bfQue hago entonces?, bueno, puedo tener 2 soluciones:<\/p>\n\n\n\n<p>Aves que vuelan, y aves que no vuelan, que implementen las funciones intermedias necesarias. As\u00ed ademas soportar\u00edamos aves que nadan, corren, etc.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/mauriciobeltran.cl\/wp-content\/uploads\/2023\/09\/image-20-1024x496.png\" alt=\"\" class=\"wp-image-180\" style=\"width:622px;height:301px\" width=\"622\" height=\"301\" srcset=\"https:\/\/mauriciobeltran.cl\/wp-content\/uploads\/2023\/09\/image-20-1024x496.png 1024w, https:\/\/mauriciobeltran.cl\/wp-content\/uploads\/2023\/09\/image-20-300x145.png 300w, https:\/\/mauriciobeltran.cl\/wp-content\/uploads\/2023\/09\/image-20-768x372.png 768w, https:\/\/mauriciobeltran.cl\/wp-content\/uploads\/2023\/09\/image-20-1536x744.png 1536w, https:\/\/mauriciobeltran.cl\/wp-content\/uploads\/2023\/09\/image-20-2048x992.png 2048w\" sizes=\"auto, (max-width: 622px) 100vw, 622px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/mauriciobeltran.cl\/wp-content\/uploads\/2023\/09\/image-21-1024x480.png\" alt=\"\" class=\"wp-image-181\" style=\"width:647px;height:303px\" width=\"647\" height=\"303\" srcset=\"https:\/\/mauriciobeltran.cl\/wp-content\/uploads\/2023\/09\/image-21-1024x480.png 1024w, https:\/\/mauriciobeltran.cl\/wp-content\/uploads\/2023\/09\/image-21-300x141.png 300w, https:\/\/mauriciobeltran.cl\/wp-content\/uploads\/2023\/09\/image-21-768x360.png 768w, https:\/\/mauriciobeltran.cl\/wp-content\/uploads\/2023\/09\/image-21-1536x720.png 1536w, https:\/\/mauriciobeltran.cl\/wp-content\/uploads\/2023\/09\/image-21-2048x960.png 2048w\" sizes=\"auto, (max-width: 647px) 100vw, 647px\" \/><\/figure>\n\n\n\n<p>\u00bfComo modelamos entonces la herencia?, es un proceso evolutivo, o sea, generalmente no es planificada. Y no me malentiendan, en un dise\u00f1o orientado a objetos, es muy probable que salgamos con clases padre modeladas al principio, pero en la pr\u00e1ctica, se hace lo siguiente:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Programo mi clase S<\/li>\n\n\n\n<li>Programo mi clase S&#8217;<\/li>\n\n\n\n<li>Veo que existen m\u00e9todos comunes entre ambos y paff nace la clase T<\/li>\n<\/ol>\n\n\n\n<p>Que pasa si sale una clase S\u00bb que eventualmente la clase T no soporte.<\/p>\n\n\n\n<p>Bueno, para ello deberiamos entonces distribuir la funcionalidad en S y S&#8217;, adelgazando T para que se cumpla el principio de Liskov.<\/p>\n\n\n\n<p>Espero se haya entendido, si no, me preguntan.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Creo que este debe ser el principio SOLID m\u00e1s complejo<\/p>\n","protected":false},"author":1,"featured_media":55,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4,3,5],"tags":[],"class_list":["post-60","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-software-architecture","category-development","category-solid"],"_links":{"self":[{"href":"https:\/\/mauriciobeltran.cl\/index.php\/wp-json\/wp\/v2\/posts\/60","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mauriciobeltran.cl\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mauriciobeltran.cl\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mauriciobeltran.cl\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mauriciobeltran.cl\/index.php\/wp-json\/wp\/v2\/comments?post=60"}],"version-history":[{"count":16,"href":"https:\/\/mauriciobeltran.cl\/index.php\/wp-json\/wp\/v2\/posts\/60\/revisions"}],"predecessor-version":[{"id":185,"href":"https:\/\/mauriciobeltran.cl\/index.php\/wp-json\/wp\/v2\/posts\/60\/revisions\/185"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/mauriciobeltran.cl\/index.php\/wp-json\/wp\/v2\/media\/55"}],"wp:attachment":[{"href":"https:\/\/mauriciobeltran.cl\/index.php\/wp-json\/wp\/v2\/media?parent=60"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mauriciobeltran.cl\/index.php\/wp-json\/wp\/v2\/categories?post=60"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mauriciobeltran.cl\/index.php\/wp-json\/wp\/v2\/tags?post=60"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}