Tipos de arquitecturas de aplicaciones de software

Escrito por picodotdev el , actualizado el .
programacion planeta-codigo
Enlace permanente Comentarios

Con el paso de los años las arquitectura recomendadas han cambiado. En el caso de las aplicaciones web pasando por la arquitectura spaghetti, a la por capas y finalmente con una mezcla de hexagonal, domain-driven-design o DDD y dependiendo del caso siendo RESTful, utilizando CQRS, estándo dirigida por eventos o event-driven y en los casos en los que su aplicación es útil usando event sourcing.

¿Qué es arquitectura en una aplicación de software?

La arquitectura en una aplicación de software son los aspectos comunes a las diferentes implementaciones concretas. La arquitectura de software define la estructura y comportamiento de los elementos relevantes, balanceando las necesidades de sus interesados, aplica decisiones de forma racional, definiendo estilos de arquitectura aplicables a múltiples aplicaciones con necesidades similares, está influenciada por su entorno de aplicación, influencia la estructura de los equipos, está presente en cada sistema y tiene un ámbito particular.

Según alguna de la organización de estándar IEEE la definición de arquitectura de software es:

Architecture is the fundamental organization of a system embodied in its components, their relationships to each other, and to the environment, and the principles guiding its design and evolution.

El estándar define los siguientes términos de la definición:

A system is a collection of components organized to accomplish a specific function or set of functions. The term system encompasses individual applications, systems in the traditional sense, subsystems, systems of systems, product lines, product families, whole enterprises, and other aggregations of interest. A system exists to fulfill one or more missions in its environment.

The environment, or context, determines the setting and circumstances of developmental, operational, political, and other influences upon that system.

A mission is a use or operation for which a system is intended by one or more stakeholders to meet some set of objectives.

A stakeholder is an individual, team, or organization (or classes thereof) with interests in, or concerns relative to, a system.

Tipos de arquitecturas

Arquitectura Spaghetti

En los inicios de las aplicaciones web con la aparición de las páginas programadas en en lado del servidor con servlets y JSP en Java, ASP de Microsoft y PHP la arquitectura de las mismas se caracterizaba por que no había arquitectura. En el mismo servlet o JSP, ASP o PHP el mismo código tenía diferentes responsabilidades sin ninguna separación entre ellas.

En el mismo archivo se codificaba desde el acceso a la base de datos como a la generación del resultado, la lógica para obtener los parámetros de una petición y la lógica de negocio.

Esta no arquitectura de las aplicaciones spaghetti se denomina así porque mezcla todo tipo de funcionalidades que genera dificultades en la programación, legibilidad y mantenimiento cuando las aplicaciones empiezan a tener un tamaño mediano.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
<html>
<head>
  <title>Book Query</title>
</head>
<body>
  <h1>Another E-Bookstore</h1>
  <h3>Choose Author(s):</h3>
  <form method="get">
    <input type="checkbox" name="author" value="Tan Ah Teck">Tan
    <input type="checkbox" name="author" value="Mohd Ali">Ali
    <input type="checkbox" name="author" value="Kumar">Kumar
    <input type="submit" value="Query">
  </form>
 
  <%
    String[] authors = request.getParameterValues("author");
    if (authors != null) {
  %>
  <%@ page import = "java.sql.*" %>
  <%
      Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:8888/ebookshop", "myuser", "xxxx");

      Statement stmt = conn.createStatement();
 
      String sqlStr = "SELECT * FROM books WHERE author IN (";
      sqlStr += "'" + authors[0] + "'";  // First author
      for (int i = 1; i < authors.length; ++i) {
         sqlStr += ", '" + authors[i] + "'";  // Subsequent authors need a leading commas
      }
      sqlStr += ") AND qty > 0 ORDER BY author ASC, title ASC";
 
      // for debugging
      System.out.println("Query statement is " + sqlStr);
      ResultSet rset = stmt.executeQuery(sqlStr);
  %>
      <hr>
      <form method="get" action="order.jsp">
        <table border=1 cellpadding=5>
          <tr>
            <th>Order</th>
            <th>Author</th>
            <th>Title</th>
            <th>Price</th>
            <th>Qty</th>
          </tr>
  <%
      while (rset.next()) {
        int id = rset.getInt("id");
  %>
          <tr>
            <td><input type="checkbox" name="id" value="<%= id %>"></td>
            <td><%= rset.getString("author") %></td>
            <td><%= rset.getString("title") %></td>
            <td>$<%= rset.getInt("price") %></td>
            <td><%= rset.getInt("qty") %></td>
          </tr>
  <%
      }
  %>
        </table>
        <br>
        <input type="submit" value="Order">
        <input type="reset" value="Clear">
      </form>
      <a href="<%= request.getRequestURI() %>"><h3>Back</h3></a>
  <%
      rset.close();
      stmt.close();
      conn.close();
    }
  %>
</body>
</html>
spaghetti.jsp

Arquitectura por capas

Para suplir las carencias de la arquitectura spaghetti surge la arquitectura por capas. En la arquitectura por capas cada capa tiene una responsabilidad definida, una capa se encarga de la visualización de los datos y la interacción con el usuario, otra capa se encarga de la lógica de negocio y otra capa del acceso a la base de datos. Esta distribución de responsabilidades pone cierto orden a la organización del código y estructura de las aplicaciones. Las capas superiores dependen de las capas inferiores, ya sea en un modelo estricto donde la superior depende únicamente de la inmediatamente inferior o en un modelo más permisivo donde una capa superior puede depender de cualquiera de las inferiores.

La aparición de los frameworks de desarrollo facilitan la creación de los componentes que constituyen la aplicación utilizando el patrón modelo-vista-controlador o MVC basados en acciones como Struts, de componentes como JSF y Apache Tapestry u otros similares en otros lenguajes.

Arquitectura por capas

Arquitectura por capas

Arquitectura hexagonal

En la arquitectura hexagonal o también conocida como puertos-adaptadores aísla las entradas y salidas de la aplicación de la lógica interna de la aplicación. Este aislamiento de las partes exteriores hace que la aplicación no requiera prácticamente ningún cambio que esté influenciado por cambios externos ya sea una nueva base de datos para persistir los datos o un nuevo tipo de cliente como un dispositivo móvil.

Cada entrada ya sea desde una petición REST o desde la linea de comandos o salida ya sea a una base de datos o un sistema de mensajería es un tipo diferente de puerto para su interacción. Una gran ventaja de la arquitectura hexagonal es que los puertos y adaptadores son fácilmente desarrollables para un entorno de pruebas hasta tener los definitivos, la aplicación se puede desarrollar y probar antes de que los clientes y los sistemas de persistencia existan.

Una de las tecnologías que habilitan la arquitectura hexagonal es la inversión de dependencias o IoC mediante la cual se consigue que al contrario que en la arquitectura por capas donde una capa superior depende de la interior la capa inferior dependa de la superior. Si en una aplicación se está utilizando inversión de dependencias es probable que se esté utilizando una arquitectura hexagonal más que una por capas.

Si en la arquitectura por capas la capa de lógica de negocio depende de la capa de acceso a base de datos, en la arquitectura hexagonal es la capa de acceso a base de datos la que depende de la capa de lógica de negocio. Este cambio de dependencias es lo que le da nombre a la inversión de dependencias. La inversión de dependencias se consigue creando en la capa de lógica de negocio una interfaz que es la que implementa la capa de acceso a datos.

En la Figura 1 el paquete A depende del paquete B para invertir la dependencia se crea una interfaz de la que depende el paquete A unícamente depende, en la Figura 2 es el paquete B el que depende de esa interfaz al implementarla.

Arquitectura hexagonal Inversión de dependencias

Arquitectura hexagonal e inversión de dependencias
Fuente: herbertograca.com

Metodologías relacionadas

Domain Driven Design

La metodología domain-driven-design o DDD promueve que la aplicación ha de estar desarrollada basándose en los aspectos del negocio y del dominio de la aplicación, esto afecta tanto al lenguaje compartido denominado lenguaje ubicuo tanto en la aplicación como por todos stakeholders de cada contexto de la aplicación, también afecta a como se modulariza en subdominios la aplicación con las diferentes funcionalidades. El diseño estratégico define los aspectos de análisis de la aplicación el diseño estratégico los de implementación con los agregados, entidades, value objects, repositorios o eventos de dominio.

La arquitectura hexagonal se complementa perfectamente con la metodología y principios de DDD ya que ambos casos tienen interés en aislar la lógica de negocio de las partes exteriores de la aplicación de modo que un cambio en el exterior no suponga cambios importantes en la lógica de negocio.

APIs, REST o GraphQL

Con la aparición de múltiples dispositivos ya sean navegadores, teléfonos inteligentes, aplicaciones nativas de teléfonos inteligentes, tabletas o incluso otras aplicaciones, para dar soporte a todos estos clientes las aplicaciones se desarrollan desde el primer momento con el objetivo de ofrecer una API que todos los dispositivos comparten y posteriormente cada dispositivo adapta su interfaz gráfica a sus necesidades.

Muchas aplicaciones utilizan una API denominada REST basada en los principios de la web y la semántica del protocolo HTTP y como formato de intercambio de datos se suele utilizar JSON. Las aplicaciones basadas en REST que siguen los principios de HATEOAS permiten a los clientes obtener en los los datos devueltos las ubicaciones de los recursos relacionados.

Otra forma de implementación de un API es mediante GraphQL que a diferencia de REST no se basa en los principios del protocolo HTTP y la semántica de la web aunque lo utiliza. A diferencia de REST que siempre se devuelven los mismos datos GrapqhQL permite realizar consultas indicando únicamente los datos deseados como respuesta.

CQRS

La metodología CQRS separa las operaciones de consulta que solicitan datos de las operaciones que modifican datos o comandos incluso utilizando diferentes bases de datos. El modelo necesario para la consulta puede ser distinto del necesario para la modificación y variar en diferentes casos de uso, por eso la necesidad o ventaja de separar el modelo de consulta del modelo de modificación. El modelo de consulta puede estar desnormalizado para ser más sencillo o eficiente a las necesidades de consulta que utilizando un único modelo para ambas operaciones.

El modelo de consulta se actualiza de forma asíncrona con el modelo de modificación utilizando consistencia eventual. Para manejar esta consistencia eventual en la interfaz del usuario hay varias opciones, una de ellas mostrar los datos en la interfaz como si se hubieran modificado inmediatamente aún estándo pendientes de modificarse. Otra posibilidad es mostrar la fecha y hora de la última actualización de los datos o simplemente indicar al usuario que su petición ha sido aceptada y su procesamiento requiere algo de tiempo en procesarse.

Event-Driven

En las aplicaciones dirigidas por eventos o event-driven las aplicaciones reaccionan a los eventos que se producen en el sistema. El procesamiento de un evento devuelve una respuesta o genera nuevos eventos en el sistema.

Event Sourcing

En vez de realizar modificaciones sobre los datos existentes simplemente se añaden nuevos eventos en el sistema, el estado actual del sistema se obtiene al procesar todos los eventos.

Comparte el artículo: