Skip to content

Commit 08ecc5b

Browse files
committed
Add TypeScript examples
1 parent 7d9f0b9 commit 08ecc5b

File tree

2 files changed

+198
-0
lines changed

2 files changed

+198
-0
lines changed

TypeScript/1-traditional.ts

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
abstract class AccountCommand {
2+
public account: BankAccount;
3+
public amount: number;
4+
public operation: string;
5+
6+
constructor(account: BankAccount, amount: number, operation: string) {
7+
this.account = account;
8+
this.amount = amount;
9+
this.operation = operation;
10+
}
11+
12+
abstract execute(): void;
13+
abstract undo(): void;
14+
}
15+
16+
class Withdraw extends AccountCommand {
17+
constructor(account: BankAccount, amount: number) {
18+
super(account, amount, 'withdraw');
19+
}
20+
21+
execute(): void {
22+
this.account.balance -= this.amount;
23+
}
24+
25+
undo(): void {
26+
this.account.balance += this.amount;
27+
}
28+
}
29+
30+
class Income extends AccountCommand {
31+
constructor(account: BankAccount, amount: number) {
32+
super(account, amount, 'income');
33+
}
34+
35+
execute(): void {
36+
this.account.balance += this.amount;
37+
}
38+
39+
undo(): void {
40+
this.account.balance -= this.amount;
41+
}
42+
}
43+
44+
class BankAccount {
45+
public name: string;
46+
public balance: number;
47+
48+
constructor(name: string) {
49+
this.name = name;
50+
this.balance = 0;
51+
}
52+
}
53+
54+
class Bank {
55+
private commands: AccountCommand[] = [];
56+
57+
operation(account: BankAccount, amount: number): void {
58+
const Command = amount < 0 ? Withdraw : Income;
59+
const command = new Command(account, Math.abs(amount));
60+
command.execute();
61+
this.commands.push(command);
62+
}
63+
64+
undo(count: number): void {
65+
for (let i = 0; i < count; i++) {
66+
const command = this.commands.pop();
67+
if (command) {
68+
command.undo();
69+
}
70+
}
71+
}
72+
73+
showOperations(): void {
74+
const output = this.commands.map((command) => ({
75+
operation: command.operation,
76+
account: command.account.name,
77+
amount: command.amount,
78+
}));
79+
console.table(output);
80+
}
81+
}
82+
83+
// Usage
84+
85+
const bank = new Bank();
86+
const account1 = new BankAccount('Marcus Aurelius');
87+
bank.operation(account1, 1000);
88+
bank.operation(account1, -50);
89+
const account2 = new BankAccount('Antoninus Pius');
90+
bank.operation(account2, 500);
91+
bank.operation(account2, -100);
92+
bank.operation(account2, 150);
93+
bank.showOperations();
94+
console.table([account1, account2]);
95+
bank.undo(2);
96+
bank.showOperations();
97+
console.table([account1, account2]);

TypeScript/2-js-way.ts

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
type Account = {
2+
name: string;
3+
balance: number;
4+
};
5+
6+
const accounts = new Map<string, Account>();
7+
8+
const addAccount = (name: string): Account => {
9+
const account: Account = { name, balance: 0 };
10+
accounts.set(name, account);
11+
return account;
12+
};
13+
14+
interface Command {
15+
operation: string;
16+
account: string;
17+
amount: number;
18+
}
19+
20+
type OperationType = 'withdraw' | 'income';
21+
22+
const OPERATIONS: Record<OperationType, {
23+
execute: (command: Command) => void;
24+
undo: (command: Command) => void;
25+
}> = {
26+
withdraw: {
27+
execute: (command: Command): void => {
28+
const account = accounts.get(command.account);
29+
if (account) {
30+
account.balance -= command.amount;
31+
}
32+
},
33+
undo: (command: Command): void => {
34+
const account = accounts.get(command.account);
35+
if (account) {
36+
account.balance += command.amount;
37+
}
38+
},
39+
},
40+
income: {
41+
execute: (command: Command): void => {
42+
const account = accounts.get(command.account);
43+
if (account) {
44+
account.balance += command.amount;
45+
}
46+
},
47+
undo: (command: Command): void => {
48+
const account = accounts.get(command.account);
49+
if (account) {
50+
account.balance -= command.amount;
51+
}
52+
},
53+
},
54+
};
55+
56+
class Bank {
57+
private commands: Command[] = [];
58+
59+
operation(account: Account, amount: number): void {
60+
const operation = amount < 0 ? 'withdraw' : 'income';
61+
const { execute } = OPERATIONS[operation];
62+
const command: Command = {
63+
operation,
64+
account: account.name,
65+
amount: Math.abs(amount),
66+
};
67+
this.commands.push(command);
68+
execute(command);
69+
}
70+
71+
undo(count: number): void {
72+
for (let i = 0; i < count; i++) {
73+
const command = this.commands.pop();
74+
if (command) {
75+
const operation = command.operation as OperationType;
76+
const { undo } = OPERATIONS[operation];
77+
undo(command);
78+
}
79+
}
80+
}
81+
82+
showOperations(): void {
83+
console.table(this.commands);
84+
}
85+
}
86+
87+
// Usage
88+
89+
const bank = new Bank();
90+
const account1 = addAccount('Marcus Aurelius');
91+
bank.operation(account1, 1000);
92+
bank.operation(account1, -50);
93+
const account2 = addAccount('Antoninus Pius');
94+
bank.operation(account2, 500);
95+
bank.operation(account2, -100);
96+
bank.operation(account2, 150);
97+
bank.showOperations();
98+
console.table([account1, account2]);
99+
bank.undo(2);
100+
bank.showOperations();
101+
console.table([account1, account2]);

0 commit comments

Comments
 (0)