In this unit, we'll implement two essential design patterns: the Command pattern and the Decorator pattern, aimed at enhancing our smart home automation and lighting system. These patterns help create a more flexible and expandable system for automation and lighting control.
Command Pattern:
execute
method.LightOnCommand
, LightOffCommand
) that implement this interface and perform specific actions.Light
) with methods to turn the light on and off.RemoteControl
) to store and execute commands.Decorator Pattern:
Light
).LightDecorator
) that implements the component interface and holds a reference to a component object.ColorChangeDecorator
) to extend functionalities of the basic component.Using the Command pattern, we define our commands and receivers, then utilize an invoker to store and execute commands. This enables flexible and parameterizable control over our smart home system.
Here is the complete code for implementing the Command pattern:
Python1from abc import ABC, abstractmethod 2 3# Define the Command interface 4class Command(ABC): 5 @abstractmethod 6 def execute(self): 7 pass 8 9# Concrete command classes for turning the light on and off 10class LightOnCommand(Command): 11 def __init__(self, light): 12 self.light = light 13 14 def execute(self): 15 self.light.turn_on() 16 17class LightOffCommand(Command): 18 def __init__(self, light): 19 self.light = light 20 21 def execute(self): 22 self.light.turn_off() 23 24# Receiver class encapsulating the light functionalities 25class Light: 26 def turn_on(self): 27 print("The light is on") 28 29 def turn_off(self): 30 print("The light is off") 31 32# Invoker class to store and execute commands 33class RemoteControl: 34 def __init__(self): 35 self.slots = {} 36 37 def set_command(self, command_name, command): 38 self.slots[command_name] = command 39 40 def press_button(self, command_name): 41 if command_name in self.slots: 42 self.slots[command_name].execute() 43 else: 44 print(f"No command found for {command_name}") 45 46# Example of setting up and using the command pattern 47if __name__ == "__main__": 48 living_room_light = Light() 49 50 light_on_command = LightOnCommand(living_room_light) 51 light_off_command = LightOffCommand(living_room_light) 52 53 remote_control = RemoteControl() 54 55 remote_control.set_command("light_on", light_on_command) 56 remote_control.set_command("light_off", light_off_command) 57 58 remote_control.press_button("light_on") # Expected Output: The light is on 59 remote_control.press_button("light_off") # Expected Output: The light is off
By using the Decorator pattern, we can dynamically enhance our smart home's lighting system with additional features without altering the underlying structure.
Here is the complete code for implementing the Decorator pattern:
Python1# Basic Light class 2class Light: 3 def operate(self): 4 return "Basic light operation" 5 6# Base Decorator class 7class LightDecorator(Light): 8 def __init__(self, decorated_light): 9 self.decorated_light = decorated_light 10 11 def operate(self): 12 return self.decorated_light.operate() 13 14# Concrete Decorator for adding color-changing functionality 15class ColorChangeDecorator(LightDecorator): 16 def operate(self): 17 return f"{super().operate()} with color change" 18 19# Example of using the decorator pattern 20if __name__ == "__main__": 21 basic_light = Light() 22 print(basic_light.operate()) # Expected Output: Basic light operation 23 24 color_light = ColorChangeDecorator(basic_light) 25 print(color_light.operate()) # Expected Output: Basic light operation with color change
Implementing the Command and Decorator patterns in our smart home system provides flexibility and scalability. The Command pattern encapsulates requests as objects, allowing for parameterizable and undoable operations. The Decorator pattern dynamically adds functionalities, making the system adaptable and extensible.