xxxxxxxxxx
// Command interface
public interface ICommand
{
void Execute();
}
// Concrete command for turning on the TV
public class TvOnCommand : ICommand
{
private readonly TV tv;
public TvOnCommand(TV tv)
{
this.tv = tv;
}
public void Execute()
{
tv.TurnOn();
}
}
// Concrete command for turning on the Stereo
public class StereoOnCommand : ICommand
{
private readonly Stereo stereo;
public StereoOnCommand(Stereo stereo)
{
this.stereo = stereo;
}
public void Execute()
{
stereo.TurnOn();
stereo.SetVolume(5);
}
}
// Receiver classes representing electronic devices
public class TV
{
public void TurnOn()
{
Console.WriteLine("TV is turned on.");
}
public void TurnOff()
{
Console.WriteLine("TV is turned off.");
}
}
public class Stereo
{
public void TurnOn()
{
Console.WriteLine("Stereo is turned on.");
}
public void TurnOff()
{
Console.WriteLine("Stereo is turned off.");
}
public void SetVolume(int volume)
{
Console.WriteLine($"Stereo volume set to {volume}.");
}
}
// Invoker class (Remote Control)
public class RemoteControl
{
private readonly ICommand[] onCommands;
private readonly ICommand[] offCommands;
public RemoteControl()
{
onCommands = new ICommand[2];
offCommands = new ICommand[2];
// Initialize commands with NoCommand (a command with no action)
for (int i = 0; i < 2; i++)
{
onCommands[i] = new NoCommand();
offCommands[i] = new NoCommand();
}
}
public void SetCommand(int slot, ICommand onCommand, ICommand offCommand)
{
onCommands[slot] = onCommand;
offCommands[slot] = offCommand;
}
public void OnButtonPressed(int slot)
{
onCommands[slot].Execute();
}
public void OffButtonPressed(int slot)
{
offCommands[slot].Execute();
}
}
// Concrete command for no action (NoCommand)
public class NoCommand : ICommand
{
public void Execute()
{
// Do nothing
}
}
class Program
{
static void Main()
{
// Client code
TV tv = new TV();
Stereo stereo = new Stereo();
ICommand tvOnCommand = new TvOnCommand(tv);
ICommand tvOffCommand = new NoCommand(); // No TV off command implemented in this example
ICommand stereoOnCommand = new StereoOnCommand(stereo);
ICommand stereoOffCommand = new NoCommand(); // No Stereo off command implemented in this example
RemoteControl remoteControl = new RemoteControl();
remoteControl.SetCommand(0, tvOnCommand, tvOffCommand);
remoteControl.SetCommand(1, stereoOnCommand, stereoOffCommand);
// Pressing the remote buttons
remoteControl.OnButtonPressed(0); // Turns on the TV
remoteControl.OffButtonPressed(0); // No TV off command, so nothing happens
remoteControl.OnButtonPressed(1); // Turns on the Stereo
}
}
xxxxxxxxxx
These are the following participants of the Command Design pattern:
Command This is an interface for executing an operation.
ConcreteCommand This class extends the Command interface and implements the execute method. This class creates a binding between the action and the receiver.
Client This class creates the ConcreteCommand class and associates it with the receiver.
Invoker This class asks the command to carry out the request.
Receiver This class knows to perform the operation
xxxxxxxxxx
class CommandDesignDemo {
public static void main(String[] args) {
AC ac1 = new AC();
AC ac2 = new AC();
ACAutomationRemote remote = new ACAutomationRemote();
remote.setCommand(() -> ac2.turnOn());
remote.buttonPressed();
}
}
xxxxxxxxxx
2. Command Pattern:
The Command pattern encapsulates a request as an object, thereby allowing for parameterization of clients with queues, requests, and operations.
Example in React:
Suppose you want to create a simple undo/redo functionality for user actions in your React app.
import React, { useState } from 'react';
const CommandPatternExample = () => {
const [text, setText] = useState('');
const [history, setHistory] = useState([]);
const [currentIndex, setCurrentIndex] = useState(-1);
const executeCommand = (command) => {
setHistory((prevHistory) => [prevHistory, command]);
setCurrentIndex(currentIndex + 1);
};
const undo = () => {
if (currentIndex > 0) {
setCurrentIndex(currentIndex - 1);
setText(history[currentIndex - 1]);
}
};
const redo = () => {
if (currentIndex < history.length - 1) {
setCurrentIndex(currentIndex + 1);
setText(history[currentIndex + 1]);
}
};
return (
<div>
<input
type="text"
value={text}
onChange={(e) => setText(e.target.value)}
/>
<button onClick={() => executeCommand(text)}>Submit</button>
<button onClick={undo}>Undo</button>
<button onClick={redo}>Redo</button>
</div>
);
};
export default CommandPatternExample;