Eh, acabo de reducir el precio de todos los productos. Preparemos nuestras habilidades de programación para la era posterior a la COVID. Más detalles »
State es un patrón de diseño de comportamiento que permite a un objeto cambiar de comportamiento cuando cambia su estado interno.
El patrón extrae comportamientos relacionados con el estado, los coloca dentro de clases de estado separadas y fuerza al objeto original a delegar el trabajo de una instancia de esas clases, en lugar de actuar por su cuenta.
Ejemplos de uso: El patrón State se utiliza ocasionalmente en PHP para convertir grandes y voluminosas máquinas de estados basadas en operadores switch, en objetos.
Identificación: El patrón State se puede reconocer por métodos que cambian su comportamiento dependiendo del estado del objeto, controlado externamente.
Este ejemplo ilustra la estructura del patrón de diseño State y se centra en las siguientes preguntas:
¿De qué clases se compone?
¿Qué papeles juegan esas clases?
¿De qué forma se relacionan los elementos del patrón?
Después de conocer la estructura del patrón, será más fácil comprender el siguiente ejemplo basado en un caso de uso real en PHP.
index.php: Ejemplo conceptual
<?php
namespace RefactoringGuru\State\Conceptual;
/**
* The Context defines the interface of interest to clients. It also maintains a
* reference to an instance of a State subclass, which represents the current
* state of the Context.
*/
class Context
{
/**
* @var State A reference to the current state of the Context.
*/
private $state;
public function __construct(State $state)
{
$this->transitionTo($state);
}
/**
* The Context allows changing the State object at runtime.
*/
public function transitionTo(State $state): void
{
echo "Context: Transition to " . get_class($state) . ".\n";
$this->state = $state;
$this->state->setContext($this);
}
/**
* The Context delegates part of its behavior to the current State object.
*/
public function request1(): void
{
$this->state->handle1();
}
public function request2(): void
{
$this->state->handle2();
}
}
/**
* The base State class declares methods that all Concrete State should
* implement and also provides a backreference to the Context object, associated
* with the State. This backreference can be used by States to transition the
* Context to another State.
*/
abstract class State
{
/**
* @var Context
*/
protected $context;
public function setContext(Context $context)
{
$this->context = $context;
}
abstract public function handle1(): void;
abstract public function handle2(): void;
}
/**
* Concrete States implement various behaviors, associated with a state of the
* Context.
*/
class ConcreteStateA extends State
{
public function handle1(): void
{
echo "ConcreteStateA handles request1.\n";
echo "ConcreteStateA wants to change the state of the context.\n";
$this->context->transitionTo(new ConcreteStateB());
}
public function handle2(): void
{
echo "ConcreteStateA handles request2.\n";
}
}
class ConcreteStateB extends State
{
public function handle1(): void
{
echo "ConcreteStateB handles request1.\n";
}
public function handle2(): void
{
echo "ConcreteStateB handles request2.\n";
echo "ConcreteStateB wants to change the state of the context.\n";
$this->context->transitionTo(new ConcreteStateA());
}
}
/**
* The client code.
*/
$context = new Context(new ConcreteStateA());
$context->request1();
$context->request2();
Output.txt: Resultado de la ejecución
Context: Transition to RefactoringGuru\State\Conceptual\ConcreteStateA.
ConcreteStateA handles request1.
ConcreteStateA wants to change the state of the context.
Context: Transition to RefactoringGuru\State\Conceptual\ConcreteStateB.
ConcreteStateB handles request2.
ConcreteStateB wants to change the state of the context.
Context: Transition to RefactoringGuru\State\Conceptual\ConcreteStateA.
Ejemplo del mundo real
Aunque los conceptos de las máquinas de estado y del propio patrón State son muy populares entre los desarrolladores, no se me ocurre ningún ejemplo decente en el mundo real de este patrón en una aplicación PHP real.
No obstante, si has utilizado el patrón en tu proyecto previamente, no dudes en compartir tu experiencia en el foro o por correo electrónico, en support@refactoring.guru. ¡Gracias!