Files
java-design-patterns/localization/es/balking
Luis Mateo Hincapié Martinez dc7495e8bd translation: Translated all creational patterns category to Spanish (Task of issue #2277) (#2813)
* Typo corrections

* bridge pattern translated to spanish

* builder pattern translated to spanish

* context-object pattern translated to spanish

* converter pattern translated to spanish

* dependency injection pattern translated to spanish

* factory pattern translated to spanish

* factory-kit pattern translated to spanish

* factory-method pattern translated to spanish

* monostate pattern translated to spanish

* multiton pattern translated to spanish

* object mother pattern translated to spanish

* object pool pattern translated to spanish

* property pattern translated to spanish

* prototype pattern translated to spanish

* registry pattern translated to spanish

* step builder pattern translated to spanish

* value object pattern translated to spanish

* typo corrections and resources urls refactor

* grammar corrections

* Add image to each pattern

---------

Co-authored-by: luismateoh <luismateohm@gmail.com>
Co-authored-by: luis.hincapie <luis.hincapie@blankfactor.com>
2024-03-23 11:53:54 +02:00
..

title, category, language, tag
title category language tag
Balking Concurrency es
Decoupling

Propósito

El patrón Balking se utiliza para prevenir que un objeto ejecute un código determinado si este se encuentra en un estado incompleto o inapropiado.

Explicación

Ejemplo del mundo real

En una lavadora hay un botón de arranque para iniciar el lavado de ropa. Cuando la lavadora está inactiva el botón funciona como se espera, pero si ya está lavando entonces el botón no hace nada.

En otras palabras

Usando el patrón Balking, un código determinado se ejecuta solo si el objeto está en un estado concreto.

Wikipedia dice

El patrón Balking es un patrón de diseño de software que ejecuta una acción en un objeto solamente cuando el objeto está en un estado concreto. Por ejemplo, si un objeto lee archivos ZIP y un método de llamada invoca un método get en el objeto cuando el archivo ZIP no está abierto, el objeto "rechazaría" (balk) la petición.

Ejemplo Programático

En este ejemplo de implementación, WashingMachine es un objeto que tiene dos estados los cuales pueden ser: ENABLED y WASHING (ACTIVADA y LAVANDO respectivamente). Si la máquina está ENABLED, el estado cambia a WASHING usando un método thread-safe a prueba de hilos. Por otra parte, si ya está lavando y cualquier otro hilo ejecuta wash() entonces no hará ningún cambio de estado y finalizará la ejecución del método sin hacer nada.

Aquí están las partes relevantes de la clase WashingMachine.

@Slf4j
public class WashingMachine {

    private final DelayProvider delayProvider;
    private WashingMachineState washingMachineState;

    public WashingMachine(DelayProvider delayProvider) {
        this.delayProvider = delayProvider;
        this.washingMachineState = WashingMachineState.ENABLED;
    }

    public WashingMachineState getWashingMachineState() {
        return washingMachineState;
    }
    
    public void wash() {
        synchronized (this) {
            var machineState = getWashingMachineState();
            LOGGER.info("{}: Actual machine state: {}", Thread.currentThread().getName(), machineState);
            if (this.washingMachineState == WashingMachineState.WASHING) {
                LOGGER.error("Cannot wash if the machine has been already washing!");
                return;
            }
            this.washingMachineState = WashingMachineState.WASHING;
        }
        LOGGER.info("{}: Doing the washing", Thread.currentThread().getName());
        this.delayProvider.executeAfterDelay(50, TimeUnit.MILLISECONDS, this::endOfWashing);
    }
    
    public synchronized void endOfWashing() {
        washingMachineState = WashingMachineState.ENABLED;
        LOGGER.info("{}: Washing completed.", Thread.currentThread().getId());
    }
}

Aquí la sencilla interfaz DelayProvider utilizada por WashingMachine.

public interface DelayProvider {
    void executeAfterDelay(long interval, TimeUnit timeUnit, Runnable task);
}

Ahora introducimos la aplicación utilizando WashingMachine.

public static void main(String... args) {
    final var washingMachine = new WashingMachine();
    var executorService = Executors.newFixedThreadPool(3);
    for (int i = 0; i < 3; i++) {
        executorService.execute(washingMachine::wash);
    }
    executorService.shutdown();
    try {
        executorService.awaitTermination(10, TimeUnit.SECONDS);    
    } catch (InterruptedException ie) {
        LOGGER.error("ERROR: Waiting on executor service shutdown!");
        Thread.currentThread().interrupt();
    }
}

Aquí está la salida en consola de la aplicación.

14:02:52.268 [pool-1-thread-2] INFO com.iluwatar.balking.WashingMachine - pool-1-thread-2: Actual machine state: ENABLED
14:02:52.272 [pool-1-thread-2] INFO com.iluwatar.balking.WashingMachine - pool-1-thread-2: Doing the washing
14:02:52.272 [pool-1-thread-3] INFO com.iluwatar.balking.WashingMachine - pool-1-thread-3: Actual machine state: WASHING
14:02:52.273 [pool-1-thread-3] ERROR com.iluwatar.balking.WashingMachine - Cannot wash if the machine has been already washing!
14:02:52.273 [pool-1-thread-1] INFO com.iluwatar.balking.WashingMachine - pool-1-thread-1: Actual machine state: WASHING
14:02:52.273 [pool-1-thread-1] ERROR com.iluwatar.balking.WashingMachine - Cannot wash if the machine has been already washing!
14:02:52.324 [pool-1-thread-2] INFO com.iluwatar.balking.WashingMachine - 14: Washing completed.

Diagrama de clases

alt text

Aplicabilidad

Usa el patrón Balking cuando

  • Un objeto debe ejecutar un código determinado sólo cuando se encuentra en un estado concreto.
  • Los objetos están en un estado que es propenso a bloquearse temporalmente, pero durante una cantidad de tiempo indeterminada.

Patrones relacionados

Referencias