Estado en programación vs. estado de la aplicación


Para generar código mantenible es fundamental comprender el concepto estado, puesto que la mayoría de principios y prácticas se refieren a él constantemente.

Espero que este post te ayude a conocerlo un poco mejor.

1. estado en un programa

Un programa consiste en la ejecución de una serie de operaciones cuyos resultados va almacenando en variables. Dichas variables representan ubicaciones de almacenamiento de memoria de la computadora. El contenido de estas ubicaciones de memoria, en cualquier punto de la ejecución del programa, se denomina estado del programa.

Cada vez que guardamos un dato en una variable estamos modificando el estado del programa.

Todos los programas uilizan memoria para ejecutarse, por tanto, todos tienen un "estado" que varía a medida que se ejecuta el programa.

Sin embargo, en el mundo de los principios de programación y de las buenas prácticas, no se habla del "estado" del programa, sino del "estado" de la aplicación.

 
 

2.Estado en una clase

Para comprender qué es el estado de la aplicación empezaré explicando algo más sencillo: qué es el estado en una clase. Para ello imagina el siguiente ejemplo:

public class Usuario
{
   public Usuario(string nombre, string apellidos)
   {
      Nombre = nombre;
      Apellidos = apellidos;
   }

   public string Nombre { get; } // no tienen set

   public string Apellidos { get; }

}

La clase usuario consta de dos propiedades, ambas con "get" público pero sin "set". Esto significa que después de crear un objeto usuario, ya no es posible cambiar su nombre y apellidos.

var usuario = new Usuario("Juan", "Garcia");
usuario.Nombre = "Carlos"; // no es posible, porque no tiene set

Los objetos creados con esta clase tienen un estado inicial y este no se puede modificar.

Si a las propiedades le añadimos la parte del set, entonces es posible modificar su estado inicial.

public class Usuario
{    
   // constructor omitido por brevedad

   public string Nombre { get; set; }  // al añadir el set

   public string Apellidos { get; set; }
}

/* .....*/ 

var usuario = new Usuario("Juan", "Garcia"); 
usuario.Nombre = "Carlos"; // sí posible, porque tiene set

Además de las propiedades, los campos también tienen la capacidad de almacenar estado. Por ejemplo:

public class Vehiculo
{
   private int _posicion;  // campo, != propiedad
      
   public Vehiculo(int posicion)
   {
       _posicion = posicion;
   }

   public void Avanzar(int metros)
   {
       _posicion = _posicion + metros; // uso del campo privado en un método
   } 
}

El campo _posicion almacena estado y además es posible modificarlo a través de qualquier método de la clase. En el ejemplo, cada vez que se llama al método Avanzar, el campo posición va aumentando.

En una clase, el conjunto de propiedades y campos almacenan el estado.

En una clase, solo propiedades y campos tienen esta capacidad.

3.Variables internas

Es posible utilizar variables para almacenar información provisional en los métodos de una clase, pero al salir del método dichas variables se eliminan. Estrictamente hablando, el uso de una variable interna cambia el estado del programa, pero no el estado de la clase

El uso de variables internas en un método no cambia el estado del objeto, y por tanto, tampoco el estado de la aplicación.

Por ejemplo, imagina el siguiente método que comprueba si la contraseña de un usuario es válida:

 public class Usuario
 {
    /* constructor y otras propiedades omitidas por brevedad */

    public string Nombre { get; set; }  
    public string Apellidos { get; set; }
    public string PasswordHash { get; private set; }

    public bool EsContraseñaValida(string contraseña)
    {
       var hasher = new PasswordHasher(); // uso de una varible interna hasher
       var verificacion = hasher.VerifyHashedPassword(PasswordHash, contraseña); 
       return verificacion; // cuando se devuelve el resultado las variables hasher y verificacion se eliminan
    }
    /* ... */
}

Por muchas veces que se llame al método EsContraseñaValida, el estado del objeto Usuario no cambiará, puesto que ni propiedades ni campos se  modifican durante la ejecución del método.

4. Estado global

El estado global de una aplicación es el conjunto de variables accesibles desde cualquier punto de la aplicación. En c# dichas variables se representan como propiedades o campos que tienen la cláusula static delante.

 public static class ClaseConVariablesGlobales
 {
   // propiedad
   public static string RutaCarpetaInformes { get; set; }

   // campo
   public static string RolAdmin= "administador";

 }

En c# no es necesario instanciar una clase para acceder a las variables globales, con escribir el nombre de la clase y su propiedad ya es suficiente.

Por ejemplo, desde cualquier punto de la aplicación podríamos modificar la ruta de la carpeta de informes de este modo:

ClaseConVariablesGlobales.RutaCarpetaInformes = @"C:\informes";

A estas variables se las denomina variables de ámbito global por ser accesibles desde cualquier punto de la aplicación.

5. estado externo

Las aplicaciones suelen relacionarse con otros sistemas externos para completar su funcionalidad. Por ejemplo, una aplicación e-comerce necesita una pasarela de pago para finalizar las compras, sin ella, la aplicación no sería funcional.

Cuando una aplicación realiza una llamada a uno de estos sistemas externos y desencadena una acción visible por los usuarios, también se dice que cambia el estado de la aplicación. Por ejemplo, enviar un e-mail, crear un archivo, añadir un evento a un bus o realizar una llamada a una API. Aunque estos cambios no se almacenen en variables de memoria, el cliente los percibe como cambios de situación. 

Cualquier acción externa y observable de una aplicación se considera como modificación de su estado. 

6. Las lecturas no modifican el estado

No todas las acciones con sistemas externos tienen el mismo efecto. Por ejemplo, recuperar la información de un usuario de una base de datos no implica ningún cambio observable desde el punto de vista del cliente. 

A las acciones que recuperan información existente se las denomina acciones de lectura, mientras que las que modifican estado se denominan acciones de escritura.

Las acciones de lectura, como leer un archivo o registros de base de datos, no modifican el estado de la aplicación.

Aquí tienes algunos ejemplos de sistemas externos típicos:

Base de datos:

  • Lectura: SELECT
  • Escritura: INSERT, UPDATE, DELETE

Sistema de archivos:

  • Lectura: ReadAllText, ReadAllLines, Read..
  • Escritura: File.Create, File.Delete, WriteAllBytes, WriteAllLines, Write...

Servidor SMTP:

  • Escritura: enviar email
     

Pasarela de pago:

  • Lectura: recuperar acción de pago
  • Escritura: efectuar pago

Bus:

  • Lectura: leer mensaje sin procesarlo
  • Escritura: enviar mensaje a la cola, procesar mensaje de la cola

Conclusión

  • Un dato guardado en una variable representa un cambio en el estado del programa.
  • El estado del programa no es lo mismo que el estado de la aplicación.
  • En una clase, el conjunto de propiedades y campos almacenan el estado.
  • El uso de variables internas en un método no cambia el estado del objeto, y por tanto, tampoco el estado de la aplicación.
  • El estado global de una aplicacición es el conjunto de variables accesibles desde cualquier punto de la aplicación.
  • Cualquier llamada a un sistema externo de tipo escritura se considera como modificación del estado de la aplicación. Por ejemplo, enviar un e-mail.
  • Las acciones como leer un archivo o registros de base de datos no modifican el estado de la aplicación.




Quizá algun día empiece a enviar una newsletter, si te gustaría recibirla subscríbete aquí

Archivo