¡Hola a todos, miembros del foro!
He descubierto (me parece) a fondo el patrón
Command
y quiero intentar hablar de ello "con mis propias palabras".
Basándonos en Wikipedia, podemos descubrir que su propósito es
crear una estructura en la que la clase emisora y la clase receptora no dependan directamente entre sí. Organizar una devolución de llamada a una clase que incluye la clase remitente . En principio está escrito de forma clara y correcta, pero esto es en teoría. ¿Como hacer esto? Aquí es donde empiezan los problemas, porque... la descripción ya no es tan clara y obvia. Por lo tanto, lo descubrí, decidí contarles cómo lo entendí, tal vez le sea útil a alguien: basado en la descripción del propósito de este patrón, combinaré la descripción con el código para hacerlo más claro. porque en la misma Wikipedia lo generalizaron para muchos idiomas y por eso la descripción está separada del ejemplo. Hay cuatro términos en este patrón, démoslos por sentado por ahora: comandos (
command
), receptor de comandos (
receiver
), llamador de comandos (
invoker
) y cliente (
client
). Tomaré un ejemplo de la misma Wikipedia, es bastante tolerable.
La tarea es una clase
Light
que puede hacer dos cosas: encender la luz y apagarla. En términos del patrón será “receptor de comando (
receiver
)”
public class Light{
public Light(){ }
public void turnOn(){
System.out.println("The light is on");
}
public void turnOff(){
System.out.println("The light is off");
}
}
Creemos una interfaz con un método
execute()
que se ejecutará y que se llamará en términos del patrón "comando (
command
)"
public interface Command{
void execute();
}
Es necesario encapsular la ejecución de las habilidades de clase
Light
. Para hacer esto, crearemos clases
TurnOnLightCommand
que
TurnOffLightCommand
implementen la interfaz
Command
y que aceptarán un objeto de clase en el constructor
Light
. Y cada uno de ellos realizará una sola acción. Uno llamará al método
turnOn()
y el otro llamará
turnOff()
.
public class TurnOnLightCommand implements Command{
private Light theLight;
public TurnOnLightCommand(Light light){
this.theLight=light;
}
public void execute(){
theLight.turnOn();
}
}
public class TurnOffLightCommand implements Command{
private Light theLight;
public TurnOffLightCommand(Light light){
this.theLight=light;
}
public void execute(){
theLight.turnOff();
}
}
Ahora es el momento de crear un objeto que acepte estos métodos de objetos encapsulados
Light
. En términos del patrón, se llama llamador de comandos (invocador). Llamémoslo
Switch
y dejemos que acepte variables en el constructor
Command
que se usarán en los métodos creados
flipUp()
y
flipDown()
.
public class Switch {
private Command flipUpCommand;
private Command flipDownCommand;
public Switch(Command flipUpCommand,Command flipDownCommand){
this.flipUpCommand=flipUpCommand;
this.flipDownCommand=flipDownCommand;
}
public void flipUp(){
flipUpCommand.execute();
}
public void flipDown(){
flipDownCommand.execute();
}
}
Y, por supuesto, crearemos una clase que los utilizará para comprender lo que está pasando en general. Se llamará método principal, en el que se desarrollará toda la acción:
public class TestCommand{
public static void main(String[] args){
Light l=new Light();
Command switchUp=new TurnOnLightCommand(l);
Command switchDown=new TurnOffLightCommand(l);
Switch s=new Switch(switchUp,switchDown);
s.flipUp();
s.flipDown();
}
}
La salida será la siguiente:
"The light is on"
"The light is off"
¿Dónde se aplica esto?
El propósito es claro qué y por qué se necesita esto, a saber: en una situación en la que es necesario separar una ejecución específica, esto es muy conveniente. De modo que el uso de algunas funciones no depende de una implementación específica y se puede cambiar sin dañar el sistema. algo como esto...) Escribe tus comentarios, discutamos, tal vez algo se pueda simplificar y contar mejor, editaremos todo si es necesario) Para que para aquellos que lean por primera vez, quede lo más claro posible. Bueno, a quien le guste el artículo le pone un “+” :) Esto es importante para mí) Con el tiempo, quiero escribir más sobre
Builder
y
Singleton
otros.
Vea también mis otros artículos:
GO TO FULL VERSION