{"id":830,"date":"2022-02-25T00:00:00","date_gmt":"2022-02-24T23:00:00","guid":{"rendered":"https:\/\/programaraciegas.net\/?p=830"},"modified":"2022-01-03T19:02:56","modified_gmt":"2022-01-03T18:02:56","slug":"solid-principio-de-inversion-de-dependencias-o-dependency-inversion-principle","status":"publish","type":"post","link":"https:\/\/programaraciegas.net\/?p=830","title":{"rendered":"SOLID: Principio de inversi\u00f3n de dependencias o Dependency inversion principle"},"content":{"rendered":"<p>Este es el quinto y \u00faltimo <a href=\"https:\/\/programaraciegas.net\/?p=816\">principio de programaci\u00f3n SOLID<\/a>.<\/p>\n<h2>Significado<\/h2>\n<p>Este principio establece que las clases de alto nivel no deber\u00edan depender de las clases de bajo nivel. En su lugar las clases deber\u00edan depender de las abstracciones.<\/p>\n<p>Adem\u00e1s las abstracciones no deben depender de los detalles sino que los detalles deben depender de las abstracciones.<\/p>\n<p>Con este principio se busca reducir las dependencias entre m\u00f3dulos buscando un menor nivel de acoplamiento entre clases.<\/p>\n<p>Esto es indispensable en proyectos con muchos m\u00f3dulos en los que es necesario utilizar inyecci\u00f3n de dependencias.<\/p>\n<h2>Ejemplo<\/h2>\n<p>Veamos el siguiente ejemplo en el que en nuestro proyecto tenemos una clase que nos permite el acceso a la base de datos en general que llamaremos CargadorDesdeBaseDeDatos y tenemos una clase PersonaEnBaseDeDatos que nos permite cargar datos de la clase Persona.<\/p>\n<p>Para ello la clase\u00a0PersonaEnBaseDeDatos tiene una propiedad de tipo CargadorDesdeBaseDeDatos que se utiliza como driver de acceso al sistema de almacenamiento de bases de datos de la aplicaci\u00f3n.<\/p>\n<p>\u00a0<\/p>\n<p><span style=\"font-family: Menlo; font-size: 12px;\">class CargadorDesdeBaseDeDatos {<\/span><\/p>\n<p><span style=\"font-family: Menlo; font-size: 12px;\">\u00a0 \u00a0 funcion obtenerDatosGenerales()<\/span><\/p>\n<p><span style=\"font-family: Menlo; font-size: 12px;\">}<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span style=\"font-family: Menlo; font-size: 12px;\">class PersonaEnBaseDeDatos {<\/span><\/p>\n<p><span style=\"font-family: Menlo; font-size: 12px;\">\u00a0 \u00a0 propiedad datos =\u00a0CargadorDesdeBaseDeDatos()<\/span><\/p>\n<p><span style=\"font-family: Menlo; font-size: 12px;\">\u00a0 \u00a0 propiedad listaDePersonas<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span style=\"font-family: Menlo; font-size: 12px;\">\u00a0 \u00a0 funcion cargaDatos() {<\/span><\/p>\n<p><span style=\"font-family: Menlo; font-size: 12px;\">\u00a0 \u00a0 \u00a0 \u00a0 listaGeneral =\u00a0datos.obtenerDatosGenerales()<\/span><\/p>\n<p><span style=\"font-family: Menlo; font-size: 12px;\">\u00a0 \u00a0 \u00a0 \u00a0 listaDePersonas = convertirDatosGeneralesEnDatosDePersonas(listaGeneral)<\/span><\/p>\n<p><span style=\"font-family: Menlo; font-size: 12px;\">\u00a0 \u00a0 }<\/span><\/p>\n<p><span style=\"font-family: Menlo; font-size: 12px;\">}<\/span><\/p>\n<p>\u00a0<\/p>\n<p>En el ejemplo en la clase\u00a0PersonaEnBaseDeDatos dentro de la funci\u00f3n\u00a0cargaDatos() hay una dependencia de la clase\u00a0AccesoABaseDeDatos. Esto es un problema porque si un d\u00eda necesitamos cambiar de sistema de base de datos o de obtener datos de Internet tendr\u00edamos que modificar demasiado c\u00f3digo ya que ambas clases tienen una fuerte dependencia entre ellas.<\/p>\n<p>Imaginemos por ejemplo que queremos incluir la opci\u00f3n de descargar los datos desde una API rest en Internet. El c\u00f3digo se complicar\u00eda demasiado en todas las clases.<\/p>\n<h2>Soluci\u00f3n<\/h2>\n<p>La soluci\u00f3n a este problema es utilizar una abstracci\u00f3n que permita identificar un acceso a datos mediante una interface o protocolo, dependiendo de las posibilidades del lenguaje de programaci\u00f3n.<\/p>\n<p>Veamos el c\u00f3digo.<\/p>\n<p>\u00a0<\/p>\n<p><span style=\"font-family: Menlo;\">interface\u00a0AccesoADatos {<\/span><\/p>\n<p><span style=\"font-family: Menlo;\">\u00a0 \u00a0 funcion cargaDatosDePersonas<\/span><\/p>\n<p><span style=\"font-family: Menlo;\">}<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span style=\"font-family: Menlo;\"><span style=\"font-size: 12px;\">class CargadorDesdeBaseDeDatos Implementa\u00a0<\/span>AccesoADatos\u00a0<span style=\"font-size: 12px;\">{<\/span><\/span><\/p>\n<p><span style=\"font-family: Menlo;\"><span style=\"font-size: 12px;\">\u00a0 \u00a0 propiedad listaDeDatos<\/span><\/span><\/p>\n<p>\u00a0<\/p>\n<p><span style=\"font-family: Menlo; font-size: 12px;\">\u00a0 \u00a0 funcion obtenerDatosGeneralesDesdeMySQL() {<\/span><\/p>\n<p><span style=\"font-family: Menlo; font-size: 12px;\">\u00a0 \u00a0 \u00a0 \u00a0 listaDeDatos = cargaDesdeMySQL()<\/span><\/p>\n<p><span style=\"font-family: Menlo; font-size: 12px;\">\u00a0 \u00a0 }<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span style=\"font-family: Menlo;\">\u00a0 \u00a0 funcion cargaDatosDePersonas() {<\/span><\/p>\n<p><span style=\"font-family: Menlo;\"><span style=\"font-size: 12px;\">\u00a0 \u00a0 \u00a0 \u00a0 obtenerDatosGeneralesDesdeMySQL()<\/span><\/span><\/p>\n<p><span style=\"font-family: Menlo;\">\u00a0 \u00a0 \u00a0 \u00a0 return convertirATipoPersona(<span style=\"font-size: 12px;\">listaDeDatos)<\/span><\/span><\/p>\n<p><span style=\"font-family: Menlo;\">\u00a0 \u00a0 }<\/span><\/p>\n<p><span style=\"font-family: Menlo; font-size: 12px;\">}<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span style=\"font-family: Menlo;\"><span style=\"font-size: 12px;\">class CargadorDesdeInternet Implementa\u00a0<\/span>AccesoADatos\u00a0<span style=\"font-size: 12px;\">{<\/span><\/span><\/p>\n<p><span style=\"font-family: Menlo;\"><span style=\"font-size: 12px;\">\u00a0 \u00a0 propiedad listaDeDatos<\/span><\/span><\/p>\n<p><span style=\"font-family: Menlo;\">\u00a0<\/span><\/p>\n<p><span style=\"font-family: Menlo; font-size: 12px;\">\u00a0 \u00a0 funcion obtenerDatosGeneralesDeInternet() {<\/span><\/p>\n<p><span style=\"font-family: Menlo; font-size: 12px;\">\u00a0 \u00a0 \u00a0 \u00a0 listaDeDatos = descargaDeLaNube()<\/span><\/p>\n<p><span style=\"font-family: Menlo; font-size: 12px;\">\u00a0 \u00a0 }<\/span><\/p>\n<p><span style=\"font-family: Menlo;\">\u00a0<\/span><\/p>\n<p><span style=\"font-family: Menlo;\">\u00a0 \u00a0 funcion cargaDatosDePersonas() {<\/span><\/p>\n<p><span style=\"font-family: Menlo;\"><span style=\"font-size: 12px;\">\u00a0 \u00a0 \u00a0 \u00a0 obtenerDatosGeneralesDeInternet()<\/span><\/span><\/p>\n<p><span style=\"font-family: Menlo;\">\u00a0 \u00a0 \u00a0 \u00a0 return convertirATipoPersona(<span style=\"font-size: 12px;\">listaDeDatos)<\/span><\/span><\/p>\n<p><span style=\"font-family: Menlo;\">\u00a0 \u00a0 }<\/span><\/p>\n<p><span style=\"font-family: Menlo;\"><span style=\"font-size: 12px;\">}<\/span><\/span><\/p>\n<p><span style=\"font-family: Menlo;\">\u00a0<\/span><\/p>\n<p><span style=\"font-family: Menlo; font-size: 12px;\">class PersonaEnBaseDeDatos {<\/span><\/p>\n<p><span style=\"font-family: Menlo;\"><span style=\"font-size: 12px;\">\u00a0 \u00a0 propiedad datos =\u00a0<\/span>AccesoADatos<\/span><\/p>\n<p><span style=\"font-family: Menlo; font-size: 12px;\">\u00a0 \u00a0 propiedad listaDePersonas<\/span><\/p>\n<p><span style=\"font-family: Menlo;\">\u00a0<\/span><\/p>\n<p><span style=\"font-family: Menlo;\">\u00a0 \u00a0 funcion constructor(inyeccion: AccesoADatos) {<\/span><\/p>\n<p><span style=\"font-family: Menlo;\">\u00a0 \u00a0 \u00a0 \u00a0 datos = inyeccion<\/span><\/p>\n<p><span style=\"font-family: Menlo;\">\u00a0 \u00a0 }<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span style=\"font-family: Menlo; font-size: 12px;\">\u00a0 \u00a0 funcion cargaDatos() {<\/span><\/p>\n<p><span style=\"font-family: Menlo;\"><span style=\"font-size: 12px;\">\u00a0 \u00a0 \u00a0 \u00a0 listaDePersonas = datos.<\/span>cargaDatosDePersonas()<\/span><\/p>\n<p><span style=\"font-family: Menlo; font-size: 12px;\">\u00a0 \u00a0 }<\/span><\/p>\n<p><span style=\"font-family: Menlo; font-size: 12px;\">}<\/span><\/p>\n<p>\u00a0<\/p>\n<p>Con esta soluci\u00f3n podemos inyectar cualquier clase del tipo interface AccesoADatos en el constructor de la clase PersonaEnBaseDeDatos. De esta forma podemos cambiar c\u00f3mo accedemos a esos datos inyectando cualquier clase que implemente la interfaz AccesoADatos consiguiendo un mayor nivel de desacoplamiento entre clases. De esta forma tanto el m\u00f3dulo de alto nivel como el de bajo nivel dependen de abstracciones, por lo que se cumple el principio de inversi\u00f3n de dependencias y adem\u00e1s, esto nos obliga a cumplir <a href=\"https:\/\/programaraciegas.net\/?p=826\">el principio de Liskov<\/a>, ya que las clases que acceder\u00e1n a cualquier base de datos son intercambiables entre ellas ya que todas implementan la interfaz de AccesoADatos.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Este es el quinto y \u00faltimo principio de programaci\u00f3n SOLID. Significado Este principio establece que las clases de alto nivel no deber\u00edan depender de las clases de bajo nivel. En su lugar las clases deber\u00edan depender de las abstracciones. Adem\u00e1s las abstracciones no deben depender de los detalles sino que los detalles deben depender de &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/programaraciegas.net\/?p=830\" class=\"more-link\">Continuar leyendo<span class=\"screen-reader-text\"> \u00abSOLID: Principio de inversi\u00f3n de dependencias o Dependency inversion principle\u00bb<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8,6],"tags":[87,386,388],"class_list":["post-830","post","type-post","status-publish","format-standard","hentry","category-metodologiafilosofia","category-programacion","tag-programacion-2","tag-solid","tag-teoria"],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/programaraciegas.net\/index.php?rest_route=\/wp\/v2\/posts\/830","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/programaraciegas.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/programaraciegas.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/programaraciegas.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/programaraciegas.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=830"}],"version-history":[{"count":0,"href":"https:\/\/programaraciegas.net\/index.php?rest_route=\/wp\/v2\/posts\/830\/revisions"}],"wp:attachment":[{"href":"https:\/\/programaraciegas.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=830"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/programaraciegas.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=830"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/programaraciegas.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=830"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}