El patrón State modela transiciones de estado como clases con comportamiento propio.
1. El Problema de Partida
Un post de knowledge pasa por draft → review → published. El script scripts/publish-post.js verificaba el campo status con if/else anidados: si está en draft puede pasar a review, si está en review puede publicarse o volver a draft, si está published no puede modificarse. Cada regla nueva (ej. "solo el admin puede publicar") añadía más ramas al mismo bloque.
2. La Solución State
// src/lib/workflow/PostState.js
class DraftState {
submitForReview(post) {
post.setState(new ReviewState());
return 'Enviado a revisión';
}
publish() { throw new Error('Un borrador no puede publicarse directamente'); }
}
class ReviewState {
submitForReview() { throw new Error('Ya está en revisión'); }
publish(post) {
post.setState(new PublishedState());
return 'Post publicado';
}
}
class PublishedState {
submitForReview() { throw new Error('Un post publicado no vuelve a revisión'); }
publish() { throw new Error('Ya está publicado'); }
}
export class Post {
state = new DraftState();
setState(state) { this.state = state; }
submitForReview() { return this.state.submitForReview(this); }
publish() { return this.state.publish(this); }
}3. Uso
// scripts/publish-post.js
import { Post } from '@/lib/workflow/PostState';
const post = new Post();
console.log(post.submitForReview()); // "Enviado a revisión"
console.log(post.publish()); // "Post publicado"
post.publish(); // Lanza: "Ya está publicado"4. Ventajas
- Transiciones explícitas: cada estado sabe a qué otro estado puede pasar, sin
ifgigantes dispersos. - Reglas nuevas aisladas: añadir un estado
archivedes una clase nueva, sin tocar las existentes. - Imposible un estado inválido: las transiciones no permitidas lanzan error de forma centralizada.