es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Qué patrón se puede usar aquí para previsualizar este resultado?

Tengo un método para realizar un pedido,

public async Task<bool> Ordenar(Solicitud solicitud)
{
    // Cada paso realiza cosas diferentes.
    await Paso1(solicitud);
    await Paso2(solicitud);
    await Paso3(solicitud);
    await Paso4(solicitud);
    ...
    await PasoN(solicitud);
}

public async Task<bool> Paso1(Solicitud solicitud)
{
    var cantidad1 = await cambiarAlgo1(solicitud);
    await Pago1(cantidad1);
}

public async Task<bool> Paso2(Solicitud solicitud)
{
    var cantidad2 = await cambiarAlgo2(solicitud);
    await Pago2(cantidad2);
}

public async Task<bool> PasoX(Solicitud solicitud)
{
    var cantidadX = await cambiarAlgoX(solicitud);
    await PagoX(cantidadX);
}

Ahora necesito previsualizar el pedido sin llamar a PagoX(cantidad). No quiero agregar un parámetro booleano para omitirlo, como se muestra en el siguiente código, que se ve bastante feo.

public async Task<bool> Ordenar(Solicitud solicitud, bool previsualizar = false)
{
    await Paso1(solicitud, previsualizar);
    await Paso2(solicitud, previsualizar);
    await Paso3(solicitud, previsualizar);
    await Paso4(solicitud, previsualizar);
    ....
    await PasoN(solicitud, previsualizar);
}

public async Task<bool> PasoX(Solicitud solicitud, bool previsualizar = false)
{
    var cantidadX = await cambiarAlgoX(solicitud);
    if (!previsualizar) await PagoX(cantidadX);
}

¿Qué patrón se puede aplicar aquí? Muchas gracias.

Tags:  ,

Answer

  1. Avatar for davy.ai

    El patrón de diseño Decorador se puede aplicar aquí. Crea una nueva interfaz llamada “IPay” con un método llamado “Pay” que tome una cantidad como parámetro. Haz que los métodos actuales de pago (Pay1, Pay2, etc.) implementen esta interfaz. Luego, crea una nueva clase llamada “PreviewPay” que también implemente la interfaz IPay, pero con una implementación vacía del método Pay (no hacer nada).

    Modifica los métodos Order y StepX para aceptar un objeto IPay en lugar de un parámetro booleano. En el método Order, pasa el objeto de pago normal para todos los pasos excepto para StepX, donde pasas el objeto PreviewPay. En el método StepX, simplemente llama al método Pay en el objeto IPay.

    De esta manera, al pasar el objeto PreviewPay para StepX, el método Pay no se ejecutará durante una vista previa. El código se vería así:

    public interface IPay
    {
        Task<bool> Pay(decimal amount);
    }
    
    public class Pay1 : IPay
    {
        public async Task<bool> Pay(decimal amount)
        {
            // implementación normal de Pay1
        }
    }
    
    public class PreviewPay : IPay
    {
        public async Task<bool> Pay(decimal amount)
        {
            // implementación vacía para la vista previa
            return true;
        }
    }
    
    public async Task<bool> Order(Request request, IPay pay)
    {
        await Step1(request, pay);
        await Step2(request, pay);
        await Step3(request, pay);
        await Step4(request, pay);
        ....
        await StepN(request, pay);
    }
    
    public async Task<bool> StepX(Request request, IPay pay)
    {
        var amountX = await changeSomethingX(request);
        await pay.Pay(amountX);
    }
    

    De esta manera, el diseño es más flexible y extensible, ya que puedes crear fácilmente nuevos tipos de objetos de pago (por ejemplo, un DiscountedPay) y pasarlos a cualquier paso durante el método Order.

Comments are closed.