Inicio » Comunidad » Parallel Change

Parallel Change

0
0

Parallel Change es una técnica de refactoring que nos permite implementar cambios incompatibles en una interfaz de manera segura.

Vamos a ver un ejemplo para entender mejor esta técnica. Tenemos un UserRepository que nos permite buscar por nombre.

public class UserRepository : Repository, IUserRepository
{
    public User FindOneByName(UserName name)
    {
        using (var scope = _scopeFactory.CreateScope())
        {
            var dbContext = scope.ServiceProvider.GetRequiredService();
            return dbContext.Users.FirstOrDefault(c => c.name.GetValue() == name.GetValue());
        }
    }
}

Desde negocio nos piden que, en otro caso de uso, podamos buscar un usuario por email. Por lo tanto, añadimos un nuevo método al UserRepository.

public class UserRepository : Repository, IUserRepository
{
    public User FindOneByName(UserName name)
    {
        using (var scope = _scopeFactory.CreateScope())
        {
            var dbContext = scope.ServiceProvider.GetRequiredService();
            return dbContext.Users.FirstOrDefault(c => c.name.GetValue() == name.GetValue());
        }
    }


    public User FindOneByEmail(UserEmail email)
    {
        using (var scope = _scopeFactory.CreateScope())
        {
            var dbContext = scope.ServiceProvider.GetRequiredService();
            return dbContext.Users.FirstOrDefault(c => c.email.GetValue() == email.GetValue());
        }
    }
}

Esta solución puede parecer la más adecuada, pero si en un futuro queremos buscar por otros atributos del usuario tendríamos que añadir más métodos al UserRepositorio. Lo que nos llevaría a violar seguramente el principio Open/Closed de SOLID.

La solución más adecuada sería añadir un método que nos permita buscar por cualquier atributo que tenga el usuario.

public List FindByCriteria(Criteria criteria)
{
    using (var scope = _scopeFactory.CreateScope())
    {
        //CODE
    }
}

Ahora bien, el problema surge a la hora de cambiar todos aquellos clientes que utilicen el método FindOneByName al nuevo método FindByCriteria. Ya que según el contexto y el código hacer estos cambios puede llegar a ser muy complejos. Entonces en lugar de cambiar todos los clientes, decidimos aplicar la técnica Parallel Change. Para poder aplicarla, debemos hacerlo paulatinamente siguiendo sus tres frases: expand, migrate y contract.

Expand:
Esta fase consiste en añadir un nuevo método de manera que la interface actual contiene la versión antigua y la nueva. Con lo cual, los clientes antiguos continuan utilizando la versión antigua
(FindOneByName) y los nuevos comenzarán a utilizar la versión nueva (FindByCriteria). Por consiguiente, el UserRepositorio nos quedaría de la siguiente manera:

public class UserRepository : Repository, IUserRepository
{
    public User FindOneByName(UserName name)
    {
        using (var scope = _scopeFactory.CreateScope())
        {
            var dbContext = scope.ServiceProvider.GetRequiredService();
            return dbContext.Users.FirstOrDefault(c => c.name.GetValue() == name.GetValue());
        }
    }


    public List FindByCriteria(Criteria criteria)
    {
        using (var scope = _scopeFactory.CreateScope())
        {
            //CODE
        }
    }
}

Migrate:
Durante esta fase, se debe actualizar todos los clientes que estaban llamando a la versión antigua a la nueva versión. Es recomendable hacerlo de forma progresiva si no disponemos de mucho tiempo y marcar la versión antigua como deprecada. De esta forma, evitamos que nuevos clientes utilicen la versión antigua.

Contract:
Se puede procede a eliminar la versión antigua una vez que todos los clientes hayan migrado a la nueva versión.

Conclusión
Esta técnica nos permite subir nuestro código a producción en cualquiera de las fases. Además, reduce el riesgo de la migración de los clientes ya que se hace de manera progresiva y con sus respectivos tests.

0 resultados
Tu respuesta

Por favor, primero debes para enviar.

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Más información
Privacidad