Updated: 03 September 2023

1
interface Todo {
2
id: number
3
name: string
4
done: boolean
5
}
6
7
const todo: Todo = {
8
done: false,
9
id: 0,
10
name: 'task',
11
}
12
13
interface StorageStrategy {
14
get(id: number): Todo
15
getAll(): Todo[]
16
delete(id: number): void
17
save(todo: Todo): void
18
}
19
20
type InitializerStrategy = (todo: Todo) => Todo
21
22
class TodoDB {
23
constructor(
24
private readonly storage: StorageStrategy,
25
private readonly intializer: InitializerStrategy
26
) {}
27
28
getItems(): Todo[] {
29
return this.storage.getAll()
30
}
31
32
getItem(id: number): Todo {
33
return this.storage.get(id)
34
}
35
36
addItem(todo: Todo): void {
37
const item = this.intializer(todo)
38
this.storage.save(item)
39
}
40
41
removeItem(id: number): void {
42
this.storage.delete(id)
43
}
44
45
updateItem(todo: Todo): Todo {
46
this.storage.save(todo)
47
return todo
48
}
49
50
completeItem(id: number): Todo {
51
const todo = this.storage.get(id)
52
const updated = {
53
...todo,
54
done: true,
55
}
56
this.storage.save(updated)
57
return updated
58
}
59
60
resetItem(id: number): Todo {
61
const todo = this.storage.get(id)
62
const updated = {
63
...todo,
64
done: false,
65
}
66
this.storage.save(updated)
67
return updated
68
}
69
}
70
71
class ListStorageStrategy implements StorageStrategy {
72
private todos: Todo[] = []
73
74
getAll(): Todo[] {
75
return this.todos
76
}
77
78
get(id: number): Todo {
79
const item = this.todos[id]
80
if (!item) {
81
throw new Error('Item not found')
82
}
83
84
return item
85
}
86
save(todo: Todo): void {
87
this.todos[todo.id] = todo
88
}
89
90
delete(id: number): void {
91
delete this.todos[id]
92
}
93
}
94
95
class MapStorageStrategy implements StorageStrategy {
96
private todos: Map<number, Todo> = new Map()
97
98
getAll(): Todo[] {
99
return Array.from(this.todos.entries()).map((el) => el[1])
100
}
101
102
get(id: number): Todo {
103
const item = this.todos.get(id)
104
if (!item) {
105
throw new Error('Item not found')
106
}
107
108
return item
109
}
110
111
save(todo: Todo): void {
112
this.todos.set(todo.id, todo)
113
}
114
115
delete(id: number): void {
116
this.todos.delete(id)
117
}
118
}
119
120
const alwaysIncompleteInitializer: InitializerStrategy = (todo) => ({
121
...todo,
122
done: false,
123
})
124
125
const randomIdInitializer: InitializerStrategy = (todo) => ({
126
...todo,
127
id: Math.random(),
128
})
129
130
const listTodos = new TodoDB(
131
new ListStorageStrategy(),
132
alwaysIncompleteInitializer
133
)
134
135
const mapTodos = new TodoDB(new MapStorageStrategy(), randomIdInitializer)
136
137
const item1: Todo = {
138
done: false,
139
id: 1,
140
name: 'thing',
141
}
142
143
const item2: Todo = {
144
done: true,
145
id: 2,
146
name: 'thing',
147
}
148
149
listTodos.addItem(item1)
150
mapTodos.addItem(item1)
151
152
listTodos.addItem(item2)
153
mapTodos.addItem(item2)
154
155
console.log(listTodos.getItems())
156
console.log(mapTodos.getItems())
157
158
console.log(listTodos)
159
console.log(mapTodos)
160
161
console.log(listTodos.getItem(1))
162
console.log(mapTodos.getItem(1))