Menu
Coddy logo textTech

Padrão Strategy

Parte da seção Programação Orientada a Objetos do Journey de C# da Coddy. Lição 55 de 70.

O padrão Strategy é um padrão comportamental que permite definir uma família de algoritmos, encapsular cada um em sua própria classe e torná-los intercambiáveis em tempo de execução. Em vez de codificar o comportamento diretamente, você injeta a estratégia desejada em um objeto.

O padrão consiste em três partes: uma interface de estratégia que define o contrato do algoritmo, classes de estratégia concretas que implementam comportamentos diferentes e uma classe de contexto que usa uma estratégia:

public interface IPaymentStrategy
{
    void Pay(decimal amount);
}

public class CreditCardPayment : IPaymentStrategy
{
    public void Pay(decimal amount) => 
        Console.WriteLine($"Paid {amount} via Credit Card");
}

public class PayPalPayment : IPaymentStrategy
{
    public void Pay(decimal amount) => 
        Console.WriteLine($"Paid {amount} via PayPal");
}

public class ShoppingCart
{
    private IPaymentStrategy _paymentStrategy;
    
    public void SetPaymentMethod(IPaymentStrategy strategy)
    {
        _paymentStrategy = strategy;
    }
    
    public void Checkout(decimal total)
    {
        _paymentStrategy.Pay(total);
    }
}

O contexto (ShoppingCart) não sabe qual método de pagamento está usando — ele simplesmente chama Pay() em qualquer estratégia que tenha sido fornecida:

var cart = new ShoppingCart();

cart.SetPaymentMethod(new CreditCardPayment());
cart.Checkout(99.99m);  // Pago 99.99 via Cartão de Crédito

cart.SetPaymentMethod(new PayPalPayment());
cart.Checkout(49.99m);  // Pago 49.99 via PayPal

O padrão Strategy elimina a lógica condicional complexa. Adicionar um novo método de pagamento significa criar uma nova classe que implementa IPaymentStrategy - nenhuma alteração é necessária em ShoppingCart. Isso torna seu código aberto à extensão, mas fechado para modificação.

challenge icon

Desafio

Fácil

Vamos criar uma calculadora de custos de envio usando o padrão Strategy. Diferentes métodos de envio têm algoritmos de precificação diferentes, e seu sistema deve permitir alternar entre eles em tempo de execução sem alterar a lógica central de processamento do pedido.

Você organizará seu código em três arquivos:

  • ShippingStrategy.cs: defina uma interface IShippingStrategy no namespace Shipping com um método CalculateCost(double weight) que retorna um double. Em seguida, crie três classes de estratégia concretas:
    • StandardShipping - calcula o custo como weight * 1.5
    • ExpressShipping - calcula o custo como weight * 3.0 + 5.0 (inclui uma tarifa fixa de envio expresso)
    • OvernightShipping - calcula o custo como weight * 5.0 + 10.0 (serviço premium com uma tarifa básica mais alta)
  • OrderProcessor.cs: crie uma classe OrderProcessor no mesmo namespace. Esta é sua classe de contexto que usa uma estratégia de envio. Ela deve ter:
    • Um campo privado para armazenar o IShippingStrategy atual
    • Um método SetShippingMethod(IShippingStrategy strategy) para alterar a estratégia de envio
    • Um método ProcessOrder(double weight) que usa a estratégia atual para calcular e retornar o custo de envio
  • Program.cs: reúna tudo criando um OrderProcessor e demonstrando como você pode trocar as estratégias de envio em tempo de execução. O mesmo processador pode calcular custos usando algoritmos diferentes simplesmente alterando sua estratégia.

Você receberá duas entradas:

  • O tipo de método de envio: standard, express ou overnight
  • O peso do pacote como um número decimal (por exemplo, 4.5)

Crie um OrderProcessor, defina a estratégia de envio apropriada com base no tipo de entrada, depois processe o pedido e imprima o custo calculado.

Por exemplo, se as entradas forem express e 4.5, a saída deverá ser:

18.5

Isso demonstra o poder do padrão Strategy: seu OrderProcessor não contém nenhuma lógica de cálculo de envio. Ele simplesmente delega à estratégia que lhe foi atribuída, facilitando a adição de novos métodos de envio (como DroneDelivery) sem modificar o processador de forma alguma!

Experimente você mesmo

using System;
using Shipping;

class Program
{
    public static void Main(string[] args)
    {
        // Ler entrada
        string shippingType = Console.ReadLine();
        double weight = Convert.ToDouble(Console.ReadLine());

        // TODO: Crie uma instância de OrderProcessor

        // TODO: Com base em shippingType ("standard", "express" ou "overnight"),
        // crie a estratégia de envio apropriada e defina-a no processador

        // TODO: Processe o pedido e imprima o custo calculado
    }
}
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Programação Orientada a Objetos

Pratique por conta própria: Compilador de C# online