Skip to content

Commit fed1e21

Browse files
committed
changed the example to implement undo feature
1 parent 119ad75 commit fed1e21

File tree

1 file changed

+79
-23
lines changed

1 file changed

+79
-23
lines changed

patterns/behavioral/command.py

Lines changed: 79 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@
66
it is pressed. To achieve this you implement a command object with the `execute`
77
method for each menu item and pass to it.
88
9+
*About the example
10+
We have a menu containing two items. Each item accept a file name, one hides the file
11+
and the other deletes it. Both items have undo option.
12+
Each item is a MenuItem class that accept corresponding command as input and executes
13+
its `execute` method when it is pressed.
14+
915
*TL;DR
1016
Object oriented implementation of callback functions.
1117
@@ -14,33 +20,65 @@
1420
https://docs.djangoproject.com/en/2.1/ref/request-response/#httprequest-objects
1521
"""
1622

23+
import os
24+
1725

18-
class Command:
26+
class HideFileCommand:
1927
"""
20-
The interface that commands implement. This is used to abstract invoker from
21-
the command is going to handle the job.
28+
A command to hide a file given its name
2229
"""
2330

24-
def execute(self):
25-
raise NotImplementedError()
31+
def __init__(self):
32+
# an array of files hidden, to undo them as needed
33+
self._hidden_files = []
2634

35+
def execute(self, filename):
36+
if os.path.isfile(filename):
37+
print(f'hiding {filename}')
2738

28-
class MakeBoldCommand(Command):
29-
"""
30-
A simple command to bold a text.
31-
"""
39+
os.rename(filename, f'.{filename}')
40+
self._hidden_files.append(filename)
41+
else:
42+
print(f'{filename} dose not exists to hide')
43+
44+
def undo(self):
45+
if len(self._hidden_files) > 0:
46+
filename = self._hidden_files.pop()
3247

33-
def execute(self):
34-
print('I am making it bold.')
48+
print(f'un-hiding {filename}')
3549

50+
os.rename(f'.{filename}', filename)
3651

37-
class MakeItalicCommand(Command):
52+
53+
class DeleteFileCommand:
3854
"""
39-
A simple command to italic a text.
55+
A command to delete a file given its name
4056
"""
4157

42-
def execute(self):
43-
print('I am making it italic.')
58+
def __init__(self):
59+
# an array of deleted files, to undo them as needed
60+
self._deleted_files = []
61+
62+
# create a directory to store deleted files
63+
if not os.path.exists('bin'):
64+
os.makedirs('bin')
65+
66+
def execute(self, filename):
67+
if os.path.isfile(filename):
68+
print(f'deleting {filename}')
69+
70+
os.rename(filename, f'bin/{filename}')
71+
self._deleted_files.append(filename)
72+
else:
73+
print(f'{filename} dose not exists to delete')
74+
75+
def undo(self):
76+
if len(self._deleted_files) > 0:
77+
filename = self._deleted_files.pop()
78+
79+
print(f'un-deleting {filename}')
80+
81+
os.rename(f'bin/{filename}', filename)
4482

4583

4684
class MenuItem:
@@ -51,24 +89,42 @@ class MenuItem:
5189
def __init__(self, command):
5290
self._command = command
5391

54-
def on_press(self):
55-
self._command.execute()
92+
def on_do_press(self, filename):
93+
self._command.execute(filename)
94+
95+
def on_undo_press(self):
96+
self._command.undo()
5697

5798

5899
def main():
59100
"""
60-
>>> item1 = MenuItem(MakeBoldCommand())
101+
>>> item1 = MenuItem(DeleteFileCommand())
61102
62-
>>> item2 = MenuItem(MakeItalicCommand())
103+
>>> item2 = MenuItem(HideFileCommand())
63104
64-
>>> item1.on_press()
65-
I am making it bold.
105+
# create a file named `test-file` to work with
106+
>>> test_file_name = 'test-file'
107+
>>> open(test_file_name, 'w').close()
66108
67-
>>> item2.on_press()
68-
I am making it italic.
109+
# deleting `test-file`
110+
>>> item1.on_do_press(test_file_name)
111+
deleting test-file
112+
113+
# hiding `test-file` but it dose not exists
114+
>>> item2.on_do_press(test_file_name)
115+
test-file dose not exists to hide
116+
117+
# un-deleting `test-file`
118+
>>> item1.on_undo_press()
119+
un-deleting test-file
120+
121+
# hiding `test-file`
122+
>>> item2.on_do_press(test_file_name)
123+
hiding test-file
69124
"""
70125

71126

72127
if __name__ == "__main__":
73128
import doctest
129+
74130
doctest.testmod()

0 commit comments

Comments
 (0)