{"id":217,"date":"2023-02-17T22:55:16","date_gmt":"2023-02-18T03:55:16","guid":{"rendered":"https:\/\/lafilosofiadelsoftware.com\/?p=217"},"modified":"2023-02-20T10:46:12","modified_gmt":"2023-02-20T15:46:12","slug":"inyeccion-de-dependencias-inversion-de-dependencias-e-inversion-de-control","status":"publish","type":"post","link":"https:\/\/lafilosofiadelsoftware.com\/index.php\/2023\/02\/17\/inyeccion-de-dependencias-inversion-de-dependencias-e-inversion-de-control\/","title":{"rendered":"Inyecci\u00f3n de dependencias, Inversi\u00f3n de dependencias e inversi\u00f3n de control."},"content":{"rendered":"\n<p>Para entender el valor de estos conceptos y cuando aplicarlo, primero debemos entender que es el <strong>acoplamiento<\/strong>, el cual es una medida en la que un componente o clase depende de otro para funcionar. Debido a que nuestros proyectos de software poseen diferentes componentes y clases para trabajar interactuando entre ellas para entregar un resultado, es muy dif\u00edcil y pr\u00e1cticamente imposible tener un software sin acoplamiento; sin embargo, siempre se debe buscar tener el acoplamiento en una medida baja.<br>Veamos el siguiente ejemplo:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"771\" height=\"318\" src=\"https:\/\/lafilosofiadelsoftware.com\/wp-content\/uploads\/2023\/02\/ID-Pa\u0301gina-1.drawio.png\" alt=\"\" class=\"wp-image-222\" srcset=\"https:\/\/lafilosofiadelsoftware.com\/wp-content\/uploads\/2023\/02\/ID-Pa\u0301gina-1.drawio.png 771w, https:\/\/lafilosofiadelsoftware.com\/wp-content\/uploads\/2023\/02\/ID-Pa\u0301gina-1.drawio-300x124.png 300w, https:\/\/lafilosofiadelsoftware.com\/wp-content\/uploads\/2023\/02\/ID-Pa\u0301gina-1.drawio-768x317.png 768w\" sizes=\"(max-width: 771px) 100vw, 771px\" \/><figcaption><strong>Figura 1.0 <\/strong>MoneyTransferService como una clase con m\u00faltiples dependencias y un alto acoplamiento<\/figcaption><\/figure><\/div>\n\n\n\n<p>Nuestra clase de <em>MoneyTransferService <\/em>es una clase muy inestable, dado que tiene muchas dependencias que pueden hacer que nuestra clase necesite cambios. Adicionalmente tiene un alto acoplamiento al estar ligado directamente a clases concretas que impiden poder llegar a cambiar una clase sin verse directamente afectada. <\/p>\n\n\n\n<p>Es en estos escenarios donde aparece la inyecci\u00f3n de Dependencias y la inversi\u00f3n de dependencias para ayudarnos a reducir el acoplamiento y brindar un poco m\u00e1s estabilidad a nuestras clases.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Inyecci\u00f3n de dependencias<\/h2>\n\n\n\n<p>La inyecci\u00f3n de dependencia desde un punto de vista te\u00f3rico es una t\u00e9cnica utilizada para suministrar las instancias de objetos a una clase en lugar de que esta ser la encargada de crearlos.&nbsp;<\/p>\n\n\n\n<p>Veamos el siguiente ejemplo:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/lh4.googleusercontent.com\/ue6T7CJb3PdGG4t0B1rv8zbkuxvmO3HGrxyZtzOhIkk5rICeSc8pXuRXy47JnH_v2oY_Tys03-OTmM9m3LOICGI9F6di5cuJwO6qHShCl3hY4groSoCLyES5vZAYEqWErnqSl5KoEzZpp4sAh8azi1Q\" alt=\"\"\/><figcaption><strong>Figura 2.0 <\/strong>Clase Librer\u00eda que tiene un m\u00e9todo para vender libro&nbsp;<\/figcaption><\/figure><\/div>\n\n\n\n<p>Observamos como la clase Library tiene un acoplamiento \u2018leve\u2019 debido a que la cantidad de clases de las que depende no son muchas.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh3.googleusercontent.com\/mwFj_L2PUKszqZXIodrqpYHPeyWp_jGhoCT2I6m5qrpt3v9EJcW2FuDfAkQG6hhvTt_AZEM5H0qfF9F6WhMB4viGYdQHnhlVGUFgMd7RXLKmt-9-613jl-1zbt2e-zERCQ_V7J9hEDTKSd8HUXA3aLw\" alt=\"\"\/><figcaption><strong>Figura 2.1 <\/strong>Clases encargada de hacer la entrega del libro y otra encargada del guardado de la venta<\/figcaption><\/figure>\n\n\n\n<p>Sin embargo, pese a ese \u2018leve\u2019 acoplamiento, se tiene la responsabilidad de instanciar el objeto y por lo tanto, aumentar m\u00e1s el acoplamiento de la clase al no solo depender de ellas sino tener la responsabilidad de su creaci\u00f3n.<\/p>\n\n\n\n<p>Por lo tanto, con la inyecci\u00f3n de dependencias buscamos que las instancias de la clases que necesitamos nos sean suministradas en nuestras clases y as\u00ed lograr evitar crear objetos en ella. Veamos c\u00f3mo lograrlo.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/lh4.googleusercontent.com\/pimkgwp-9Kk3fKAatS4qJk9BZ3VuR7viCAW_MUA3uF6xVaxfq06J0LY61AOTfsBQD1hbJMywIyFTSOJ-p77T_TAY0WspETRWAb1jdTaBA1M33P0Y3cyT7liMfzUXG-1_Fo6ojaJJdz-ZUHZFX_apeq8\" alt=\"\"\/><figcaption><strong>2.2<\/strong> LibraryService aplica inyecci\u00f3n de dependencias para suministrar las instancias necesarias para funcionar.<\/figcaption><\/figure><\/div>\n\n\n\n<p>Sin embargo, es momento de hacernos una pregunta \u00bfSe redujo el acoplamiento que ten\u00eda la clase LibraryService? la respuesta es sencillamente <strong>NO<\/strong>. Nuestro c\u00f3digo sigue estando dependiendo de las clases <strong><em>DeliveryEmail<\/em><\/strong><strong> <\/strong>e <strong><em>LibraryRepository<\/em><\/strong><strong> <\/strong>para lograr su funcionamiento.<\/p>\n\n\n\n<p>Nuestra clase (LibraryService) adicional a tener la l\u00f3gica de negocio necesaria para la venta del libro se acopla tambi\u00e9n al c\u00f3mo emitir una factura y c\u00f3mo enviar un pedido. Por lo tanto, el patr\u00f3n de dise\u00f1o inyecci\u00f3n de dependencias <em><strong>per se<\/strong><\/em> no nos ayuda a reducir el acoplamiento en nuestro software.<\/p>\n\n\n\n<p>Tenga en cuenta que existen dos formas de inyectar la dependencia: una por constructor como se vio en el ejemplo y la otra por par\u00e1metro de una funci\u00f3n que necesite de una dependencia para funcionar. <\/p>\n\n\n\n<p>Ahora veamos qu\u00e9 t\u00e9cnica nos ayudar\u00e1 a reducir el acoplamiento hacia esos m\u00f3dulos de bajo nivel necesarios en nuestra aplicaci\u00f3n para funcionar.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Inversi\u00f3n de dependencias<\/h2>\n\n\n\n<p>El principio de inversi\u00f3n de dependencias (<em>tambi\u00e9n conocido como DIP por sus siglas del ingl\u00e9s Dependency Inversion Principle<\/em>)&nbsp; forma parte de los principales principios de desarrollo orientado a objetos y dise\u00f1o; SOLID.&nbsp;<\/p>\n\n\n\n<p>DIP se define formalmente por Robert C. Mart\u00edn por primera vez a partir de las siguientes declaraciones:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li><em>Los m\u00f3dulos de alto nivel no deben depender de los m\u00f3dulos de bajo nivel. Ambos deben depender de abstracciones.<\/em><\/li><\/ol>\n\n\n\n<p>Cuando se habla de &#8216;m\u00f3dulo de alto nivel&#8217; se refiere a esas clases que tienen la l\u00f3gica de negocio y define lo que hace tu programa; estos m\u00f3dulos de alto nivel deber\u00edan ser los m\u00e1s importantes en tu aplicaci\u00f3n.&nbsp;<\/p>\n\n\n\n<p>Por otro lado est\u00e1n los m\u00f3dulos de bajo nivel que contienen aquellas clases que no est\u00e1n ligadas directamente a la l\u00f3gica del negocio como lo puede llegar a ser la persistencia de datos (SQL, NoSQL), o la comunicaci\u00f3n con un servicio externo a trav\u00e9s (rest, soap u otros mecanismos). El ideal es permitir que estos m\u00f3dulos de bajo nivel puedan ser reemplazables sin afectar la l\u00f3gica de nuestro negocio.&nbsp;<\/p>\n\n\n\n<ol class=\"wp-block-list\" start=\"2\"><li><em>Las abstracciones no deben depender de los detalles. Los detalles deben depender de abstracciones.<\/em><\/li><\/ol>\n\n\n\n<p>Para lograr esta afirmaci\u00f3n, nuestra clase ubicada en m\u00f3dulo de alto nivel depender\u00e1 de una abstracci\u00f3n; as\u00ed mismo, la clase de bajo nivel depender\u00e1 de esta abstracci\u00f3n al momento de heredar de ella. Ve\u00e1moslo en un gr\u00e1fico nuestro panorama actual:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/lh3.googleusercontent.com\/CIzs021zdgfVMtpl_T72kG5FkC1z5ypqDZKGe37Lf_tusyfwaLizcYdw5hSfKvKmHRdy6NEVvM0IvMjj6H1I7kYn-JAz24L7cyiIYNoauaJNyAW8pENyJsDatglLvHSLjT5L-q9xXm57YyeXLcXQdq8\" alt=\"\"\/><\/figure><\/div>\n\n\n\n<p><strong>2.3 <\/strong>La clase <strong>LibraryService<\/strong> tiene una relaci\u00f3n de dependencia (alto acoplamiento) hacia <strong>LibraryRepository<\/strong><\/p>\n\n\n\n<p>Los cambios de <strong>LibraryRepository <\/strong>afectar\u00e1n directamente a <strong>LibraryService, <\/strong>adicional a no poder reemplazar <strong>LibraryRepository<\/strong>&nbsp; por otra clase sin afectar a <strong>LibraryService<\/strong>. Lo anterior se podr\u00eda llamar alto acoplamiento entre componentes.&nbsp;<\/p>\n\n\n\n<p>Para reducir ese alto acoplamiento usamos <em>DIP<\/em> de la siguiente manera:<\/p>\n\n\n\n<p class=\"has-text-align-center\"><img loading=\"lazy\" decoding=\"async\" width=\"251\" height=\"281\" src=\"https:\/\/lh3.googleusercontent.com\/ks49c5WbqU-r0dQG_-9zgYaz-beBgySSuMU7cQyLSiq0znav1C6hCUijbI3PByc1oqICwpZfaXsPCJAHuAh60TpWmfvSEmILs9zWA38nTAflhu0Iorn4yM0yM-ko05YBEUPZyCt41b9Jm6m1wyMyBOw\"><br><strong>2.4 LibraryService <\/strong>ya no tiene una dependencia hacia <strong>LibraryRepository<\/strong> ahora depende de una abstracci\u00f3n y <strong>LibraryRepository <\/strong>depende tambi\u00e9n de dicha abstracci\u00f3n.&nbsp;<br><\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"523\" src=\"https:\/\/lafilosofiadelsoftware.com\/wp-content\/uploads\/2023\/02\/Captura-de-pantalla-2023-02-19-a-las-1.25.28-p.m.-1024x523.png\" alt=\"\" class=\"wp-image-228\" srcset=\"https:\/\/lafilosofiadelsoftware.com\/wp-content\/uploads\/2023\/02\/Captura-de-pantalla-2023-02-19-a-las-1.25.28-p.m.-1024x523.png 1024w, https:\/\/lafilosofiadelsoftware.com\/wp-content\/uploads\/2023\/02\/Captura-de-pantalla-2023-02-19-a-las-1.25.28-p.m.-300x153.png 300w, https:\/\/lafilosofiadelsoftware.com\/wp-content\/uploads\/2023\/02\/Captura-de-pantalla-2023-02-19-a-las-1.25.28-p.m.-768x392.png 768w, https:\/\/lafilosofiadelsoftware.com\/wp-content\/uploads\/2023\/02\/Captura-de-pantalla-2023-02-19-a-las-1.25.28-p.m.-1536x784.png 1536w, https:\/\/lafilosofiadelsoftware.com\/wp-content\/uploads\/2023\/02\/Captura-de-pantalla-2023-02-19-a-las-1.25.28-p.m..png 1614w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><figcaption><strong>2.5 LibraryService <\/strong>ahora trabaja con abstracciones (interfaces) en su c\u00f3digo y no depende de ninguna implementaci\u00f3n concreta.<\/figcaption><\/figure><\/div>\n\n\n\n<p>Aunque a simple vista pareciera que no hemos hecho gran cosa, veamos c\u00f3mo inicializamos la clase <strong>LibraryService.&nbsp;<\/strong><\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/lh5.googleusercontent.com\/Yda68K-UlAHbmtQCqaP0tutu1RKZZDKjqORNAv_PQyn-paD2j0JkXMrwRYILazPEGUbbWsFbEMkFqNp1kTL-kXgAt9k0OgNPoTwTWE8-Aa6S09Bo12NElqDtc2mP9gYbzYcHSad3knEdApxm8NSFOls\" alt=\"\"\/><figcaption><strong>2.6 <\/strong>Inicializaci\u00f3n de la clase <strong>LibraryService <\/strong>suministrando sus dos dependencias necesarias.<\/figcaption><\/figure><\/div>\n\n\n\n<p>A diferencia de antes (cuando no ten\u00edamos <em>DIP) <\/em>donde solo pod\u00edamos pasar las dos implementaciones<em>; <\/em>ahora podremos colocar cualquier clase en nuestra inicializaci\u00f3n siempre y cuando implemente la abstracci\u00f3n necesaria que tiene <strong>LibraryService.<\/strong><\/p>\n\n\n\n<p>Tenga en cuenta lo siguiente:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li><strong><em>La Inversi\u00f3n de dependencias necesita del patr\u00f3n inyecci\u00f3n de dependencias para funcionar. En otras palabras: No se puede tener Inversi\u00f3n de dependencia sin inyecci\u00f3n de dependencia pero si es posible tener inyecci\u00f3n de dependencia sin hacer inversi\u00f3n de dependencia.<\/em><\/strong><\/li><li>Aplicar Inversi\u00f3n de dependencia reduce el acoplamiento entre componentes.<\/li><li>Aplicar <strong>SOLO<\/strong> inyecci\u00f3n de dependencia sin hacer inversi\u00f3n NO reduce el acoplamiento.<\/li><li><strong>No siempre debemos tener inversi\u00f3n de dependencia en nuestro c\u00f3digo<\/strong>, a veces es solo necesario tener inyecci\u00f3n de dependencia. Busca aplicar Inversi\u00f3n en el momento que veas que vas a interactuar con otro m\u00f3dulo, si es una relaci\u00f3n entre clases del mismo m\u00f3dulo bastar\u00e1 con hacer inyecci\u00f3n.<\/li><\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Inversi\u00f3n de Control<\/h2>\n\n\n\n<p>La inversi\u00f3n de control es un principio de dise\u00f1o de software en el cual se busca que el framework tome el control en el flujo del ciclo de vida de una petici\u00f3n.<\/p>\n\n\n\n<p>Mir\u00e9moslo de esta forma: En un flujo normal cuando est\u00e1s enfermo y necesitas de un doctor, t\u00fa vas al doctor para que te atienda. Si se invierte el control, en el momento que est\u00e1s enfermo es el doctor quien viene a ti a atenderte.<\/p>\n\n\n\n<p>La met\u00e1fora anterior, enfocada al ejemplo que estamos trabajando, busca conseguir que en lugar de inicializar instancias en nuestras clases e inyectar las dependencias manualmente sea el framework quien se encargue de dicha actividad, es decir, lo visto en la imagen <strong>2.6 <\/strong>de crear un objeto y pasar las dependencias ya no ser\u00e1 necesario; porque ser\u00e1 el framework quien determine que t\u00fa necesitas una instancia de determinada clase y el mismo framework se encargar\u00e1 de suministrar las dependencias necesarias.<\/p>\n\n\n\n<p>Para lograr lo anterior, la inversi\u00f3n de control trabaja con un contenedor donde almacenar\u00e1 todas las clases con las que puede manejar el ciclo de vida del objeto y sus dependencias asociadas.<\/p>\n\n\n\n<p>Entonces podemos decir:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>La Inversi\u00f3n de control funciona gracias a la inyecci\u00f3n de dependencia.<\/li><li>La inversi\u00f3n de control no reduce en <strong>NADA<\/strong> el acoplamiento entre componentes, este solo se encarga de gestionar instancias y el ciclo de vida de los objetos.<\/li><li>Se puede tener Inversi\u00f3n de control <strong>sin<\/strong> hacer Inversi\u00f3n de dependencia.<\/li><li>Se puede hacer Inversi\u00f3n de control aplicando tambi\u00e9n inversi\u00f3n de dependencia, aplica la misma regla explicada en el punto 4 de inversi\u00f3n de dependencia.&nbsp;<\/li><\/ol>\n\n\n\n<p><\/p>\n\n\n\n<p>Autores: <a href=\"https:\/\/co.linkedin.com\/in\/daniel-saavedra-1997ba27\" title=\"Daniel Saavedra\">Daniel Saavedra<\/a>, <a href=\"https:\/\/co.linkedin.com\/in\/richard-lion\" title=\"Richard Lion Guevara\">Richard Lion Guevara<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Durante muchos a\u00f1os se han confundido los t\u00e9rminos de inyecci\u00f3n de dependencias, inversi\u00f3n de dependencias e inversi\u00f3n de control, llegando a existir publicaciones donde las describen como lo mismo, sin\u00f3nimos o incluso afirmando que una es mejor que otra. Este art\u00edculo busca responder las preguntas de \u00bfQu\u00e9 son? \u00bfSon lo mismo? \u00bfCu\u00e1l debe aplicarse en mi c\u00f3digo?.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[2],"tags":[8,35,27,28,34,11,29,31,30,19,20],"class_list":["post-217","post","type-post","status-publish","format-standard","hentry","category-clean-architecture","tag-clean-code","tag-computer-society-unisabana","tag-id","tag-idp","tag-ieeeunisabana","tag-ingeniera-de-software","tag-inversion-control","tag-inversion-dependencia","tag-inyeccion-dependencia","tag-software-engineer","tag-solid"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/lafilosofiadelsoftware.com\/index.php\/wp-json\/wp\/v2\/posts\/217"}],"collection":[{"href":"https:\/\/lafilosofiadelsoftware.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/lafilosofiadelsoftware.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/lafilosofiadelsoftware.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/lafilosofiadelsoftware.com\/index.php\/wp-json\/wp\/v2\/comments?post=217"}],"version-history":[{"count":13,"href":"https:\/\/lafilosofiadelsoftware.com\/index.php\/wp-json\/wp\/v2\/posts\/217\/revisions"}],"predecessor-version":[{"id":243,"href":"https:\/\/lafilosofiadelsoftware.com\/index.php\/wp-json\/wp\/v2\/posts\/217\/revisions\/243"}],"wp:attachment":[{"href":"https:\/\/lafilosofiadelsoftware.com\/index.php\/wp-json\/wp\/v2\/media?parent=217"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/lafilosofiadelsoftware.com\/index.php\/wp-json\/wp\/v2\/categories?post=217"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/lafilosofiadelsoftware.com\/index.php\/wp-json\/wp\/v2\/tags?post=217"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}