-
Notifications
You must be signed in to change notification settings - Fork 36
Expand file tree
/
Copy pathcommand.py
More file actions
95 lines (74 loc) · 2.54 KB
/
command.py
File metadata and controls
95 lines (74 loc) · 2.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
"""
Command
- An object which represents an instruction to perform a particular action.
Contains all the information necessary for the action to be taken.
Motivation
- Ordinary statements are perishable
- Cannot undo member assignment
- Cannot directly serialize a sequence of actions (calls)
- Want an object that represents an operation
- person should change its age to value 22
- car should do explode()
- Uses: GUI commands , multilevel undo/redo, macro recording and more!
"""
from abc import ABC
from enum import Enum
class BankAccount:
OVERDRAFT_LIMIT = -500
def __init__(self, balance=0):
self.balance = balance
def deposit(self, amount):
self.balance += amount
print(f'Deposited {amount}, balance = {self.balance}')
def withdraw(self, amount):
if self.balance - amount >= BankAccount.OVERDRAFT_LIMIT:
self.balance -= amount
print(f'Withdrew {amount}, balance = {self.balance}')
return True
return False
def __str__(self):
return f'Balance = {self.balance}'
# optional
class Command(ABC):
def invoke(self):
pass
def undo(self):
pass
class BankAccountCommand(Command):
def __init__(self, account, action, amount):
self.amount = amount
self.action = action
self.account = account
self.success = None
class Action(Enum):
DEPOSIT = 0
WITHDRAW = 1
def invoke(self):
if self.action == self.Action.DEPOSIT:
self.account.deposit(self.amount)
self.success = True
elif self.action == self.Action.WITHDRAW:
self.success = self.account.withdraw(self.amount)
def undo(self):
if not self.success:
return
# strictly speaking this is not correct
# (you don't undo a deposit by withdrawing)
# but it works for this demo, so...
if self.action == self.Action.DEPOSIT:
self.account.withdraw(self.amount)
elif self.action == self.Action.WITHDRAW:
self.account.deposit(self.amount)
if __name__ == '__main__':
BA = BankAccount()
CMD = BankAccountCommand(BA, BankAccountCommand.Action.DEPOSIT, 100)
CMD.invoke()
print('After $100 deposit:', BA)
CMD.undo()
print('$100 deposit undone:', BA)
ILLEGAL_CMD = BankAccountCommand(BA,
BankAccountCommand.Action.WITHDRAW, 1000)
ILLEGAL_CMD.invoke()
print('After impossible withdrawal:', BA)
ILLEGAL_CMD.undo()
print('After undo:', BA)