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