Skip to content

Commit d989908

Browse files
committed
🔧 Adding
Command Pattern
1 parent 9e1ed58 commit d989908

File tree

1 file changed

+138
-0
lines changed

1 file changed

+138
-0
lines changed
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
from abc import ABC, abstractmethod
2+
3+
4+
# Receiver: The actual business logic
5+
class Editor:
6+
def __init__(self):
7+
self.text = ""
8+
self.clipboard = ""
9+
self.selection = ""
10+
11+
def get_selection(self):
12+
return self.selection
13+
14+
def delete_selection(self):
15+
print("Deleting selection...")
16+
self.text = self.text.replace(self.selection, "")
17+
self.selection = ""
18+
19+
def replace_selection(self, new_text):
20+
print(f"Replacing selection with: {new_text}")
21+
self.text = self.text.replace(self.selection, new_text)
22+
self.selection = new_text
23+
24+
def set_selection(self, selection):
25+
self.selection = selection
26+
27+
def __str__(self):
28+
return f"Text: '{self.text}' | Selection: '{self.selection}'"
29+
30+
31+
# Command Interface
32+
class Command(ABC):
33+
def __init__(self, editor: Editor):
34+
self.editor = editor
35+
self._backup = ""
36+
37+
def save_backup(self):
38+
self._backup = self.editor.text
39+
40+
def undo(self):
41+
self.editor.text = self._backup
42+
43+
@abstractmethod
44+
def execute(self) -> bool:
45+
pass
46+
47+
48+
# Command History
49+
class CommandHistory:
50+
def __init__(self):
51+
self._history = []
52+
53+
def push(self, command: Command):
54+
self._history.append(command)
55+
56+
def pop(self):
57+
return self._history.pop() if self._history else None
58+
59+
60+
# Concrete Commands
61+
class CopyCommand(Command):
62+
def execute(self):
63+
self.editor.clipboard = self.editor.get_selection()
64+
print(f"Copied: '{self.editor.clipboard}'")
65+
return False # No text modified
66+
67+
68+
class CutCommand(Command):
69+
def execute(self):
70+
self.save_backup()
71+
self.editor.clipboard = self.editor.get_selection()
72+
self.editor.delete_selection()
73+
return True # Text modified
74+
75+
76+
class PasteCommand(Command):
77+
def execute(self):
78+
self.save_backup()
79+
self.editor.replace_selection(self.editor.clipboard)
80+
return True # Text modified
81+
82+
83+
class UndoCommand(Command):
84+
def __init__(self, history: CommandHistory):
85+
self.history = history
86+
87+
def execute(self):
88+
command = self.history.pop()
89+
if command:
90+
print("Undoing last command...")
91+
command.undo()
92+
else:
93+
print("Nothing to undo.")
94+
return False
95+
96+
97+
# Invoker
98+
class Application:
99+
def __init__(self):
100+
self.editor = Editor()
101+
self.history = CommandHistory()
102+
103+
def execute_command(self, command: Command):
104+
if command.execute():
105+
self.history.push(command)
106+
107+
def run(self):
108+
self.editor.text = "Hello, World!"
109+
self.editor.set_selection("World")
110+
111+
print("\nInitial Editor State:", self.editor)
112+
113+
# CUT
114+
self.execute_command(CutCommand(self.editor))
115+
print("After Cut:", self.editor)
116+
117+
# PASTE
118+
self.editor.set_selection("Hello")
119+
self.execute_command(PasteCommand(self.editor))
120+
print("After Paste:", self.editor)
121+
122+
# COPY
123+
self.editor.set_selection("Hello")
124+
self.execute_command(CopyCommand(self.editor))
125+
print("After Copy (Clipboard):", self.editor.clipboard)
126+
127+
# UNDO
128+
undo = UndoCommand(self.history)
129+
self.execute_command(undo)
130+
print("After Undo 1:", self.editor)
131+
132+
self.execute_command(undo)
133+
print("After Undo 2:", self.editor)
134+
135+
136+
if __name__ == "__main__":
137+
app = Application()
138+
app.run()

0 commit comments

Comments
 (0)