File tree Expand file tree Collapse file tree 11 files changed +379
-0
lines changed
section-04-behavioral-design-patterns/16-command
src/main/java/com/luv2code/designpatterns/behavioral/command Expand file tree Collapse file tree 11 files changed +379
-0
lines changed Original file line number Diff line number Diff line change 1+ <?xml version =" 1.0" encoding =" UTF-8" ?>
2+ <project xmlns =" http://maven.apache.org/POM/4.0.0"
3+ xmlns : xsi =" http://www.w3.org/2001/XMLSchema-instance"
4+ xsi : schemaLocation =" http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" >
5+ <modelVersion >4.0.0</modelVersion >
6+
7+ <groupId >com.luv2code</groupId >
8+ <artifactId >java-design-patterns</artifactId >
9+ <version >1.0</version >
10+
11+ <properties >
12+ <maven .compiler.source>25</maven .compiler.source>
13+ <maven .compiler.target>25</maven .compiler.target>
14+ <project .build.sourceEncoding>UTF-8</project .build.sourceEncoding>
15+ </properties >
16+
17+ </project >
Original file line number Diff line number Diff line change 1+ package com .luv2code .designpatterns .behavioral .command ;
2+
3+ /**
4+ * Role: Receiver
5+ *
6+ * Knows how to perform the actual lighting operations.
7+ * Has no knowledge of the Command pattern.
8+ */
9+ public class Light {
10+
11+ private String location ;
12+
13+ public Light (String location ) {
14+ this .location = location ;
15+ }
16+
17+ public String getLocation () {
18+ return location ;
19+ }
20+
21+ public void turnOn () {
22+ System .out .println ("[Device] " + location + " light -> ON" );
23+ }
24+
25+ public void turnOff () {
26+ System .out .println ("[Device] " + location + " light -> OFF" );
27+ }
28+
29+ }
30+
31+
32+
33+
34+
35+
36+
37+
38+
39+
Original file line number Diff line number Diff line change 1+ package com .luv2code .designpatterns .behavioral .command ;
2+
3+ /**
4+ * Role: ConcreteCommand
5+ *
6+ * Turns a Light off.
7+ * Undo turns the light on.
8+ */
9+ public class LightOffCommand implements SmartHomeCommand {
10+
11+ private Light light ;
12+
13+ public LightOffCommand (Light light ) {
14+ this .light = light ;
15+ }
16+
17+ @ Override
18+ public void execute () {
19+ light .turnOff ();
20+ }
21+
22+ @ Override
23+ public void undo () {
24+ light .turnOn ();
25+ }
26+
27+ @ Override
28+ public String getDescription () {
29+ return "Turn " + light .getLocation () + " light OFF" ;
30+ }
31+ }
Original file line number Diff line number Diff line change 1+ package com .luv2code .designpatterns .behavioral .command ;
2+
3+ /**
4+ * Role: ConcreteCommand
5+ *
6+ * Turns a Light on.
7+ * Undo turns the light off.
8+ */
9+ public class LightOnCommand implements SmartHomeCommand {
10+
11+ private Light light ;
12+
13+ public LightOnCommand (Light light ) {
14+ this .light = light ;
15+ }
16+
17+ @ Override
18+ public void execute () {
19+ light .turnOn ();
20+ }
21+
22+ @ Override
23+ public void undo () {
24+ light .turnOff ();
25+ }
26+
27+ @ Override
28+ public String getDescription () {
29+ return "Turn " + light .getLocation () + " light ON" ;
30+ }
31+ }
Original file line number Diff line number Diff line change 1+ package com .luv2code .designpatterns .behavioral .command ;
2+
3+ /**
4+ * Role: Client
5+ *
6+ * Demonstrates the Command pattern.
7+ * The RemoteControl (Invoker) is reused across all demos without modification.
8+ */
9+ public class MainApp {
10+
11+ static void main () {
12+
13+ System .out .println ("--- Demo 1: Smart Home Demo ---" );
14+ runSmartHomeDemo ();
15+
16+ System .out .println ("\n --- Demo 2: Thermostat Demo ---" );
17+ runThermostatDemo ();
18+
19+ System .out .println ("\n --- Demo 3: Pet Food Demo ---" );
20+ runPetFoodDemo ();
21+ }
22+
23+ private static void runPetFoodDemo () {
24+
25+ PetFoodDispenser petFoodDispenser = new PetFoodDispenser ("Max" );
26+ RemoteControl remoteControl = new RemoteControl ();
27+
28+ remoteControl .pressButton (new PetFoodDispenserCommand (petFoodDispenser ));
29+
30+ // Attempting undo
31+ remoteControl .pressUndo ();
32+ }
33+
34+ private static void runThermostatDemo () {
35+
36+ Thermostat thermostat = new Thermostat (18 );
37+ RemoteControl remoteControl = new RemoteControl ();
38+
39+ remoteControl .pressButton (new ThermostatSetCommand (thermostat , 22 ));
40+
41+ System .out .println ("\n -- Undoing temperature change ---" );
42+ remoteControl .pressUndo ();
43+ }
44+
45+ private static void runSmartHomeDemo () {
46+
47+ Light livingRoomLight = new Light ("Living Room" );
48+ RemoteControl remoteControl = new RemoteControl ();
49+
50+ remoteControl .pressButton (new LightOnCommand (livingRoomLight ));
51+ remoteControl .pressButton (new LightOffCommand (livingRoomLight ));
52+
53+ System .out .println ();
54+ remoteControl .printHistory ();
55+ }
56+ }
57+
58+
59+
60+
61+
62+
63+
64+
65+
66+
67+
68+
69+
70+
71+
72+
73+
74+
Original file line number Diff line number Diff line change 1+ package com .luv2code .designpatterns .behavioral .command ;
2+
3+ /**
4+ * Role: Receiver
5+ *
6+ * Knows how to dispense a single serving of pet food.
7+ * Has no knowledge of the Command pattern.
8+ */
9+ public class PetFoodDispenser {
10+
11+ private String petName ;
12+
13+ public PetFoodDispenser (String petName ) {
14+ this .petName = petName ;
15+ }
16+
17+ public void dispense () {
18+ System .out .println ("[Device] Dispensing one serving for " + petName );
19+ }
20+ }
Original file line number Diff line number Diff line change 1+ package com .luv2code .designpatterns .behavioral .command ;
2+
3+ /**
4+ * Role: ConcreteCommand
5+ *
6+ * Dispenses a single serving of pet food.
7+ * This action is irreversible - undo does nothing.
8+ */
9+ public class PetFoodDispenserCommand implements SmartHomeCommand {
10+
11+ private PetFoodDispenser petFoodDispenser ;
12+
13+ public PetFoodDispenserCommand (PetFoodDispenser petFoodDispenser ) {
14+ this .petFoodDispenser = petFoodDispenser ;
15+ }
16+
17+ @ Override
18+ public void execute () {
19+ petFoodDispenser .dispense ();
20+ }
21+
22+ @ Override
23+ public void undo () {
24+ System .out .println ("[Command] Cannot undo: food already dispensed." );
25+ }
26+
27+ @ Override
28+ public String getDescription () {
29+ return "Dispense pet food serving" ;
30+ }
31+ }
Original file line number Diff line number Diff line change 1+ package com .luv2code .designpatterns .behavioral .command ;
2+
3+ import java .util .ArrayDeque ;
4+ import java .util .Deque ;
5+
6+ /**
7+ * Role: Invoker
8+ *
9+ * Triggers commands and maintains a history stack for undo support.
10+ * Depends only on the SmartHomeCommand interface.
11+ */
12+ public class RemoteControl {
13+
14+ private Deque <SmartHomeCommand > history = new ArrayDeque <>();
15+
16+ public void pressButton (SmartHomeCommand command ) {
17+ if (command == null ) {
18+ throw new IllegalArgumentException ("Command cannot be null" );
19+ }
20+
21+ command .execute ();
22+ history .push (command );
23+ }
24+
25+ public void pressUndo () {
26+ if (history .isEmpty ()) {
27+ System .out .println ("[Remote] Nothing to undo." );
28+ }
29+
30+ SmartHomeCommand command = history .pop ();
31+ System .out .println ("[Remote] Undoing: " + command .getDescription ());
32+ command .undo ();
33+ }
34+
35+ public void printHistory () {
36+ System .out .println ("[Remote] Command History (most recent first):" );
37+
38+ if (history .isEmpty ()) {
39+ System .out .println (" (empty)" );
40+ } else {
41+ for (SmartHomeCommand tempCommand : history ) {
42+ System .out .println (" - " + tempCommand .getDescription ());
43+ }
44+ }
45+ }
46+
47+ }
48+
49+
50+
51+
52+
53+
54+
55+
56+
57+
58+
Original file line number Diff line number Diff line change 1+ package com .luv2code .designpatterns .behavioral .command ;
2+
3+ /**
4+ * Role: Command
5+ *
6+ * Declares the contract for all smart home commands.
7+ * Every concrete command must support execute, undo and a description.
8+ */
9+ public interface SmartHomeCommand {
10+
11+ void execute ();
12+
13+ void undo ();
14+
15+ String getDescription ();
16+ }
Original file line number Diff line number Diff line change 1+ package com .luv2code .designpatterns .behavioral .command ;
2+
3+ /**
4+ * Role: Receiver
5+ *
6+ * Knows how to perform temperature changes.
7+ * Has no knowledge of the Command pattern.
8+ */
9+ public class Thermostat {
10+
11+ private int temperatureCelsius ;
12+
13+ public Thermostat (int temperatureCelsius ) {
14+ this .temperatureCelsius = temperatureCelsius ;
15+ }
16+
17+ public int getTemperatureCelsius () {
18+ return temperatureCelsius ;
19+ }
20+
21+ public void setTemperatureCelsius (int temperatureCelsius ) {
22+ System .out .println ("[Device] Thermostat: " + this .temperatureCelsius
23+ + "C -> " + temperatureCelsius + "C" );
24+ this .temperatureCelsius = temperatureCelsius ;
25+ }
26+ }
You can’t perform that action at this time.
0 commit comments