{"id":20417,"date":"2022-02-28T00:08:56","date_gmt":"2022-02-27T22:08:56","guid":{"rendered":"https:\/\/www.hiberus.com\/crecemos-contigo\/?p=20417"},"modified":"2023-11-28T09:13:16","modified_gmt":"2023-11-28T08:13:16","slug":"del-codigo-espagueti-a-la-arquitectura-hexagonal","status":"publish","type":"post","link":"https:\/\/www.hiberus.com\/crecemos-contigo\/del-codigo-espagueti-a-la-arquitectura-hexagonal\/","title":{"rendered":"Del c\u00f3digo espagueti a la arquitectura hexagonal"},"content":{"rendered":"<p>A d\u00eda de hoy, el software es <strong>ubicuo<\/strong>. \u00bfQueremos chatear con un amigo a miles de kil\u00f3metros? Recurrimos al software. \u00bfQueremos comprar online? Recurrimos al software. \u00bfQueremos escuchar m\u00fasica? Recurrimos al software. Por esto, en este post voy a escribir sobre <strong>arquitecturas de software<\/strong>, desde el<strong> c\u00f3digo espagueti<\/strong> hasta la tan nombrada <strong>arquitectura hexagonal<\/strong>.<\/p>\n<h3>La arquitectura de software<\/h3>\n<p>Todo software tiene una arquitectura que estar\u00e1 mejor o peor dise\u00f1ada, pero todo software tiene una serie de elementos que lo conforman y que logran que sea de una determinada manera. Evidentemente, la fase de dise\u00f1o arquitectural ha de ser intencional si la resoluci\u00f3n de nuestros problemas no es trivial. Dise\u00f1ar es una tarea complicada, puesto que <strong>es necesario crear software que resuelva problemas<\/strong>.<\/p>\n<blockquote><p>Al fin y al cabo, es lo que el ser humano ha desarrollado a lo largo de la historia: herramientas que permiten hacernos la vida m\u00e1s f\u00e1cil.<\/p><\/blockquote>\n<p>Es imposible (o muy complicado, pues en este sector no se deber\u00edan hacer afirmaciones tan categ\u00f3ricas) hacer el software perfecto, pero, al menos, hay que tratar de dise\u00f1ar e implementar software que maximice las <strong>caracter\u00edsticas de calidad<\/strong>: rendimiento, escalabilidad, capacidad para ser evaluable, mantenibilidad, eficiencia, robustez, resiliencia, efectividad, flexibilidad, funcionalidad, portabilidad&#8230; Es por esto que es recomendable proponer<strong> dise\u00f1os t\u00e9cnicos<\/strong> entre varias personas (el dise\u00f1o es una tarea colegiada), ya que esto implica discutir distintos puntos de vista y abarcar m\u00e1s casu\u00edsticas que las que podr\u00eda abarcar una sola persona.<\/p>\n<h2>El c\u00f3digo espagueti<\/h2>\n<p><span class=\"TextRun SCXW95307298 BCX0\" lang=\"ES-ES\" xml:lang=\"ES-ES\" data-contrast=\"auto\"><span class=\"NormalTextRun SCXW95307298 BCX0\">He comentado antes, literalmente: \u201cla fase de dise\u00f1o arquitectural ha de ser intencional\u201d. El c\u00f3digo espagueti no <\/span><span class=\"NormalTextRun SCXW95307298 BCX0\">est\u00e1 dise\u00f1ado concienzudamente, aunque, <strong>a veces, cumple sus prop\u00f3sitos<\/strong>. Siempre que pienso en el c\u00f3digo espagueti se me viene a la cabeza <\/span><span class=\"NormalTextRun SCXW95307298 BCX0\">una improvisaci\u00f3n musical. <\/span><span class=\"NormalTextRun SCXW95307298 BCX0\">Por un lad<\/span><span class=\"NormalTextRun SCXW95307298 BCX0\">o, e<\/span><span class=\"NormalTextRun SCXW95307298 BCX0\">n el mundo de la m\u00fasica<\/span><span class=\"NormalTextRun SCXW95307298 BCX0\"> en particular y del arte en general,<\/span> <span class=\"NormalTextRun SCXW95307298 BCX0\">la espontaneidad puede ser una aliada ya que <\/span><span class=\"NormalTextRun SCXW95307298 BCX0\">facilita la transmisi\u00f3n de tu \u201cyo m\u00e1s interior\u201d, de tu personalidad&#8230; Dicho de otra manera, espontaneidad puede ser confundida con <\/span><strong><span class=\"NormalTextRun SCXW95307298 BCX0\">\u201c<\/span><span class=\"NormalTextRun SCXW95307298 BCX0\">creatividad en tiempo real<\/span><span class=\"NormalTextRun SCXW95307298 BCX0\">\u201d<\/span><\/strong><span class=\"NormalTextRun SCXW95307298 BCX0\">. E<\/span><span class=\"NormalTextRun SCXW95307298 BCX0\">sto se percibe socialmente como bueno y de calidad. <\/span><\/span><\/p>\n<p><span class=\"TextRun SCXW95307298 BCX0\" lang=\"ES-ES\" xml:lang=\"ES-ES\" data-contrast=\"auto\"><span class=\"NormalTextRun SCXW95307298 BCX0\">Sin embargo, e<\/span><span class=\"NormalTextRun SCXW95307298 BCX0\">n el mundo del software pasa un poco lo mismo que en el mundo de la arquitectura tradicional (s\u00ed, la de los puentes). \u00bfPasar\u00edas por un puente improvisado<\/span><span class=\"NormalTextRun SCXW95307298 BCX0\"> que se ha dise\u00f1ado de forma accidental?<\/span><span class=\"NormalTextRun SCXW95307298 BCX0\"> \u00bf<\/span><span class=\"NormalTextRun SCXW95307298 BCX0\">U<\/span><span class=\"NormalTextRun SCXW95307298 BCX0\">tilizar\u00edas una pasarela de pago construida con c\u00f3digo espagueti?<\/span><span class=\"NormalTextRun SCXW95307298 BCX0\"> \u00bfTe subir\u00edas a un coche aut\u00f3nomo que ha programado un desarrollador \u201cen un momento de inspiraci\u00f3n\u201d?<\/span> <span class=\"NormalTextRun SCXW95307298 BCX0\">Entonces, \u00bfqu\u00e9 ocurre? \u00bfPor qu\u00e9 he empezado diciendo que <strong>a veces<\/strong> cumple sus prop\u00f3sitos? Porque es as\u00ed, en determinadas ocasiones no es necesario <\/span><span class=\"NormalTextRun SCXW95307298 BCX0\">llevar a cabo <\/span><span class=\"NormalTextRun SpellingErrorV2 SCXW95307298 BCX0\">sobreingenier\u00eda<\/span><span class=\"NormalTextRun SCXW95307298 BCX0\"> y exprimir al 100% nuestra CPU <\/span><span class=\"NormalTextRun SCXW95307298 BCX0\">fisiol\u00f3gica para resolver un problema<\/span><span class=\"NormalTextRun SCXW95307298 BCX0\">. <\/span><\/span><\/p>\n<p><span class=\"TextRun SCXW95307298 BCX0\" lang=\"ES-ES\" xml:lang=\"ES-ES\" data-contrast=\"auto\"><span class=\"NormalTextRun SCXW95307298 BCX0\">Dicho de otro modo, <\/span><span class=\"NormalTextRun SCXW95307298 BCX0\">a veces,<\/span><span class=\"NormalTextRun SCXW95307298 BCX0\"> nuestro cerebro<\/span><span class=\"NormalTextRun SCXW95307298 BCX0\"> improvisa<\/span><span class=\"NormalTextRun SCXW95307298 BCX0\"> impl\u00edcitamente<\/span> <span class=\"NormalTextRun SCXW95307298 BCX0\">una soluci\u00f3n que<\/span><span class=\"NormalTextRun SCXW95307298 BCX0\"> funciona <\/span><span class=\"NormalTextRun SCXW95307298 BCX0\">y que entra dentro de nuestros objetivos de calidad<\/span> <span class=\"NormalTextRun SCXW95307298 BCX0\">(funcionalidad, efectividad&#8230;)<\/span><span class=\"NormalTextRun SCXW95307298 BCX0\">.<\/span><span class=\"NormalTextRun SCXW95307298 BCX0\"> No obstante, nuestro cerebro no es capaz de improvisar la arquitectu<\/span><span class=\"NormalTextRun SCXW95307298 BCX0\">ra software de l<\/span><span class=\"NormalTextRun SCXW95307298 BCX0\">o<\/span><span class=\"NormalTextRun SCXW95307298 BCX0\">s grandes e-<\/span><span class=\"NormalTextRun SpellingErrorV2 SCXW95307298 BCX0\">commerce<\/span><span class=\"NormalTextRun SCXW95307298 BCX0\">, ni tampoco de un coche aut\u00f3nomo<\/span><span class=\"NormalTextRun SCXW95307298 BCX0\">. <em><strong>A nivel cognitivo es imposible para un ser humano empezar a escribir <\/strong><\/em><\/span><em><strong><span class=\"NormalTextRun SCXW95307298 BCX0\">el <\/span><span class=\"NormalTextRun SCXW95307298 BCX0\">c\u00f3digo <\/span><\/strong><\/em><span class=\"NormalTextRun SCXW95307298 BCX0\"><em><strong>de un sistema de esas caracter\u00edsticas asegurando, adem\u00e1s, que se alcanzan los objetivos de calidad especificados.<\/strong> <\/em>Es por esto que el c\u00f3digo espagueti, <\/span><span class=\"NormalTextRun SCXW95307298 BCX0\">estigmatizado y despreciado por el sector del software<\/span><span class=\"NormalTextRun SCXW95307298 BCX0\">, y al que he empezado \u00abdefendiendo\u00bb (porque, admit\u00e1moslo, <strong>dependiendo<\/strong> del problema no es tan malo), es incompatible con los productos que tenemos que desarrollar en H<\/span><span class=\"NormalTextRun SCXW95307298 BCX0\">iberus.<\/span><\/span><span class=\"EOP SCXW95307298 BCX0\" data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<h2>La arquitectura hexagonal (o arquitectura de puertos y adaptadores)<\/h2>\n<p><span class=\"TextRun SCXW263095204 BCX0\" lang=\"ES-ES\" xml:lang=\"ES-ES\" data-contrast=\"auto\"><span class=\"NormalTextRun SCXW263095204 BCX0\">Lo que se pretende con esta<strong> arquitectura limpia<\/strong> es proponer una metodolog\u00eda de dise\u00f1o para sistemas complejos que proporciona muchas <\/span><span class=\"NormalTextRun SCXW263095204 BCX0\">f<\/span><span class=\"NormalTextRun SCXW263095204 BCX0\">acilidades para obtener los objetivos de calidad mencionados.<\/span> <\/span><\/p>\n<p><span class=\"TextRun SCXW263095204 BCX0\" lang=\"ES-ES\" xml:lang=\"ES-ES\" data-contrast=\"auto\"><span class=\"NormalTextRun SCXW263095204 BCX0\">Consiste en separar el sistema en <strong>tres capas: <\/strong><\/span><\/span><\/p>\n<ul>\n<li><span class=\"TextRun SCXW263095204 BCX0\" lang=\"ES-ES\" xml:lang=\"ES-ES\" data-contrast=\"auto\"><span class=\"NormalTextRun SCXW263095204 BCX0\"><strong>infraestructura<\/strong><\/span><\/span><\/li>\n<li><span class=\"TextRun SCXW263095204 BCX0\" lang=\"ES-ES\" xml:lang=\"ES-ES\" data-contrast=\"auto\"><span class=\"NormalTextRun SCXW263095204 BCX0\"><strong>aplicaci\u00f3n <\/strong><\/span><\/span><\/li>\n<li><span class=\"TextRun SCXW263095204 BCX0\" lang=\"ES-ES\" xml:lang=\"ES-ES\" data-contrast=\"auto\"><span class=\"NormalTextRun SCXW263095204 BCX0\"><strong>dominio<\/strong><\/span><\/span><\/li>\n<\/ul>\n<p><span class=\"TextRun SCXW263095204 BCX0\" lang=\"ES-ES\" xml:lang=\"ES-ES\" data-contrast=\"auto\"><span class=\"NormalTextRun SCXW263095204 BCX0\">La palabra \u00abseparaci\u00f3n\u00bb implica, en este caso, un <strong>bajo acoplamiento<\/strong><\/span><span class=\"NormalTextRun SCXW263095204 BCX0\"> (o incluso un desacople total)<\/span> <span class=\"NormalTextRun SCXW263095204 BCX0\">entre capas, que transitivamente se convierte en una mayor mantenibilidad<\/span> <span class=\"NormalTextRun SCXW263095204 BCX0\">(responsabilidades acotadas)<\/span> <span class=\"NormalTextRun SCXW263095204 BCX0\">y una mayor <\/span><span class=\"NormalTextRun CommentStart CommentHighlightPipeRest CommentHighlightRest SCXW263095204 BCX0\">capacidad para ser evaluable <\/span><span class=\"NormalTextRun CommentHighlightPipeRest SCXW263095204 BCX0\">(<\/span><span class=\"NormalTextRun SpellingErrorV2 SCXW263095204 BCX0\">mocks<\/span><span class=\"NormalTextRun SCXW263095204 BCX0\"> y posibilidad de realizar pruebas unitarias<\/span><span class=\"NormalTextRun SCXW263095204 BCX0\">)<\/span><span class=\"NormalTextRun SCXW263095204 BCX0\">. Adem\u00e1s, tambi\u00e9n favorece la <strong>alta cohesi\u00f3n<\/strong>. Para que el dise\u00f1o sea correcto y no desemboque en una \u201carquitectura de puertos, adaptadores y espaguetis\u201d es necesario <\/span><span class=\"NormalTextRun SCXW263095204 BCX0\"><strong>respetar el orden de las capas<\/strong>. <\/span><\/span><\/p>\n<p><span class=\"TextRun SCXW263095204 BCX0\" lang=\"ES-ES\" xml:lang=\"ES-ES\" data-contrast=\"auto\"><span class=\"NormalTextRun CommentStart CommentHighlightPipeRest CommentHighlightRest SCXW263095204 BCX0\">Los o<\/span><span class=\"NormalTextRun CommentHighlightRest SCXW263095204 BCX0\">bjetos de la capa de dominio<\/span><span class=\"NormalTextRun CommentHighlightRest SCXW263095204 BCX0\"> y aplicaci\u00f3n<\/span><span class=\"NormalTextRun CommentHighlightRest SCXW263095204 BCX0\"> no deber\u00edan utilizar <\/span><span class=\"NormalTextRun CommentHighlightRest SCXW263095204 BCX0\">objetos de la capa de<\/span><span class=\"NormalTextRun CommentHighlightRest SCXW263095204 BCX0\"> infraestructura<\/span><span class=\"NormalTextRun CommentHighlightRest SCXW263095204 BCX0\">, al igual que los objetos de la capa de dominio no deber\u00edan utilizar objetos de la capa de aplicaci\u00f3n. Dicho de otra manera, las dependencias van de \u00abfuera\u00bb hacia \u00abdentro\u00bb.<\/span><\/span><\/p>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-20419 aligncenter\" src=\"https:\/\/www.hiberus.com\/crecemos-contigo\/wp-content\/uploads\/2022\/02\/hexagono-300x273.png\" alt=\"\" width=\"300\" height=\"273\" srcset=\"https:\/\/www.hiberus.com\/crecemos-contigo\/wp-content\/uploads\/2022\/02\/hexagono-300x273.png 300w, https:\/\/www.hiberus.com\/crecemos-contigo\/wp-content\/uploads\/2022\/02\/hexagono-768x700.png 768w, https:\/\/www.hiberus.com\/crecemos-contigo\/wp-content\/uploads\/2022\/02\/hexagono-360x328.png 360w, https:\/\/www.hiberus.com\/crecemos-contigo\/wp-content\/uploads\/2022\/02\/hexagono.png 785w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p><span class=\"TextRun SCXW151128995 BCX0\" lang=\"ES-ES\" xml:lang=\"ES-ES\" data-contrast=\"auto\"><span class=\"NormalTextRun SCXW151128995 BCX0\">Aunque se suele representar como forma de hex\u00e1gono (de ah\u00ed su nombre), realmente no limita el n\u00famero de interacciones entre las capas <span class=\"TextRun SCXW263095204 BCX0\" lang=\"ES-ES\" xml:lang=\"ES-ES\" data-contrast=\"auto\"><span class=\"NormalTextRun SCXW263095204 BCX0\">(que sea un hex\u00e1gono no un cuadrado o un oct\u00f3gono es casualidad)<\/span><\/span>.<\/span><span class=\"NormalTextRun SCXW151128995 BCX0\"> De esta manera, <strong>cada lado del pol\u00edgono ser\u00eda un puerto al que nos podr\u00edamos conectar a trav\u00e9s de un adaptador<\/strong><\/span><span class=\"NormalTextRun SCXW151128995 BCX0\">. <\/span><\/span><\/p>\n<p><span class=\"TextRun SCXW151128995 BCX0\" lang=\"ES-ES\" xml:lang=\"ES-ES\" data-contrast=\"auto\"><span class=\"NormalTextRun SCXW151128995 BCX0\">A<\/span><span class=\"NormalTextRun SCXW151128995 BCX0\">lgunos ejemplos:<\/span><\/span><span class=\"EOP SCXW151128995 BCX0\" data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<ul>\n<li>Implementamos un\u00a0<strong>adaptador<\/strong> (e.g. clase UserController) en la capa de infraestructura para conectarnos al <strong>puerto<\/strong> HTTP de nuestro sistema.<\/li>\n<li><span class=\"TextRun SCXW49580121 BCX0\" lang=\"ES-ES\" xml:lang=\"ES-ES\" data-contrast=\"auto\"><span class=\"NormalTextRun SCXW49580121 BCX0\">Este controlador\/adaptador necesitar\u00e1 <\/span><span class=\"NormalTextRun SCXW49580121 BCX0\">utilizar <\/span><span class=\"NormalTextRun SCXW49580121 BCX0\">un <\/span><span class=\"NormalTextRun SCXW49580121 BCX0\">\u201ccas<\/span><span class=\"NormalTextRun SCXW49580121 BCX0\">o <\/span><span class=\"NormalTextRun SCXW49580121 BCX0\">de uso\u201d <\/span><span class=\"NormalTextRun SCXW49580121 BCX0\">de la capa<\/span><span class=\"NormalTextRun SCXW49580121 BCX0\"> de<\/span><span class=\"NormalTextRun SCXW49580121 BCX0\"> aplicaci\u00f3n<\/span><span class=\"NormalTextRun SCXW49580121 BCX0\"> (<\/span><span class=\"NormalTextRun SpellingErrorV2 SCXW49580121 BCX0\">e.g<\/span><span class=\"NormalTextRun SCXW49580121 BCX0\">. <\/span><span class=\"NormalTextRun SCXW49580121 BCX0\">interfaz<\/span> <span class=\"NormalTextRun SpellingErrorV2 SCXW49580121 BCX0\">UserS<\/span><span class=\"NormalTextRun SpellingErrorV2 SCXW49580121 BCX0\">ignIn<\/span><span class=\"NormalTextRun SCXW49580121 BCX0\"> y clase <\/span><span class=\"NormalTextRun SpellingErrorV2 SCXW49580121 BCX0\">UserS<\/span><span class=\"NormalTextRun SpellingErrorV2 SCXW49580121 BCX0\">ignIn<\/span><span class=\"NormalTextRun SpellingErrorV2 SCXW49580121 BCX0\">Impl<\/span><span class=\"NormalTextRun SCXW49580121 BCX0\">)<\/span><span class=\"NormalTextRun SCXW49580121 BCX0\"> para registrar un usuario<\/span><span class=\"NormalTextRun SCXW49580121 BCX0\">.<\/span> <span class=\"NormalTextRun SCXW49580121 BCX0\">He definido una interfaz y una clase que la implementa ya que he seguido <\/span><span class=\"NormalTextRun SCXW49580121 BCX0\">el <strong>Principio de Inversi\u00f3n de Dependencias<\/strong><\/span><span class=\"NormalTextRun SCXW49580121 BCX0\"> (la D de los principios SOLID). Este principio <\/span><span class=\"NormalTextRun SCXW49580121 BCX0\">se basa en que lo mejor es <strong>acoplarse a contratos<\/strong> (<\/span><span class=\"NormalTextRun SpellingErrorV2 SCXW49580121 BCX0\">UserSignIn<\/span><span class=\"NormalTextRun SCXW49580121 BCX0\">) y <strong>no a implementaciones concretas<\/strong> (<\/span><span class=\"NormalTextRun SpellingErrorV2 SCXW49580121 BCX0\">UserS<\/span><span class=\"NormalTextRun SpellingErrorV2 SCXW49580121 BCX0\">ignIn<\/span><span class=\"NormalTextRun SpellingErrorV2 SCXW49580121 BCX0\">Impl<\/span><span class=\"NormalTextRun SCXW49580121 BCX0\">)<\/span><span class=\"NormalTextRun SCXW49580121 BCX0\">. En este caso, el puerto ser\u00eda la interfaz, mientras que el adaptador ser\u00eda la implementaci\u00f3n concreta<\/span><span class=\"NormalTextRun SCXW49580121 BCX0\">.<\/span><\/span><\/li>\n<li><span class=\"TextRun SCXW107706755 BCX0\" lang=\"ES-ES\" xml:lang=\"ES-ES\" data-contrast=\"auto\"><span class=\"NormalTextRun SCXW107706755 BCX0\">Este <\/span><span class=\"NormalTextRun SCXW107706755 BCX0\">caso de uso <\/span><span class=\"NormalTextRun SCXW107706755 BCX0\">de la capa de aplicaci\u00f3n necesitar\u00e1 crear una <strong>entidad<\/strong> usuario (<\/span><span class=\"NormalTextRun SpellingErrorV2 SCXW107706755 BCX0\">e.g<\/span><span class=\"NormalTextRun SCXW107706755 BCX0\">. clase <\/span><span class=\"NormalTextRun SpellingErrorV2 SCXW107706755 BCX0\">User<\/span><span class=\"NormalTextRun SCXW107706755 BCX0\">) y almacenarla en u<\/span><span class=\"NormalTextRun SCXW107706755 BCX0\">n <strong>repositorio<\/strong> (<\/span><span class=\"NormalTextRun SpellingErrorV2 SCXW107706755 BCX0\">e.g<\/span><span class=\"NormalTextRun SCXW107706755 BCX0\">. interfaz <\/span><span class=\"NormalTextRun SpellingErrorV2 SCXW107706755 BCX0\">UserRepository<\/span><span class=\"NormalTextRun SCXW107706755 BCX0\">). Estos dos \u00faltimos elementos mencionados <\/span><span class=\"NormalTextRun SCXW107706755 BCX0\">pertenecen a la <strong>capa de dominio<\/strong>, el <strong>n\u00facleo del sistema en una arquitectura limpia<\/strong><\/span><span class=\"NormalTextRun SCXW107706755 BCX0\">. Recalco que es el n\u00facleo, porque es a lo que se le da m\u00e1s importancia en este tipo de arquitecturas. A partir del n\u00facleo\/dominio surge<\/span><span class=\"NormalTextRun SCXW107706755 BCX0\"> el<\/span><strong><span class=\"NormalTextRun SCXW107706755 BCX0\"> Dise\u00f1o Dirigido por el Dominio (<\/span><span class=\"NormalTextRun SpellingErrorV2 SCXW107706755 BCX0\">Domain<\/span> <span class=\"NormalTextRun SpellingErrorV2 SCXW107706755 BCX0\">Driven<\/span> <span class=\"NormalTextRun SpellingErrorV2 SCXW107706755 BCX0\">Design<\/span><span class=\"NormalTextRun SCXW107706755 BCX0\">, DDD)<\/span><\/strong><span class=\"NormalTextRun SCXW107706755 BCX0\">, del que hablar\u00e9 pronto en otro post.<\/span><\/span><\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-20418 aligncenter\" src=\"https:\/\/www.hiberus.com\/crecemos-contigo\/wp-content\/uploads\/2022\/02\/classDiagram-247x300.png\" alt=\"\" width=\"431\" height=\"523\" srcset=\"https:\/\/www.hiberus.com\/crecemos-contigo\/wp-content\/uploads\/2022\/02\/classDiagram-247x300.png 247w, https:\/\/www.hiberus.com\/crecemos-contigo\/wp-content\/uploads\/2022\/02\/classDiagram.png 351w\" sizes=\"auto, (max-width: 431px) 100vw, 431px\" \/><\/p>\n<p>&nbsp;<\/p>\n<h2>Ventajas del uso de la arquitectura hexagonal<\/h2>\n<p><span class=\"TextRun SCXW251065876 BCX0\" lang=\"ES-ES\" xml:lang=\"ES-ES\" data-contrast=\"auto\"><span class=\"NormalTextRun SCXW251065876 BCX0\">Con este peque\u00f1o dise\u00f1o hemos conseguido<\/span><span class=\"NormalTextRun SCXW251065876 BCX0\"> muchas ventajas. Algunas de ellas son:<\/span><\/span><span class=\"EOP SCXW251065876 BCX0\" data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<ul>\n<li><span class=\"TextRun SCXW127261416 BCX0\" lang=\"ES-ES\" xml:lang=\"ES-ES\" data-contrast=\"auto\"><span class=\"NormalTextRun SCXW127261416 BCX0\">El caso de uso de registrar un usuario <strong>se podr\u00eda utilizar desde <\/strong><\/span><span class=\"NormalTextRun SCXW127261416 BCX0\"><strong>distintos lugares<\/strong> que no sean nuestra clase <\/span><span class=\"NormalTextRun SpellingErrorV2 SCXW127261416 BCX0\">UserController<\/span><span class=\"NormalTextRun SCXW127261416 BCX0\"> (<\/span><span class=\"NormalTextRun SpellingErrorV2 SCXW127261416 BCX0\">e.g<\/span><span class=\"NormalTextRun SCXW127261416 BCX0\">. interfaz de l\u00ednea de comandos, adaptador de Kafka\/<\/span><span class=\"NormalTextRun SpellingErrorV2 SCXW127261416 BCX0\">RabbitMQ<\/span><span class=\"NormalTextRun SCXW127261416 BCX0\">&#8230;)<\/span><span class=\"NormalTextRun SCXW127261416 BCX0\">, ya que se han separado las responsabilidades.<\/span><\/span><span class=\"EOP SCXW127261416 BCX0\" data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/li>\n<li><span class=\"TextRun SCXW222221373 BCX0\" lang=\"ES-ES\" xml:lang=\"ES-ES\" data-contrast=\"auto\"><span class=\"NormalTextRun SCXW222221373 BCX0\">El caso de uso de registrar un usuario<strong> podr\u00eda implementarse de diferentes maneras<\/strong> (<\/span><span class=\"NormalTextRun SpellingErrorV2 SCXW222221373 BCX0\">e.g<\/span><span class=\"NormalTextRun SCXW222221373 BCX0\">. registro email\/contrase\u00f1a, registro con token de una red social, registro con n\u00famero de tel\u00e9<\/span><span class=\"NormalTextRun SCXW222221373 BCX0\">fono&#8230;), ya que <\/span><span class=\"NormalTextRun SCXW222221373 BCX0\">hemos seguido el principio de inversi\u00f3n de dependencias y los elementos de la capa de infraestructura no dependen de implementaciones concretas.<\/span><\/span><span class=\"EOP SCXW222221373 BCX0\" data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/li>\n<li><span class=\"TextRun SCXW174630896 BCX0\" lang=\"ES-ES\" xml:lang=\"ES-ES\" data-contrast=\"auto\"><span class=\"NormalTextRun SCXW174630896 BCX0\">El caso de uso de registrar un usuario <strong>podr\u00eda almacenar al usuario en una base de datos documental<\/strong> (MongoDB), <strong>en una base de datos relacional<\/strong> (PostgreSQL)<\/span><span class=\"NormalTextRun SCXW174630896 BCX0\">\u2026 Y<\/span><span class=\"NormalTextRun SCXW174630896 BCX0\">a que hemos seguido el principio de inversi\u00f3n de dependencias.<\/span><span class=\"NormalTextRun SCXW174630896 BCX0\"> Esto hace que la soluci\u00f3n sea agn\u00f3stica del SGBD que se utiliza, favoreciendo la mantenibilidad.<\/span><\/span><span class=\"EOP SCXW174630896 BCX0\" data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/li>\n<li><span class=\"TextRun SCXW153367315 BCX0\" lang=\"ES-ES\" xml:lang=\"ES-ES\" data-contrast=\"auto\"><span class=\"NormalTextRun SCXW153367315 BCX0\">A nivel de sem\u00e1ntica, todo est\u00e1 m\u00e1s separado, diferenciado y estructurado, por lo que<strong> se entiende mucho mejor<\/strong> y todas las partes resultantes son mucho m<\/span><span class=\"NormalTextRun SCXW153367315 BCX0\">\u00e1s simples.<\/span><\/span><span class=\"EOP SCXW153367315 BCX0\" data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/li>\n<li><span class=\"TextRun SCXW167150386 BCX0\" lang=\"ES-ES\" xml:lang=\"ES-ES\" data-contrast=\"auto\"><span class=\"NormalTextRun SCXW167150386 BCX0\">Se pueden hacer <\/span><strong><span class=\"NormalTextRun SpellingErrorV2 SpellingErrorHighlight SCXW167150386 BCX0\">tes<\/span><span class=\"NormalTextRun SpellingErrorV2 SpellingErrorHighlight SCXW167150386 BCX0\">t<\/span><span class=\"NormalTextRun SpellingErrorV2 SpellingErrorHighlight SCXW167150386 BCX0\">s<\/span><\/strong><span class=\"NormalTextRun SCXW167150386 BCX0\"><strong> unitarios por capas<\/strong>.<\/span><\/span><span class=\"EOP SCXW167150386 BCX0\" data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/li>\n<li><span class=\"TextRun SCXW251023897 BCX0\" lang=\"ES-ES\" xml:lang=\"ES-ES\" data-contrast=\"auto\"><span class=\"NormalTextRun SCXW251023897 BCX0\">Al fragmentar la aplicaci\u00f3n, <strong>s<\/strong><\/span><span class=\"NormalTextRun SCXW251023897 BCX0\"><strong>e puede reutilizar el c\u00f3digo de casos de uso repetitivos entre aplicaciones<\/strong>, como puede ser el caso de uso mencionado de registro de usuarios.<\/span><\/span><span class=\"EOP SCXW251023897 BCX0\" data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/li>\n<\/ul>\n<h3>Conclusiones<\/h3>\n<p><span class=\"TextRun SCXW57746790 BCX0\" lang=\"ES-ES\" xml:lang=\"ES-ES\" data-contrast=\"auto\"><span class=\"NormalTextRun CommentStart CommentHighlightPipeRest CommentHighlightRest SCXW57746790 BCX0\">En este post hemos repasado<\/span><span class=\"NormalTextRun CommentHighlightPipeRest SCXW57746790 BCX0\"> la importancia del software, <\/span><span class=\"NormalTextRun SCXW57746790 BCX0\">qu\u00e9 es una arquitectura de software, as\u00ed como <\/span><span class=\"NormalTextRun SCXW57746790 BCX0\">qu\u00e9 diferencia al <\/span><span class=\"NormalTextRun SCXW57746790 BCX0\">\u201c<\/span><span class=\"NormalTextRun SCXW57746790 BCX0\">c\u00f3digo espagueti<\/span><span class=\"NormalTextRun SCXW57746790 BCX0\">\u201d<\/span><span class=\"NormalTextRun SCXW57746790 BCX0\"> de<\/span><span class=\"NormalTextRun SCXW57746790 BCX0\"> arquitecturas bien dise\u00f1adas y estructuradas<\/span><span class=\"NormalTextRun SCXW57746790 BCX0\">. <\/span><\/span><\/p>\n<p><span class=\"TextRun SCXW57746790 BCX0\" lang=\"ES-ES\" xml:lang=\"ES-ES\" data-contrast=\"auto\"><span class=\"NormalTextRun SCXW57746790 BCX0\">Dentro de estas<\/span><span class=\"NormalTextRun SCXW57746790 BCX0\"> \u00faltimas<\/span><span class=\"NormalTextRun SCXW57746790 BCX0\">, se encuentra la ya famosa \u201carquitectura hexagonal\u201d<\/span><span class=\"NormalTextRun SCXW57746790 BCX0\">, <\/span><span class=\"NormalTextRun SCXW57746790 BCX0\">de la que hemos detallado sus ventajas, adem\u00e1s de a qu\u00e9 se deben<\/span><span class=\"NormalTextRun SCXW57746790 BCX0\">. <\/span><\/span><\/p>\n<p><span class=\"TextRun SCXW57746790 BCX0\" lang=\"ES-ES\" xml:lang=\"ES-ES\" data-contrast=\"auto\"><span class=\"NormalTextRun SCXW57746790 BCX0\">En Hiberus somos <a href=\"https:\/\/www.hiberus.com\/modern-applications\/microservicios\">expertos en microservicios<\/a>. <strong>Trabajamos d\u00eda a d\u00eda para mejorar nuestro software bas\u00e1ndonos en experiencias previas y en <\/strong><\/span><strong><span class=\"NormalTextRun SCXW57746790 BCX0\">patrones arquitecturales como este. <\/span><\/strong><span class=\"NormalTextRun SCXW57746790 BCX0\">Si crees que podemos mejorar tu sistema de informaci\u00f3n<\/span><span class=\"NormalTextRun SCXW57746790 BCX0\">, cont\u00e1ctanos.<\/span><\/span><span class=\"EOP SCXW57746790 BCX0\" data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n        <div class=\"row\">\n            <div class=\"block-cta-form\" style=\"background-color: #003664;\">\n                <div class=\"content-cta-form\">\n                    <div class=\"text-cta-form\">\n                        <p class=\"title-cta-form\">\u00bfQuieres m\u00e1s informaci\u00f3n sobre nuestra \u00e1rea de Microservicios?<\/p>\n                        <p>Contacta con nuestro equipo de Microservicios<\/p>\n                    <\/div>\n                    <div class=\"form-fields\">\n                        \n<div class=\"wpcf7 no-js\" id=\"wpcf7-f33973-o1\" lang=\"es-ES\" dir=\"ltr\" data-wpcf7-id=\"33973\">\n<div class=\"screen-reader-response\"><p role=\"status\" aria-live=\"polite\" aria-atomic=\"true\"><\/p> <ul><\/ul><\/div>\n<form action=\"\/crecemos-contigo\/wp-json\/wp\/v2\/posts\/20417#wpcf7-f33973-o1\" method=\"post\" class=\"wpcf7-form init\" aria-label=\"Formulario de contacto\" novalidate=\"novalidate\" data-status=\"init\">\n<fieldset class=\"hidden-fields-container\"><input type=\"hidden\" name=\"_wpcf7\" value=\"33973\" \/><input type=\"hidden\" name=\"_wpcf7_version\" value=\"6.1.5\" \/><input type=\"hidden\" name=\"_wpcf7_locale\" value=\"es_ES\" \/><input type=\"hidden\" name=\"_wpcf7_unit_tag\" value=\"wpcf7-f33973-o1\" \/><input type=\"hidden\" name=\"_wpcf7_container_post\" value=\"0\" \/><input type=\"hidden\" name=\"_wpcf7_posted_data_hash\" value=\"\" \/><input type=\"hidden\" name=\"_wpcf7_recaptcha_response\" value=\"\" \/>\n<\/fieldset>\n<div id=\"responsive-form\" class=\"clearfix\">\n\t<div class=\"form-row\">\n\t\t<div class=\"column-half\">\n\t\t\t<p><span class=\"wpcf7-form-control-wrap\" data-name=\"nombre\"><input size=\"40\" maxlength=\"400\" class=\"wpcf7-form-control wpcf7-text wpcf7-validates-as-required\" aria-required=\"true\" aria-invalid=\"false\" placeholder=\"Nombre *\" value=\"\" type=\"text\" name=\"nombre\" \/><\/span>\n\t\t\t<\/p>\n\t\t<\/div>\n\t\t<div class=\"column-half\">\n\t\t\t<p><span class=\"wpcf7-form-control-wrap\" data-name=\"apellido\"><input size=\"40\" maxlength=\"400\" class=\"wpcf7-form-control wpcf7-text wpcf7-validates-as-required\" aria-required=\"true\" aria-invalid=\"false\" placeholder=\"Apellido *\" value=\"\" type=\"text\" name=\"apellido\" \/><\/span>\n\t\t\t<\/p>\n\t\t<\/div>\n\t<\/div>\n\t<div class=\"form-row\">\n\t\t<div class=\"column-half\">\n\t\t\t<p><span class=\"wpcf7-form-control-wrap\" data-name=\"correo\"><input size=\"40\" maxlength=\"400\" class=\"wpcf7-form-control wpcf7-email wpcf7-validates-as-required wpcf7-text wpcf7-validates-as-email\" aria-required=\"true\" aria-invalid=\"false\" placeholder=\"Correo corporativo *\" value=\"\" type=\"email\" name=\"correo\" \/><\/span>\n\t\t\t<\/p>\n\t\t<\/div>\n\t\t<div class=\"column-half\">\n\t\t\t<p><span class=\"wpcf7-form-control-wrap\" data-name=\"telf-contacto\"><input size=\"40\" maxlength=\"400\" class=\"wpcf7-form-control wpcf7-tel wpcf7-validates-as-required wpcf7-text wpcf7-validates-as-tel\" aria-required=\"true\" aria-invalid=\"false\" placeholder=\"Tel\u00e9fono *\" value=\"\" type=\"tel\" name=\"telf-contacto\" \/><\/span>\n\t\t\t<\/p>\n\t\t<\/div>\n\t<\/div>\n\t<div class=\"form-row\">\n\t\t<div class=\"column-half\">\n\t\t\t<p><span class=\"wpcf7-form-control-wrap\" data-name=\"compania\"><input size=\"40\" maxlength=\"400\" class=\"wpcf7-form-control wpcf7-text wpcf7-validates-as-required\" aria-required=\"true\" aria-invalid=\"false\" placeholder=\"Compa\u00f1ia *\" value=\"\" type=\"text\" name=\"compania\" \/><\/span>\n\t\t\t<\/p>\n\t\t<\/div>\n\t<\/div>\n\t<div class=\"form-row\">\n\t\t<div class=\"column-full\">\n\t\t\t<p><span class=\"wpcf7-form-control-wrap\" data-name=\"mensaje\"><textarea cols=\"40\" rows=\"10\" maxlength=\"2000\" class=\"wpcf7-form-control wpcf7-textarea wpcf7-validates-as-required\" aria-required=\"true\" aria-invalid=\"false\" placeholder=\"Mensaje *\" name=\"mensaje\"><\/textarea><\/span>\n\t\t\t<\/p>\n\t\t<\/div>\n\t<\/div>\n\t<div class=\"form-row\">\n\t\t<div class=\"column-full color-acceptance\">\n\t\t\t<p><span class=\"wpcf7-form-control-wrap\" data-name=\"politica\"><span class=\"wpcf7-form-control wpcf7-acceptance\"><span class=\"wpcf7-list-item\"><label><input type=\"checkbox\" name=\"politica\" value=\"1\" aria-invalid=\"false\" \/><span class=\"wpcf7-list-item-label\">He le\u00eddo y acepto la <a href=\"https:\/\/www.hiberus.com\/politica\" target=\"_blank\"><u>Pol\u00edtica de privacidad<\/u><\/a><\/span><\/label><\/span><\/span><\/span>\n\t\t\t<\/p>\n\t\t<\/div>\n\t<\/div>\n\t<div class=\"form-row\">\n\t\t<div class=\"column-full color-acceptance\">\n\t\t\t<p><span class=\"wpcf7-form-control-wrap\" data-name=\"marketing\"><span class=\"wpcf7-form-control wpcf7-acceptance optional\"><span class=\"wpcf7-list-item\"><label><input type=\"checkbox\" name=\"marketing\" value=\"1\" aria-invalid=\"false\" \/><span class=\"wpcf7-list-item-label\">Me gustar\u00eda recibir comunicaciones de marketing de Hiberus y sobre sus productos, servicios y eventos.<\/span><\/label><\/span><\/span><\/span>\n\t\t\t<\/p>\n\t\t<\/div>\n\t<\/div>\n\t<div class=\"form-row\">\n\t\t<div class=\"column-half\">\n\t\t\t<p><input class=\"wpcf7-form-control wpcf7-submit has-spinner\" type=\"submit\" value=\"Contacta con nosotros\" \/>\n\t\t\t<\/p>\n\t\t<\/div>\n\t<\/div>\n\t<div class=\"form-row\">\n\t\t<div id=\"campos_ocultos\" class=\"hidden\">\n\t\t\t<p><span class=\"wpcf7-form-control-wrap\" data-name=\"oculto_analitica_new1\"><input size=\"40\" maxlength=\"400\" class=\"wpcf7-form-control wpcf7-text\" id=\"oculto_analitica_new1\" aria-invalid=\"false\" value=\"\" type=\"text\" name=\"oculto_analitica_new1\" \/><\/span><br \/>\n<span class=\"wpcf7-form-control-wrap\" data-name=\"oculto_analitica_new2\"><input size=\"40\" maxlength=\"400\" class=\"wpcf7-form-control wpcf7-text\" id=\"oculto_analitica_new2\" aria-invalid=\"false\" value=\"\" type=\"text\" name=\"oculto_analitica_new2\" \/><\/span><br \/>\n<span class=\"wpcf7-form-control-wrap\" data-name=\"oculto_analitica_new3\"><input size=\"40\" maxlength=\"400\" class=\"wpcf7-form-control wpcf7-text\" id=\"oculto_analitica_new3\" aria-invalid=\"false\" value=\"\" type=\"text\" name=\"oculto_analitica_new3\" \/><\/span><br \/>\n<span class=\"wpcf7-form-control-wrap\" data-name=\"oculto_analitica_new4\"><input size=\"40\" maxlength=\"400\" class=\"wpcf7-form-control wpcf7-text\" id=\"oculto_analitica_new4\" aria-invalid=\"false\" value=\"\" type=\"text\" name=\"oculto_analitica_new4\" \/><\/span><br \/>\n<span class=\"wpcf7-form-control-wrap\" data-name=\"oculto_analitica_new_p\"><input size=\"40\" maxlength=\"400\" class=\"wpcf7-form-control wpcf7-text\" id=\"oculto_analitica_new_p\" aria-invalid=\"false\" value=\"\" type=\"text\" name=\"oculto_analitica_new_p\" \/><\/span>\n\t\t\t<\/p>\n\t\t<\/div>\n\t<\/div>\n<\/div>\n\n<!--end responsive-form--><div class=\"wpcf7-response-output\" aria-hidden=\"true\"><\/div>\n<\/form>\n<\/div>\n                    <\/div>\n                <\/div>\n            <\/div>\n        <\/div>\n        \n","protected":false},"excerpt":{"rendered":"<p>A d\u00eda de hoy, el software es ubicuo. \u00bfQueremos chatear con un amigo a miles de kil\u00f3metros? Recurrimos al software. \u00bfQueremos comprar&#8230;<\/p>\n","protected":false},"author":234,"featured_media":20168,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_ayudawp_aiss_exclude":false,"footnotes":""},"categories":[3,237],"tags":[56],"class_list":{"0":"post-20417","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-negocio-electronico","8":"category-microservicios","9":"tag-microservicios"},"acf":[],"_links":{"self":[{"href":"https:\/\/www.hiberus.com\/crecemos-contigo\/wp-json\/wp\/v2\/posts\/20417","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.hiberus.com\/crecemos-contigo\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.hiberus.com\/crecemos-contigo\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.hiberus.com\/crecemos-contigo\/wp-json\/wp\/v2\/users\/234"}],"replies":[{"embeddable":true,"href":"https:\/\/www.hiberus.com\/crecemos-contigo\/wp-json\/wp\/v2\/comments?post=20417"}],"version-history":[{"count":12,"href":"https:\/\/www.hiberus.com\/crecemos-contigo\/wp-json\/wp\/v2\/posts\/20417\/revisions"}],"predecessor-version":[{"id":36261,"href":"https:\/\/www.hiberus.com\/crecemos-contigo\/wp-json\/wp\/v2\/posts\/20417\/revisions\/36261"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.hiberus.com\/crecemos-contigo\/wp-json\/wp\/v2\/media\/20168"}],"wp:attachment":[{"href":"https:\/\/www.hiberus.com\/crecemos-contigo\/wp-json\/wp\/v2\/media?parent=20417"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.hiberus.com\/crecemos-contigo\/wp-json\/wp\/v2\/categories?post=20417"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.hiberus.com\/crecemos-contigo\/wp-json\/wp\/v2\/tags?post=20417"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}