El último de los principios básicos de programación orientada a objetos nos insta a desacoplar módulos de software, a través de las siguientes directrices:
La idea detrás de este principio es aislar nuestras clases detrás de un límite (las abstracciones) para que, en caso de que las implementaciones concretas que están detrás sufran modificaciones nuestra clase siga funcionando correctamente. Esto es algo que suena muy bonito pero que quizá no sea tan sencillo de entender. ¿Qué tal si proponemos un ejemplo?
Vamos a utilizar como ejemplo un robot periodista que se encarga de difundir noticias. El código sería el siguiente:
class NewsRobot
def broadcast(news)
FantasicBlog.new.print(news)
end
end
class FantasicBlog
def post(news)
puts news
end
end
robot_emilio = NewsRobot.new
robot_emilio.broadcast("New great article fom codigojose.com!")Teniendo este código como referencia, nuestro robot funcionará perfectamente y difundirá las noticias en nuestro blog sin ningún problema, pero…
¿Y si mañana quisiéramos publicar las noticias en otros medios, ocmo por ejemplo Twitter, periódicos, otros blog? Nos veríamos obligados a modificar nuestra clase NewsRobot (que vendría a ser la implementación de alto nivel) porque depende directamente y de forma exclusiva de FantasticBlog. ¿Cómo podemos solucionar este problema? Utilizando la inyección de dependencias.
class NewsRobot
def broadcast(news, platform = FantasticBlog)
platform.new.post(news)
end
endSi observamos el nuevo bloque de código veremos que la modificación realizada es la injección de la dependencia platform. Esta abstracción nos permite poder emitir nuestras notificas en diferentes medios sin que nuestra clase NewsRobot tenga que verse afectada, por lo que podríamos hacer lo siguiente:
class NewsRobot
def broadcast(news, platform = FantasticBlog)
platform.new.post(news)
end
end
class FantasicBlog
def post(news)
puts news
end
end
class AnotherBlog
def post(news)
puts news
end
end
class Twitter
def post(news)
tweet news
end
end
robot_emilio = NewsRobot.new
robot_emilio.broadcast("New great article fom codigojose.com!") # Utilizará la plataforma por defecto FantasticBlog
robot_emilio.broadcast("New great article fom codigojose.com!", AnotherBlog)
robot_emilio.broadcast("New great article fom codigojose.com!", Twitter)Como vemos, hemos conseguido difundir noticias en varios medios sin tener que realizar modificaciones sobre nuestra clase NewsRobot debido a que ésta ya no depende de ninguna implementación externa. Esta implementación se vuelve mucho más flexible, robusta y es mucho más sencillo realizar pruebas sobre la misma. Si ahora quisiéramos realizar una serie de pruebas unitarias sobre nuestro NewsRobot solo tendríamos que hacer un Mock de cualquier plataforma para comprobar el correcto funcionamiento.
buenas prácticas, desarrollo, SOLID
[…] Dependency Inversion – SOLID V […]