viernes, julio 26, 2013

Sobre arquitectura en capas – Parte 1

Aun veo proyectos que separan los componentes de la aplicación en capas, utilizando el viejo modelo de 3 capas, el cual siento que ya no es la mejor opción ya que la forma de desarrollar software ha cambiado. En esta serie de artículos pretendo explicar porque ya no es necesaria una separación en 3 capas al momento de desarrollar un nuevo proyecto de software.

Primero debo empezar por definir qué es es la arquitectura en capas para mi, así que esta primera parte trata sobre eso.

¿Qué es la arquitectura en capas?

La arquitectura en capas consiste en separar las responsabilidades de nuestra aplicación de una manera horizontal. Esto se hace con la intención de elevar el nivel de abstracción. Ocultar la plomería de la aplicación poniendo una capa de abstracciones sobre ella. Las típicas capas de esta arquitectura, iniciando de abajo hacia arriba, se describen a continuación.

Capa de acceso a datos (también conocida como DAL por sus siglas en ingles): Es donde se escribe el código que habla con la base de datos. Es en esta capa donde se definen las consultas a la base de datos (el SQL). No realiza validaciones entre entidades, sólo las validaciones que van hacia la base de datos. La intención de esta capa es que el resto de la aplicación no se preocupe de los detalles (en cierta medida) de la estructura de la base de datos y trabaje a un nivel de objetos. Es la encargada de la entrada y salida de datos hacia y desde la base de datos. Ya que no debe de preocuparse de las reglas de negocio el código de la capa debería de ser fácil de seguir y de mantener. Las capas construidas encima de esta (es decir que usen esta capa) deben de dejar de pensar en tablas y registros para pensar en objetos y colecciones.

Capa de reglas de negocio (BL): Una vez que tenemos la abstracción de la capa de acceso a datos, sobre ella se construye una capa. En esta capa es donde se escriben las reglas de negocio, validaciones que involucran varias entidades, validación de estados y condiciones definidas en los requerimientos. Usa a la capa de acceso a datos para realizar las consultas y actualizaciones a la base de datos. La capa de negocio no sabe cómo es presentada la información al usuario o de cómo fue capturada por él. Al no preocuparse de como se presenta la información (UI) o de como es que se almacena (DAL), en el código solo deben observarse que las reglas (de negocio) definidas en los requerimientos se cumplan.

Capa de presentación (UI): Lo que el usuario ve. Es la capa donde se crean los componentes de la interfaz de usuario. Esta capa utiliza a la capa de negocio para realizar la tarea que el usuario requiera. La capa de negocio validará y regresará el resultado o error y la capa de presentación los mostrará al usuario. Entonces el código en esta capa sólo se encarga de pasar valores a la capa de negocio y de desplegar información, en la interfaz de usuario, que viene de la capa de negocio.

Hagamos un ejemplo para entender mejor a que se refiere cada capa. Supongamos que se nos pide que en la aplicación que estamos desarrollando un usuario pueda ingresar al sistema con un nombre de usuario (username) y contraseña validos. Separando nuestra aplicación en capas como las definidas anteriormente tendríamos las siguientes clases (en C#).

Primero la capa de acceso a datos

namespace Dal
{
  public class UserRepository
  {
    public User FindByUsername(string username)
    {
      User user = null;
      var sql = "SELECT * FROM User WHERE Username = @Username";
      using(var connection = new SqlConnection(Config.ConnectionString)){
        var cmd = new SqlCommand(sql, connection);
        cmd.Parameters.AddWithValue("@Username", username);
        connection.Open();
        using(var reader = cmd.ExecuteReader())
        {          
              user = reader.read() ? 
                 new User(username, reader["password"]) : null;
        }
        return user;
      }
    }
  }
}

Ahora la capa de reglas de negocio:

namespace BL
{
  public class UsersService
  {
    public bool ValidateUser(string username, string password)
    {
      var userRepository =  new UserRepository();
      var user = userRepository.FindByUsername(username);
      if (user == null) return false;
      var cryptoService = new CryptoService();
      return cryptoService.ComputeHash(password) == username.Password;
    }
  }
}

Por último la capa de presentación:

...
void LoginButton_Click(object sender, EventArgs e)
{
   var usersService = new UsersService();
   if (usersService.ValidateUser(usernameTextbox.Text, passwordTextbox.Text))   
       MessageBox.Show("Bienvenido");
   else
       MessageBox.Show("Usuario o contraseña incorrectos");
}
...

Aquí puede verse la separación de la lógica en capas. En lugar de hacer la consulta a la base de datos directamente en el método de clic del botón, la capa de presentación delega la validación del usuario a la capa de negocio. La capa de negocio a su vez delega a la capa de acceso a datos la creación y ejecución de las consultas en SQL sobre la base de datos.


Así era como desarrollábamos una aplicación hace años; pero ya no.


Artículo relacionado: Sobre arquitectura en capas – parte 2

4 comentarios:

  1. Me pica la curiosidad de saber que alternativa tenemos...

    ResponderEliminar
  2. Últimamente he visto muchos artículos y comentarios de viejas prácticas que se consideran hoy obsoletas. Lamentablemente en mi muy humilde opinión creo que hace falta más información de porque nacieron, o sea que problemática del desarrollo del software se quiere prevenir y como lo logra. Además también es obvio que hay casos en los que de verdad no aplican, pero no se podrá saber cuándo si usarlos y cuando no si no se conoce para que nos sirven. En proyectos pequeños en donde no hay más de dos desarrolladores en un proyecto de no más de tres meses estoy de acuerdo contigo, no es necesario programar más de tres capas, de lo contrario creo que es una excelente patrón de diseño.
    http://msdn.microsoft.com/en-us/library/ff650706.aspx

    ResponderEliminar
  3. Por hacer una analogía, sabemos que los candados tienen el propósito de solo dejar pasar a quienes tienen la llave, pero cuando no se usa el candado correcto esto es lo que pasa: http://devopsreactions.tumblr.com/post/56770243712/this-looks-secur-wait-a-minute

    Así croe que está ocurriendo en la industria, muchos no están utilizando el patrón de diseño correctamente y lo que los programadores a la larga creen con justa razón es que el patrón de diseño no es útil ya que les da muchos problemas el implementarlo y ningún beneficio.

    ResponderEliminar
  4. Yo tambien tengo mucha curiosidad de conocer las alternativas.

    Pero desde mi punto de vista, no todos los proyectos son iguales y para diseñar una arquitectura se tienen que tomar en cuenta muchas cosas, no solamente lo que 'esta de moda' o el supuesto estandar de la industria.

    Si bien la arquitectura en 3 capas es de las mas adoptadas, creo que muchas veces es implementada por las razones equivocadas. El simple hecho de usar capas en un proyecto por que 'asi me enseñaron' o por que 'es el estandar' no son razones suficientes y muchas veces se pierde el tiempo programando para prevenir cosas que jamas van a ocurrir.

    Si la razon por la que usas un diseño en capas es para 'poder reemplazar cualquier capa sin afectar las demas capas' entonces puede que estes perdiendo tu tiempo.

    Ojo, tienes que analizar si la posibilidad de un reemplazo de cualquiera de las capaz es tan siquiera factible.

    La arquitectura muchas veces la analizamos desde el ambito tecnico, pero nos olvidamos del ambito administrativo, algo que no se puede dejar de lado al momento de gestionar cualquier proyecto. Creo que la arquitectura en capas facilita ciertas funciones administrativas, al poder 'descomponer' tu proyecto en areas definidas y separar de mejor manera las tareas. Me ha tocado trabajar en varios proyectos donde un equipo de alrededor de 5 personas trabaja sobre el mismo codigo y la arquitectura en capas ha ayudado a delegar las tareas. Puedes tener 2 personas trabajando en el front-end y otras 2 en el DAL sin que nadie se pise los talones.


    En conclusion mi postura es, todo es cuestion de hacer las cosas con un proposito claro en mente y no como borreguitos. Debemos de aprender a aplicar muy bien el Separation of Concerns (SoC)pero nunca olvidarnos del KISS :) (Keep it simple, stupid!)




    ResponderEliminar