State – Patrones de Diseño
Antonio Leiva

El patrón de diseño State es un patrón de comportamiento que nos permite cambiar el comportamiento de un objeto en función del estado en el que se encuentre.

Este patrón nos permite desacoplar el comportamiento de un objeto de su implementación, lo que nos permite cambiar el comportamiento de un objeto en tiempo de ejecución de forma sencilla y mantenible.

Ejemplo de State: Ascensor

Para ilustrar el uso de este patrón en Kotlin, consideremos un ejemplo de una máquina de estados finitos que simula un ascensor.

En este caso, el ascensor puede encontrarse en uno de tres estados: Subiendo, Bajando y Detenido.

Cada uno de estos estados tiene un comportamiento diferente en cuanto a la acción que debe realizar cuando se presiona un botón de piso.

Para implementar el patrón de diseño State en Kotlin, podemos utilizar una interfaz que represente el estado del ascensor y una clase que represente la máquina de estados finitos del ascensor.

La interfaz del estado del ascensor tendría un método para manejar la acción de presionar un botón de piso, y cada una de las clases que representan los estados del ascensor implementaría este método de forma diferente.

A continuación se muestra un ejemplo de cómo se podría implementar el patrón de diseño State en Kotlin para el caso del ascensor.

La interfaz ElevatorState representa un estado del ascensor y tiene un método handleFloorButtonPress() que se encarga de manejar la acción de presionar un botón de piso:

interface ElevatorState {
    fun handleFloorButtonPress(floor: Int)
}

La clase Elevator es la máquina de estados finitos del ascensor y su estado inicial es StoppedState.

class Elevator {
    var state: ElevatorState = StoppedState()

    fun pressFloorButton(floor: Int) {
        state.handleFloorButtonPress(floor)
    }
}

Este sería un ejemplo de implementación de los estados:

class StoppedState: ElevatorState {
    override fun handleFloorButtonPress(floor: Int) {
        if (floor > Elevator.currentFloor) {
            Elevator.state = GoingUpState()
        } else if (floor < Elevator.currentFloor) {
            Elevator.state = GoingDownState()
        } else {
            // Do nothing, already on the selected floor
        }
    }
}

class GoingUpState: ElevatorState {
    override fun handleFloorButtonPress(floor: Int) {
        if (floor > Elevator.currentFloor) {
            // Add floor to list of floors to visit
        } else if (floor < Elevator.currentFloor) {
            // Change direction and add floor to list of floors to visit
        } else {
            // Stop elevator on selected floor
            Elevator.state = StoppedState()
        }
    }
}

class GoingDownState: ElevatorState {
    override fun handleFloorButtonPress(floor: Int) {
        if (floor > Elevator.currentFloor) {
            // Change direction and add floor to list of floors to visit
        } else if (floor < Elevator.currentFloor) {
            // Add floor to list of floors to visit
        } else {
            // Stop elevator on selected floor
            Elevator.state = StoppedState()
        }
    }
}

Cuando se presiona un botón de piso, se llama al método pressFloorButton() de la clase Elevator, que a su vez llama al método handleFloorButtonPress() del estado actual del ascensor.

Cada una de las clases que representan los estados del ascensor implementa este método de forma diferente, de modo que el comportamiento del ascensor cambia en función del estado en el que se encuentre.

Por ejemplo, si el ascensor se encuentra en el estado StoppedState y se presiona un botón de piso en un piso superior al actual, el ascensor cambiará su estado a GoingUpState y empezará a subir.

Si en cambio se presiona un botón de piso en un piso inferior al actual, el ascensor cambiará su estado a GoingDownState y empezará a bajar.

Si se presiona un botón de piso en el mismo piso en el que se encuentra el ascensor, no se producirá ningún cambio de estado.

Conclusión

El patrón de diseño State nos permite cambiar el comportamiento de un objeto en función de su estado.

En Kotlin, podemos implementar este patrón mediante el uso de una interfaz que represente los estados del objeto y una clase que represente la máquina de estados finitos del objeto.

Cada una de las clases que representan los estados del objeto implementan el método correspondiente al comportamiento que se desea en cada estado, lo que nos permite cambiar el comportamiento del objeto en tiempo de ejecución de forma sencilla y mantenible.

Quizá también te interese…

Las reglas FIRST de los tests

Las reglas FIRST de los tests

Las reglas FIRST son un conjunto de principios que se utilizan para diseñar y escribir tests de software de manera efectiva. Las siglas FIRST significan: F - Fast: Un test debe ser rápido de ejecutar. I - Independent: Un test debe ser independiente de otros tests y...

¿Qué son los dobles de test?

¿Qué son los dobles de test?

Los dobles de prueba (también conocidos como "doubles" o "fakes") son herramientas comunes en la programación y en particular en el testing de software. Se utilizan para simular el comportamiento de una dependencia de una aplicación en un entorno de pruebas, sin tener...

Kata del TicTacToe en Kotlin

Kata del TicTacToe en Kotlin

Escribe el código para representar una entidad que almacene el tablero de juego del 3 en raya, y que además tenga: Un método move() con 2 parámetros, fila y columna, que permita añadir un movimiento al tablero Un método findWinner(), que devuelva el ganador (X, Y o...

0 comentarios

Enviar un comentario

Los datos personales que proporciones a través de este formulario quedarán registrados en un fichero de DevExpert, S.L.U., con el fin de gestionar los comentarios que realizas en este blog. La legitimación se realiza a través del consentimiento de la parte interesada. Si no se acepta, no podrás comentar en este blog. Los datos que proporciona solo se utilizan para evitar el correo no deseado y no se usarán para nada más. Puede ejercer los derechos de acceso, rectificación, cancelación y oposición en contacto@devexperto.com.

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Acepto la política de privacidad *