{"id":324,"date":"2016-02-01T00:01:28","date_gmt":"2016-02-01T06:01:28","guid":{"rendered":"http:\/\/projectopy.com\/programacion\/?p=324"},"modified":"2024-04-05T20:05:37","modified_gmt":"2024-04-05T20:05:37","slug":"principios-solid","status":"publish","type":"post","link":"https:\/\/iscodigo.com\/blog\/objetos\/principios-solid\/","title":{"rendered":"Principios SOLID"},"content":{"rendered":"<p>Acr\u00f3nimo inventado por Robert C. Martin para establecer 5 principios b\u00e1sicos en la programaci\u00f3n orientada a objetos.<\/p>\n<blockquote><p>El objetivo de tener un buen dise\u00f1o de programaci\u00f3n es abarcar la fase de mantenimiento de una manera m\u00e1s legible y sencilla, as\u00ed como conseguir crear nuevas funcionalidades sin tener que modificar en gran medida c\u00f3digo antiguo. Los costes de mantenimiento pueden abarcar el 80% de un proyecto de software, por lo que hay que valorar un buen dise\u00f1o.[1]<\/p><\/blockquote>\n<h3><\/h3>\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_72 counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Tabla de Contenidos<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Toggle Table of Content\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 eztoc-toggle-hide-by-default' ><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/iscodigo.com\/blog\/objetos\/principios-solid\/#S-Responsabilidad_simple_Single_responsibility\" title=\"S-Responsabilidad simple (Single responsibility)\">S-Responsabilidad simple (Single responsibility)<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/iscodigo.com\/blog\/objetos\/principios-solid\/#O-AbiertoCerrado_OpenClosed\" title=\"O-Abierto\/Cerrado (Open\/Closed)\">O-Abierto\/Cerrado (Open\/Closed)<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/iscodigo.com\/blog\/objetos\/principios-solid\/#L-Sustitucion_Liskov_Liskov_substitution\" title=\"L-Sustituci\u00f3n Liskov (Liskov substitution)\">L-Sustituci\u00f3n Liskov (Liskov substitution)<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/iscodigo.com\/blog\/objetos\/principios-solid\/#I-Segregacion_del_interface_Interface_segregation\" title=\"I-Segregaci\u00f3n del interface (Interface segregation)\">I-Segregaci\u00f3n del interface (Interface segregation)<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/iscodigo.com\/blog\/objetos\/principios-solid\/#D-Inversion_de_dependencias_Dependency_inversion\" title=\"D-Inversi\u00f3n de dependencias (Dependency inversion)\">D-Inversi\u00f3n de dependencias (Dependency inversion)<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/iscodigo.com\/blog\/objetos\/principios-solid\/#Glosario\" title=\"Glosario\">Glosario<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/iscodigo.com\/blog\/objetos\/principios-solid\/#Bibliografia\" title=\"Bibliograf\u00eda\">Bibliograf\u00eda<\/a><\/li><\/ul><\/nav><\/div>\n<h3><span class=\"ez-toc-section\" id=\"S-Responsabilidad_simple_Single_responsibility\"><\/span>S-Responsabilidad simple (Single responsibility)<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Este principio trata de destinar cada clase a una finalidad sencilla y concreta. Esto tambi\u00e9n debe aplicarse para el caso de los m\u00e9todos, en los que cada uno deber\u00eda realizar una sola actividad.<\/p>\n<hr \/>\n<p>Para el siguiente caso tenemos que la clase Veh\u00edculo, adem\u00e1s de definir las caracter\u00edsticas propias de la clase, posee una responsabilidad m\u00e1s: imprimir el objeto que se instancia. Esto puede ser un problema en el futuro. Imagine que por ahora dicho m\u00e9todo imprime en el terminal. Sin embargo, en un futuro se planea que se pueda utilizar en un ambiente web y deba mostrarse utilizando etiquetas HTML, tendr\u00eda que cambiar la estructura de la clase.<\/p>\n<figure id=\"attachment_1471\" aria-describedby=\"caption-attachment-1471\" style=\"width: 184px\" class=\"wp-caption alignnone\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"wp-image-1471 size-full\" src=\"https:\/\/i0.wp.com\/iscodigo.com\/blog\/wp-content\/uploads\/2017\/04\/vehiculo.jpg?resize=184%2C150&#038;ssl=1\" alt=\"vehiculo\" width=\"184\" height=\"150\" \/><figcaption id=\"caption-attachment-1471\" class=\"wp-caption-text\">Fig 1. Veh\u00edculo<\/figcaption><\/figure>\n<p>Lo m\u00e1s recomendable separar las responsabilidades con el fin de que cada clase posea una responsabilidad, por lo cual se quitar\u00eda de Veh\u00edculo el m\u00e9todo \u201cimprimir\u201d y se trasladar\u00eda a una nueva clase denominada VehiculoImpresor.<\/p>\n<figure id=\"attachment_1472\" aria-describedby=\"caption-attachment-1472\" style=\"width: 195px\" class=\"wp-caption alignnone\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1472\" src=\"https:\/\/i0.wp.com\/iscodigo.com\/blog\/wp-content\/uploads\/2017\/04\/vehiculoimpresor.jpg?resize=195%2C107&#038;ssl=1\" alt=\"VehiculoImpresor\" width=\"195\" height=\"107\" \/><figcaption id=\"caption-attachment-1472\" class=\"wp-caption-text\">Fig 2. Veh\u00edculoImpresor<\/dd>\n<p><\/p>\n<dd><\/figcaption><\/figure>\n<h3><span class=\"ez-toc-section\" id=\"O-AbiertoCerrado_OpenClosed\"><\/span>O-Abierto\/Cerrado (Open\/Closed)<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Principio atribuido a Bertrand Meyer que habla de crear clases extensibles sin necesidad de entrar al c\u00f3digo fuente a modificarlo [3]. Es decir, el dise\u00f1o debe ser abierto para extenderse pero cerrado para modificarse. Lo complicado es predecir por donde se debe extender sin tener que modificarse. Para conseguir este principio hay que tener muy claro c\u00f3mo va a funcionar la aplicaci\u00f3n, por donde se puede extender y como van a interactuar las clases.<\/p>\n<p>El uso m\u00e1s com\u00fan de extensi\u00f3n es mediante la herencia y la reimplementaci\u00f3n de m\u00e9todos. Existe otra alternativa, que consiste en utilizar m\u00e9todos que acepten una interface de manera que podemos ejecutar cualquier clase que implemente ese interface. En todos los casos, el comportamiento de la clase cambia sin que hayamos tenido que tocar c\u00f3digo interno.<\/p>\n<hr \/>\n<p>Siguiendo con el ejemplo anterior, si se debe imprimir en HTML el veh\u00edculo no ser\u00eda correcto implementar un nuevo m\u00e9todo en VehiculoImpresor, es posible definir una interfaz que permita ampliar en el tiempo las funcionalidades de cada clase que se va creando.<\/p>\n<figure id=\"attachment_1473\" aria-describedby=\"caption-attachment-1473\" style=\"width: 468px\" class=\"wp-caption alignnone\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"wp-image-1473 size-full\" src=\"https:\/\/i0.wp.com\/iscodigo.com\/blog\/wp-content\/uploads\/2017\/04\/openclose.jpg?resize=468%2C243&#038;ssl=1\" alt=\"OpenClose\" width=\"468\" height=\"243\" srcset=\"https:\/\/i0.wp.com\/iscodigo.com\/blog\/wp-content\/uploads\/2017\/04\/openclose.jpg?w=468&amp;ssl=1 468w, https:\/\/i0.wp.com\/iscodigo.com\/blog\/wp-content\/uploads\/2017\/04\/openclose.jpg?resize=300%2C156&amp;ssl=1 300w\" sizes=\"auto, (max-width: 468px) 100vw, 468px\" \/><figcaption id=\"caption-attachment-1473\" class=\"wp-caption-text\">Fig 3. Interface para VehiculoImpresor<\/dd>\n<p><\/p>\n<dd><\/figcaption><\/figure>\n<h3><span class=\"ez-toc-section\" id=\"L-Sustitucion_Liskov_Liskov_substitution\"><\/span>L-Sustituci\u00f3n Liskov (Liskov substitution)<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Este principio fue creado por Barbara Liskov y habla de la importancia de originar todas las clases derivadas para que tambi\u00e9n puedan ser tratadas como la propia clase base. Cuando se crean clases derivadas, se debe asegurar de no re-implementar m\u00e9todos que hagan que los m\u00e9todos de la clase base no funcionar\u00e1n si se tratan como un objeto de esa clase base.<\/p>\n<hr \/>\n<p>Con el ejemplo de la Figura 3,\u00a0con las clases VehiculoImpresorConsola y VehiculoImpresorHTML puede sustituirse sin problema con la interface IVehiculoImpresor.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"I-Segregacion_del_interface_Interface_segregation\"><\/span>I-Segregaci\u00f3n del interface (Interface segregation)<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Este principio fue formulado por Robert C. Martin y trata de algo parecido al primer principio. Cuando se definen interfaces, estos deben ser espec\u00edficos a una finalidad concreta. Por ello, si tenemos que definir una serie de m\u00e9todos abstractos que debe utilizar una clase a trav\u00e9s de interfaces, es preferible tener muchas interfaces que definan pocos m\u00e9todos que tener un interface con muchos m\u00e9todos.<\/p>\n<p>El objetivo de este principio es principalmente seguir aprovechando los interfaces en otras clases. Si tenemos un interface que compara y clona en el mismo interface, de manera m\u00e1s complicada se podr\u00e1 utilizar en una clase que solo debe comparar o en otra que solo debe clonar.<\/p>\n<hr \/>\n<p>En la figura 4, se establecen demasiadas responsabilidades para la interface ITrasporte, con el consiguiente problema que las clases que implementen dicha interfaz est\u00e1n obligados a implementar los tres m\u00e9todos descritos. Lo cual es err\u00f3neo.<\/p>\n<figure id=\"attachment_1477\" aria-describedby=\"caption-attachment-1477\" style=\"width: 252px\" class=\"wp-caption alignnone\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1477\" src=\"https:\/\/i0.wp.com\/iscodigo.com\/blog\/wp-content\/uploads\/2017\/04\/segregacioninterface1.jpg?resize=252%2C297&#038;ssl=1\" alt=\"SegregacionInterface1\" width=\"252\" height=\"297\" \/><figcaption id=\"caption-attachment-1477\" class=\"wp-caption-text\"><em><strong>Fig 4. Interface con varias responsabilidades<\/strong><\/em><\/figcaption><\/figure>\n<p>Para solucionar esto se debe separar cada responsabilidad. Tal como la figura 5.<\/p>\n<figure id=\"attachment_1478\" aria-describedby=\"caption-attachment-1478\" style=\"width: 504px\" class=\"wp-caption alignnone\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1478\" src=\"https:\/\/i0.wp.com\/iscodigo.com\/blog\/wp-content\/uploads\/2017\/04\/segregacioninterface2.jpg?resize=504%2C201&#038;ssl=1\" alt=\"SegregacionInterface2\" width=\"504\" height=\"201\" srcset=\"https:\/\/i0.wp.com\/iscodigo.com\/blog\/wp-content\/uploads\/2017\/04\/segregacioninterface2.jpg?w=504&amp;ssl=1 504w, https:\/\/i0.wp.com\/iscodigo.com\/blog\/wp-content\/uploads\/2017\/04\/segregacioninterface2.jpg?resize=300%2C120&amp;ssl=1 300w\" sizes=\"auto, (max-width: 504px) 100vw, 504px\" \/><figcaption id=\"caption-attachment-1478\" class=\"wp-caption-text\"><strong><em>Fig 5. Interfaces separadas<\/em><\/strong><\/dd>\n<p><\/p>\n<dd><\/figcaption><\/figure>\n<h3><span class=\"ez-toc-section\" id=\"D-Inversion_de_dependencias_Dependency_inversion\"><\/span>D-Inversi\u00f3n de dependencias (Dependency inversion)<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Tambi\u00e9n fue definido por Robert C. Martin. El objetivo de este principio es conseguir desacoplar las clases. En todo dise\u00f1o existe un acoplamiento, pero debe evitarse en la medida de lo posible. Un sistema no acoplado no hace nada, pero un sistema altamente acoplado es muy dif\u00edcil de mantener.<\/p>\n<p>El objetivo de este principio es el uso de abstracciones para conseguir que una clase interact\u00fae con otras clases sin que las conozca directamente. Es decir, las clases de nivel superior no deben conocer las clases de nivel inferior. Dicho de otro modo, no debe conocer los detalles. Existen diferentes patrones como la inyecci\u00f3n de dependencias o service locator que nos permiten invertir el control.<\/p>\n<hr \/>\n<figure id=\"attachment_1481\" aria-describedby=\"caption-attachment-1481\" style=\"width: 334px\" class=\"wp-caption alignnone\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"wp-image-1481 size-full\" src=\"https:\/\/i0.wp.com\/iscodigo.com\/blog\/wp-content\/uploads\/2017\/04\/inversion-dependencia.jpg?resize=334%2C120&#038;ssl=1\" alt=\"inversion-dependencia\" width=\"334\" height=\"120\" srcset=\"https:\/\/i0.wp.com\/iscodigo.com\/blog\/wp-content\/uploads\/2017\/04\/inversion-dependencia.jpg?w=334&amp;ssl=1 334w, https:\/\/i0.wp.com\/iscodigo.com\/blog\/wp-content\/uploads\/2017\/04\/inversion-dependencia.jpg?resize=300%2C108&amp;ssl=1 300w\" sizes=\"auto, (max-width: 334px) 100vw, 334px\" \/><figcaption id=\"caption-attachment-1481\" class=\"wp-caption-text\">Fig. 6 Direcci\u00f3n est\u00e1 fuertemente acoplada<\/figcaption><\/figure>\n<figure id=\"attachment_1482\" aria-describedby=\"caption-attachment-1482\" style=\"width: 446px\" class=\"wp-caption alignnone\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1482\" src=\"https:\/\/i0.wp.com\/iscodigo.com\/blog\/wp-content\/uploads\/2017\/04\/inversion-dependencia2.jpg?resize=446%2C107&#038;ssl=1\" alt=\"inversion-dependencia2\" width=\"446\" height=\"107\" srcset=\"https:\/\/i0.wp.com\/iscodigo.com\/blog\/wp-content\/uploads\/2017\/04\/inversion-dependencia2.jpg?w=446&amp;ssl=1 446w, https:\/\/i0.wp.com\/iscodigo.com\/blog\/wp-content\/uploads\/2017\/04\/inversion-dependencia2.jpg?resize=300%2C72&amp;ssl=1 300w\" sizes=\"auto, (max-width: 446px) 100vw, 446px\" \/><figcaption id=\"caption-attachment-1482\" class=\"wp-caption-text\">Fig 7. Se\u00a0logra la inversi\u00f3n de dependencia<\/dd>\n<p><\/p>\n<dd><\/figcaption><\/figure>\n<h2><span class=\"ez-toc-section\" id=\"Glosario\"><\/span>Glosario<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p><strong>Acoplamiento:<\/strong>\u00a0Grado de dependencia que tienen dos unidades de software. Si hablamos de funciones, el acoplamiento nos da una idea de lo dependientes que son dos funciones entre s\u00ed. Es decir, en qu\u00e9 grado una funci\u00f3n puede hacer su trabajo sin la otra. Si hablo del m\u00e1s bajo nivel de acoplamiento cuando dos unidades de software son totalmente independientes.[2]<\/p>\n<p>Un bajo acoplamiento permite:<\/p>\n<ul>\n<li>Entender una clase sin leer otras<\/li>\n<li>Cambiar una clase sin afectar a otras<\/li>\n<li>Mejora la mantenibilidad del c\u00f3digo<\/li>\n<\/ul>\n<p><strong>Cohesi\u00f3n:\u00a0<\/strong>La cohesi\u00f3n mide el costo del cambio dentro de un elemento. Un elemento es cohesivo a medida que cambia el elemento entero cuando el sistema necesita cambiar.[4]<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Bibliografia\"><\/span>Bibliograf\u00eda<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>[1] http:\/\/www.genbetadev.com\/paradigmas-de-programacion\/solid-cinco-principios-basicos-de-diseno-de-clases<\/p>\n<p>[2]\u00a0http:\/\/latecladeescape.com\/h\/2015\/07\/acoplamiento-y-cohesion#<\/p>\n<p>[3]\u00a0https:\/\/devexperto.com\/principio-open-closed\/<\/p>\n<p>[4]\u00a0https:\/\/dosideas.com\/noticias\/java\/502-acoplamiento-y-cohesion<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Acr\u00f3nimo inventado por Robert C. Martin para establecer 5 principios b\u00e1sicos en la programaci\u00f3n orientada a objetos. El objetivo de tener un buen dise\u00f1o de programaci\u00f3n es abarcar la fase de mantenimiento de una manera m\u00e1s legible y sencilla, as\u00ed como conseguir crear nuevas funcionalidades sin tener que modificar en gran medida c\u00f3digo antiguo. Los [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[45],"tags":[56,125,135],"class_list":["post-324","post","type-post","status-publish","format-standard","hentry","category-objetos","tag-buenas-practicas","tag-principios","tag-solid"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/iscodigo.com\/blog\/wp-json\/wp\/v2\/posts\/324","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/iscodigo.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/iscodigo.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/iscodigo.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/iscodigo.com\/blog\/wp-json\/wp\/v2\/comments?post=324"}],"version-history":[{"count":2,"href":"https:\/\/iscodigo.com\/blog\/wp-json\/wp\/v2\/posts\/324\/revisions"}],"predecessor-version":[{"id":1644,"href":"https:\/\/iscodigo.com\/blog\/wp-json\/wp\/v2\/posts\/324\/revisions\/1644"}],"wp:attachment":[{"href":"https:\/\/iscodigo.com\/blog\/wp-json\/wp\/v2\/media?parent=324"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/iscodigo.com\/blog\/wp-json\/wp\/v2\/categories?post=324"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/iscodigo.com\/blog\/wp-json\/wp\/v2\/tags?post=324"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}