Updated: 03 September 2023
1interface Todo {2 id: number3 name: string4 done: boolean5}6
7const todo: Todo = {8 done: false,9 id: 0,10 name: 'task',11}12
13interface StorageStrategy {14 get(id: number): Todo15 getAll(): Todo[]16 delete(id: number): void17 save(todo: Todo): void18}19
20type InitializerStrategy = (todo: Todo) => Todo21
22class TodoDB {23 constructor(24 private readonly storage: StorageStrategy,25 private readonly intializer: InitializerStrategy26 ) {}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 todo48 }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 updated58 }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 updated68 }69}70
71class ListStorageStrategy implements StorageStrategy {72 private todos: Todo[] = []73
74 getAll(): Todo[] {75 return this.todos76 }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 item85 }86 save(todo: Todo): void {87 this.todos[todo.id] = todo88 }89
90 delete(id: number): void {91 delete this.todos[id]92 }93}94
95class 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 item109 }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
120const alwaysIncompleteInitializer: InitializerStrategy = (todo) => ({121 ...todo,122 done: false,123})124
125const randomIdInitializer: InitializerStrategy = (todo) => ({126 ...todo,127 id: Math.random(),128})129
130const listTodos = new TodoDB(131 new ListStorageStrategy(),132 alwaysIncompleteInitializer133)134
135const mapTodos = new TodoDB(new MapStorageStrategy(), randomIdInitializer)136
137const item1: Todo = {138 done: false,139 id: 1,140 name: 'thing',141}142
143const item2: Todo = {144 done: true,145 id: 2,146 name: 'thing',147}148
149listTodos.addItem(item1)150mapTodos.addItem(item1)151
152listTodos.addItem(item2)153mapTodos.addItem(item2)154
155console.log(listTodos.getItems())156console.log(mapTodos.getItems())157
158console.log(listTodos)159console.log(mapTodos)160
161console.log(listTodos.getItem(1))162console.log(mapTodos.getItem(1))