Menu
Coddy logo textTech

Patrón Strategy

Parte de la sección Programación Orientada a Objetos del Journey de Java de Coddy. Lección 69 de 87.

El patrón Strategy es un patrón de diseño de comportamiento que te permite definir una familia de algoritmos, encapsular cada uno en su propia clase y hacer que sean intercambiables. En lugar de codificar directamente un comportamiento específico, puedes intercambiar algoritmos durante la ejecución sin cambiar el código que los utiliza.

Imagina un sistema de pagos que admita múltiples métodos de pago. Sin el patrón Strategy, terminarías con una lógica condicional desordenada. Con él, cada método de pago se convierte en su propia estrategia:

interface PaymentStrategy {
    void pay(int amount);
}

class CreditCardPayment implements PaymentStrategy {
    public void pay(int amount) {
        System.out.println("Paid " + amount + " via Credit Card");
    }
}

class PayPalPayment implements PaymentStrategy {
    public void pay(int amount) {
        System.out.println("Paid " + amount + " via PayPal");
    }
}

La clase de contexto mantiene una referencia a una estrategia y delega el trabajo en ella. La clave es que el contexto no sabe qué estrategia concreta está utilizando. Solo conoce la interfaz:

class ShoppingCart {
    private PaymentStrategy paymentStrategy;
    
    public void setPaymentStrategy(PaymentStrategy strategy) {
        this.paymentStrategy = strategy;
    }
    
    public void checkout(int amount) {
        paymentStrategy.pay(amount);
    }
}

Ahora puedes cambiar dinámicamente el comportamiento del pago:

ShoppingCart cart = new ShoppingCart();

cart.setPaymentStrategy(new CreditCardPayment());
cart.checkout(100);  // Pagado 100 vía Credit Card

cart.setPaymentStrategy(new PayPalPayment());
cart.checkout(50);   // Pagado 50 vía PayPal

El patrón Strategy destaca cuando tienes varias formas de realizar una acción y quieres cambiar fácilmente entre ellas. Añadir un nuevo método de pago simplemente significa crear una nueva clase que implemente PaymentStrategy: no se requieren cambios en el código existente.

challenge icon

Desafío

Fácil

¡Construyamos un sistema de formato de texto usando el patrón Strategy! Crearás un sistema en el que se puedan intercambiar distintas estrategias de formato durante la ejecución para transformar el texto de varias maneras, perfecto para una aplicación que necesita admitir múltiples formatos de salida.

Organizarás tu código en cuatro archivos:

  • TextFormatter.java: Define la interfaz TextFormatter que implementarán todas las estrategias de formato. Debe declarar un único método String format(String text) que recibe una cadena y devuelve la versión con formato.
  • Formatters.java: Crea tres estrategias concretas que implementen tu interfaz TextFormatter:

    UpperCaseFormatter: transforma el texto para que todas las letras estén en mayúsculas.

    LowerCaseFormatter: transforma el texto para que todas las letras estén en minúsculas.

    TitleCaseFormatter: escribe en mayúscula la primera letra de cada palabra y convierte el resto a minúsculas. Las palabras están separadas por espacios.

  • TextEditor.java: Crea la clase de contexto que utiliza una estrategia de formato. Tu TextEditor debe tener:

    Un campo privado para almacenar la estrategia actual de TextFormatter.

    Un método setFormatter(TextFormatter formatter) que cambie la estrategia de formato activa.

    Un método publishText(String text) que aplique el formateador actual al texto e imprima Published: [formatted text]. Si no se ha establecido ningún formateador, debe imprimir Published: [original text] sin cambios.

  • Main.java: ¡Integra tu sistema de estrategias! Recibirás dos entradas: el texto que se va a formatear (String) y el estilo de formato (String: "upper", "lower" o "title").

    Crea un TextEditor y llama primero a publishText con el texto de entrada antes de establecer cualquier formateador (para demostrar el comportamiento predeterminado).

    Después, según la entrada de estilo, establece la estrategia de formato adecuada y vuelve a llamar a publishText con el mismo texto para mostrar el resultado con formato.

Recibirás dos entradas en orden: el texto que se va a formatear (String) y el estilo de formato (String).

Por ejemplo, con las entradas hello world y title, el resultado sería:

Published: hello world
Published: Hello World

Observa que TextEditor no sabe nada sobre la lógica específica de formato. Simplemente delega en la estrategia que esté establecida en ese momento. ¡Esto hace que sea muy fácil añadir nuevos estilos de formato sin tocar el código del editor!

Pruébalo tú mismo

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String text = scanner.nextLine();
        String style = scanner.nextLine();
        
        // TODO: Crea una instancia de TextEditor
        
        // TODO: Llama a publishText con el texto de entrada (antes de establecer cualquier formateador)
        
        // TODO: Según la entrada de estilo ("upper", "lower" o "title"),
        // establece el formateador apropiado y llama a publishText de nuevo
        
    }
}
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Programación Orientada a Objetos

Practica por tu cuenta: Compilador de Java online