@shaykec/bridge 0.4.24 → 0.4.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/journeys/ai-engineer.yaml +34 -0
- package/journeys/backend-developer.yaml +36 -0
- package/journeys/business-analyst.yaml +37 -0
- package/journeys/devops-engineer.yaml +37 -0
- package/journeys/engineering-manager.yaml +44 -0
- package/journeys/frontend-developer.yaml +41 -0
- package/journeys/fullstack-developer.yaml +49 -0
- package/journeys/mobile-developer.yaml +42 -0
- package/journeys/product-manager.yaml +35 -0
- package/journeys/qa-engineer.yaml +37 -0
- package/journeys/ux-designer.yaml +43 -0
- package/modules/README.md +52 -0
- package/modules/accessibility-fundamentals/content.md +126 -0
- package/modules/accessibility-fundamentals/exercises.md +88 -0
- package/modules/accessibility-fundamentals/module.yaml +43 -0
- package/modules/accessibility-fundamentals/quick-ref.md +71 -0
- package/modules/accessibility-fundamentals/quiz.md +100 -0
- package/modules/accessibility-fundamentals/resources.md +29 -0
- package/modules/accessibility-fundamentals/walkthrough.md +80 -0
- package/modules/adr-writing/content.md +121 -0
- package/modules/adr-writing/exercises.md +81 -0
- package/modules/adr-writing/module.yaml +41 -0
- package/modules/adr-writing/quick-ref.md +57 -0
- package/modules/adr-writing/quiz.md +73 -0
- package/modules/adr-writing/resources.md +29 -0
- package/modules/adr-writing/walkthrough.md +64 -0
- package/modules/ai-agents/content.md +120 -0
- package/modules/ai-agents/exercises.md +82 -0
- package/modules/ai-agents/module.yaml +42 -0
- package/modules/ai-agents/quick-ref.md +60 -0
- package/modules/ai-agents/quiz.md +103 -0
- package/modules/ai-agents/resources.md +30 -0
- package/modules/ai-agents/walkthrough.md +85 -0
- package/modules/ai-assisted-research/content.md +136 -0
- package/modules/ai-assisted-research/exercises.md +80 -0
- package/modules/ai-assisted-research/module.yaml +42 -0
- package/modules/ai-assisted-research/quick-ref.md +67 -0
- package/modules/ai-assisted-research/quiz.md +73 -0
- package/modules/ai-assisted-research/resources.md +33 -0
- package/modules/ai-assisted-research/walkthrough.md +85 -0
- package/modules/ai-pair-programming/content.md +105 -0
- package/modules/ai-pair-programming/exercises.md +98 -0
- package/modules/ai-pair-programming/module.yaml +39 -0
- package/modules/ai-pair-programming/quick-ref.md +58 -0
- package/modules/ai-pair-programming/quiz.md +73 -0
- package/modules/ai-pair-programming/resources.md +34 -0
- package/modules/ai-pair-programming/walkthrough.md +117 -0
- package/modules/ai-test-generation/content.md +125 -0
- package/modules/ai-test-generation/exercises.md +98 -0
- package/modules/ai-test-generation/module.yaml +39 -0
- package/modules/ai-test-generation/quick-ref.md +65 -0
- package/modules/ai-test-generation/quiz.md +74 -0
- package/modules/ai-test-generation/resources.md +41 -0
- package/modules/ai-test-generation/walkthrough.md +100 -0
- package/modules/api-design/content.md +189 -0
- package/modules/api-design/exercises.md +84 -0
- package/modules/api-design/game.yaml +113 -0
- package/modules/api-design/module.yaml +45 -0
- package/modules/api-design/quick-ref.md +73 -0
- package/modules/api-design/quiz.md +100 -0
- package/modules/api-design/resources.md +55 -0
- package/modules/api-design/walkthrough.md +88 -0
- package/modules/clean-code/content.md +136 -0
- package/modules/clean-code/exercises.md +137 -0
- package/modules/clean-code/game.yaml +172 -0
- package/modules/clean-code/module.yaml +44 -0
- package/modules/clean-code/quick-ref.md +44 -0
- package/modules/clean-code/quiz.md +105 -0
- package/modules/clean-code/resources.md +40 -0
- package/modules/clean-code/walkthrough.md +78 -0
- package/modules/clean-code/workshop.yaml +149 -0
- package/modules/code-review/content.md +130 -0
- package/modules/code-review/exercises.md +95 -0
- package/modules/code-review/game.yaml +83 -0
- package/modules/code-review/module.yaml +42 -0
- package/modules/code-review/quick-ref.md +77 -0
- package/modules/code-review/quiz.md +105 -0
- package/modules/code-review/resources.md +40 -0
- package/modules/code-review/walkthrough.md +106 -0
- package/modules/daily-workflow/content.md +81 -0
- package/modules/daily-workflow/exercises.md +50 -0
- package/modules/daily-workflow/module.yaml +33 -0
- package/modules/daily-workflow/quick-ref.md +37 -0
- package/modules/daily-workflow/quiz.md +65 -0
- package/modules/daily-workflow/resources.md +38 -0
- package/modules/daily-workflow/walkthrough.md +83 -0
- package/modules/debugging-systematically/content.md +139 -0
- package/modules/debugging-systematically/exercises.md +91 -0
- package/modules/debugging-systematically/module.yaml +46 -0
- package/modules/debugging-systematically/quick-ref.md +59 -0
- package/modules/debugging-systematically/quiz.md +105 -0
- package/modules/debugging-systematically/resources.md +42 -0
- package/modules/debugging-systematically/walkthrough.md +84 -0
- package/modules/debugging-systematically/workshop.yaml +127 -0
- package/modules/demo-test/content.md +68 -0
- package/modules/demo-test/exercises.md +28 -0
- package/modules/demo-test/game.yaml +171 -0
- package/modules/demo-test/module.yaml +41 -0
- package/modules/demo-test/quick-ref.md +54 -0
- package/modules/demo-test/quiz.md +74 -0
- package/modules/demo-test/resources.md +21 -0
- package/modules/demo-test/walkthrough.md +122 -0
- package/modules/demo-test/workshop.yaml +31 -0
- package/modules/design-critique/content.md +93 -0
- package/modules/design-critique/exercises.md +71 -0
- package/modules/design-critique/module.yaml +41 -0
- package/modules/design-critique/quick-ref.md +63 -0
- package/modules/design-critique/quiz.md +73 -0
- package/modules/design-critique/resources.md +27 -0
- package/modules/design-critique/walkthrough.md +68 -0
- package/modules/design-patterns/content.md +335 -0
- package/modules/design-patterns/exercises.md +82 -0
- package/modules/design-patterns/game.yaml +55 -0
- package/modules/design-patterns/module.yaml +45 -0
- package/modules/design-patterns/quick-ref.md +44 -0
- package/modules/design-patterns/quiz.md +101 -0
- package/modules/design-patterns/resources.md +40 -0
- package/modules/design-patterns/walkthrough.md +64 -0
- package/modules/exploratory-testing/content.md +133 -0
- package/modules/exploratory-testing/exercises.md +88 -0
- package/modules/exploratory-testing/module.yaml +41 -0
- package/modules/exploratory-testing/quick-ref.md +68 -0
- package/modules/exploratory-testing/quiz.md +75 -0
- package/modules/exploratory-testing/resources.md +39 -0
- package/modules/exploratory-testing/walkthrough.md +87 -0
- package/modules/git/content.md +128 -0
- package/modules/git/exercises.md +53 -0
- package/modules/git/game.yaml +190 -0
- package/modules/git/module.yaml +44 -0
- package/modules/git/quick-ref.md +67 -0
- package/modules/git/quiz.md +89 -0
- package/modules/git/resources.md +49 -0
- package/modules/git/walkthrough.md +92 -0
- package/modules/git/workshop.yaml +145 -0
- package/modules/hiring-interviews/content.md +130 -0
- package/modules/hiring-interviews/exercises.md +88 -0
- package/modules/hiring-interviews/module.yaml +41 -0
- package/modules/hiring-interviews/quick-ref.md +68 -0
- package/modules/hiring-interviews/quiz.md +73 -0
- package/modules/hiring-interviews/resources.md +36 -0
- package/modules/hiring-interviews/walkthrough.md +75 -0
- package/modules/hooks/content.md +97 -0
- package/modules/hooks/exercises.md +69 -0
- package/modules/hooks/module.yaml +39 -0
- package/modules/hooks/quick-ref.md +93 -0
- package/modules/hooks/quiz.md +81 -0
- package/modules/hooks/resources.md +34 -0
- package/modules/hooks/walkthrough.md +105 -0
- package/modules/hooks/workshop.yaml +64 -0
- package/modules/incident-response/content.md +124 -0
- package/modules/incident-response/exercises.md +82 -0
- package/modules/incident-response/game.yaml +132 -0
- package/modules/incident-response/module.yaml +45 -0
- package/modules/incident-response/quick-ref.md +53 -0
- package/modules/incident-response/quiz.md +103 -0
- package/modules/incident-response/resources.md +40 -0
- package/modules/incident-response/walkthrough.md +82 -0
- package/modules/llm-fundamentals/content.md +114 -0
- package/modules/llm-fundamentals/exercises.md +83 -0
- package/modules/llm-fundamentals/module.yaml +42 -0
- package/modules/llm-fundamentals/quick-ref.md +64 -0
- package/modules/llm-fundamentals/quiz.md +103 -0
- package/modules/llm-fundamentals/resources.md +30 -0
- package/modules/llm-fundamentals/walkthrough.md +91 -0
- package/modules/one-on-ones/content.md +133 -0
- package/modules/one-on-ones/exercises.md +81 -0
- package/modules/one-on-ones/module.yaml +44 -0
- package/modules/one-on-ones/quick-ref.md +67 -0
- package/modules/one-on-ones/quiz.md +73 -0
- package/modules/one-on-ones/resources.md +37 -0
- package/modules/one-on-ones/walkthrough.md +69 -0
- package/modules/package.json +9 -0
- package/modules/prioritization-frameworks/content.md +130 -0
- package/modules/prioritization-frameworks/exercises.md +93 -0
- package/modules/prioritization-frameworks/module.yaml +41 -0
- package/modules/prioritization-frameworks/quick-ref.md +77 -0
- package/modules/prioritization-frameworks/quiz.md +73 -0
- package/modules/prioritization-frameworks/resources.md +32 -0
- package/modules/prioritization-frameworks/walkthrough.md +69 -0
- package/modules/prompt-engineering/content.md +123 -0
- package/modules/prompt-engineering/exercises.md +82 -0
- package/modules/prompt-engineering/game.yaml +101 -0
- package/modules/prompt-engineering/module.yaml +45 -0
- package/modules/prompt-engineering/quick-ref.md +65 -0
- package/modules/prompt-engineering/quiz.md +105 -0
- package/modules/prompt-engineering/resources.md +36 -0
- package/modules/prompt-engineering/walkthrough.md +81 -0
- package/modules/rag-fundamentals/content.md +111 -0
- package/modules/rag-fundamentals/exercises.md +80 -0
- package/modules/rag-fundamentals/module.yaml +45 -0
- package/modules/rag-fundamentals/quick-ref.md +58 -0
- package/modules/rag-fundamentals/quiz.md +75 -0
- package/modules/rag-fundamentals/resources.md +34 -0
- package/modules/rag-fundamentals/walkthrough.md +75 -0
- package/modules/react-fundamentals/content.md +140 -0
- package/modules/react-fundamentals/exercises.md +81 -0
- package/modules/react-fundamentals/game.yaml +145 -0
- package/modules/react-fundamentals/module.yaml +45 -0
- package/modules/react-fundamentals/quick-ref.md +62 -0
- package/modules/react-fundamentals/quiz.md +106 -0
- package/modules/react-fundamentals/resources.md +42 -0
- package/modules/react-fundamentals/walkthrough.md +89 -0
- package/modules/react-fundamentals/workshop.yaml +112 -0
- package/modules/react-native-fundamentals/content.md +141 -0
- package/modules/react-native-fundamentals/exercises.md +79 -0
- package/modules/react-native-fundamentals/module.yaml +42 -0
- package/modules/react-native-fundamentals/quick-ref.md +60 -0
- package/modules/react-native-fundamentals/quiz.md +61 -0
- package/modules/react-native-fundamentals/resources.md +24 -0
- package/modules/react-native-fundamentals/walkthrough.md +84 -0
- package/modules/registry.yaml +1650 -0
- package/modules/risk-management/content.md +162 -0
- package/modules/risk-management/exercises.md +86 -0
- package/modules/risk-management/module.yaml +41 -0
- package/modules/risk-management/quick-ref.md +82 -0
- package/modules/risk-management/quiz.md +73 -0
- package/modules/risk-management/resources.md +40 -0
- package/modules/risk-management/walkthrough.md +67 -0
- package/modules/running-effective-standups/content.md +119 -0
- package/modules/running-effective-standups/exercises.md +79 -0
- package/modules/running-effective-standups/module.yaml +40 -0
- package/modules/running-effective-standups/quick-ref.md +61 -0
- package/modules/running-effective-standups/quiz.md +73 -0
- package/modules/running-effective-standups/resources.md +36 -0
- package/modules/running-effective-standups/walkthrough.md +76 -0
- package/modules/solid-principles/content.md +154 -0
- package/modules/solid-principles/exercises.md +107 -0
- package/modules/solid-principles/module.yaml +42 -0
- package/modules/solid-principles/quick-ref.md +50 -0
- package/modules/solid-principles/quiz.md +102 -0
- package/modules/solid-principles/resources.md +39 -0
- package/modules/solid-principles/walkthrough.md +84 -0
- package/modules/sprint-planning/content.md +142 -0
- package/modules/sprint-planning/exercises.md +79 -0
- package/modules/sprint-planning/game.yaml +84 -0
- package/modules/sprint-planning/module.yaml +44 -0
- package/modules/sprint-planning/quick-ref.md +76 -0
- package/modules/sprint-planning/quiz.md +102 -0
- package/modules/sprint-planning/resources.md +39 -0
- package/modules/sprint-planning/walkthrough.md +75 -0
- package/modules/sql-fundamentals/content.md +160 -0
- package/modules/sql-fundamentals/exercises.md +87 -0
- package/modules/sql-fundamentals/game.yaml +105 -0
- package/modules/sql-fundamentals/module.yaml +45 -0
- package/modules/sql-fundamentals/quick-ref.md +53 -0
- package/modules/sql-fundamentals/quiz.md +103 -0
- package/modules/sql-fundamentals/resources.md +42 -0
- package/modules/sql-fundamentals/walkthrough.md +92 -0
- package/modules/sql-fundamentals/workshop.yaml +109 -0
- package/modules/stakeholder-communication/content.md +186 -0
- package/modules/stakeholder-communication/exercises.md +87 -0
- package/modules/stakeholder-communication/module.yaml +38 -0
- package/modules/stakeholder-communication/quick-ref.md +89 -0
- package/modules/stakeholder-communication/quiz.md +73 -0
- package/modules/stakeholder-communication/resources.md +41 -0
- package/modules/stakeholder-communication/walkthrough.md +74 -0
- package/modules/system-design/content.md +149 -0
- package/modules/system-design/exercises.md +83 -0
- package/modules/system-design/game.yaml +95 -0
- package/modules/system-design/module.yaml +46 -0
- package/modules/system-design/quick-ref.md +59 -0
- package/modules/system-design/quiz.md +102 -0
- package/modules/system-design/resources.md +46 -0
- package/modules/system-design/walkthrough.md +90 -0
- package/modules/team-topologies/content.md +166 -0
- package/modules/team-topologies/exercises.md +85 -0
- package/modules/team-topologies/module.yaml +41 -0
- package/modules/team-topologies/quick-ref.md +61 -0
- package/modules/team-topologies/quiz.md +101 -0
- package/modules/team-topologies/resources.md +37 -0
- package/modules/team-topologies/walkthrough.md +76 -0
- package/modules/technical-debt/content.md +111 -0
- package/modules/technical-debt/exercises.md +92 -0
- package/modules/technical-debt/module.yaml +39 -0
- package/modules/technical-debt/quick-ref.md +60 -0
- package/modules/technical-debt/quiz.md +73 -0
- package/modules/technical-debt/resources.md +25 -0
- package/modules/technical-debt/walkthrough.md +94 -0
- package/modules/technical-mentoring/content.md +128 -0
- package/modules/technical-mentoring/exercises.md +84 -0
- package/modules/technical-mentoring/module.yaml +41 -0
- package/modules/technical-mentoring/quick-ref.md +74 -0
- package/modules/technical-mentoring/quiz.md +73 -0
- package/modules/technical-mentoring/resources.md +33 -0
- package/modules/technical-mentoring/walkthrough.md +65 -0
- package/modules/test-strategy/content.md +136 -0
- package/modules/test-strategy/exercises.md +84 -0
- package/modules/test-strategy/game.yaml +99 -0
- package/modules/test-strategy/module.yaml +45 -0
- package/modules/test-strategy/quick-ref.md +66 -0
- package/modules/test-strategy/quiz.md +99 -0
- package/modules/test-strategy/resources.md +60 -0
- package/modules/test-strategy/walkthrough.md +97 -0
- package/modules/test-strategy/workshop.yaml +96 -0
- package/modules/typescript-fundamentals/content.md +127 -0
- package/modules/typescript-fundamentals/exercises.md +79 -0
- package/modules/typescript-fundamentals/game.yaml +111 -0
- package/modules/typescript-fundamentals/module.yaml +45 -0
- package/modules/typescript-fundamentals/quick-ref.md +55 -0
- package/modules/typescript-fundamentals/quiz.md +104 -0
- package/modules/typescript-fundamentals/resources.md +42 -0
- package/modules/typescript-fundamentals/walkthrough.md +71 -0
- package/modules/typescript-fundamentals/workshop.yaml +146 -0
- package/modules/user-story-mapping/content.md +123 -0
- package/modules/user-story-mapping/exercises.md +87 -0
- package/modules/user-story-mapping/module.yaml +41 -0
- package/modules/user-story-mapping/quick-ref.md +64 -0
- package/modules/user-story-mapping/quiz.md +73 -0
- package/modules/user-story-mapping/resources.md +29 -0
- package/modules/user-story-mapping/walkthrough.md +86 -0
- package/modules/writing-prds/content.md +133 -0
- package/modules/writing-prds/exercises.md +93 -0
- package/modules/writing-prds/game.yaml +83 -0
- package/modules/writing-prds/module.yaml +44 -0
- package/modules/writing-prds/quick-ref.md +77 -0
- package/modules/writing-prds/quiz.md +103 -0
- package/modules/writing-prds/resources.md +30 -0
- package/modules/writing-prds/walkthrough.md +87 -0
- package/package.json +5 -3
- package/src/server.js +17 -7
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
# Design Patterns — Factory, Observer, Strategy, and Friends
|
|
2
|
+
|
|
3
|
+
<!-- hint:slides topic="Six essential design patterns: Singleton, Factory, Observer, Strategy, Decorator, Adapter — when and why to use each" slides="7" -->
|
|
4
|
+
|
|
5
|
+
Six essential design patterns with practical TypeScript examples and Mermaid class diagrams.
|
|
6
|
+
|
|
7
|
+
## 1. Singleton
|
|
8
|
+
|
|
9
|
+
**Problem:** Ensure a class has exactly one instance globally.
|
|
10
|
+
|
|
11
|
+
**Solution:** Private constructor, static `getInstance()` that returns the shared instance.
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
class Database {
|
|
15
|
+
private static instance: Database;
|
|
16
|
+
|
|
17
|
+
private constructor() {}
|
|
18
|
+
|
|
19
|
+
static getInstance(): Database {
|
|
20
|
+
if (!Database.instance) {
|
|
21
|
+
Database.instance = new Database();
|
|
22
|
+
}
|
|
23
|
+
return Database.instance;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
query(sql: string) { /* ... */ }
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
```mermaid
|
|
31
|
+
classDiagram
|
|
32
|
+
class Database {
|
|
33
|
+
-static instance: Database
|
|
34
|
+
-constructor()
|
|
35
|
+
+static getInstance() Database
|
|
36
|
+
+query(sql: string)
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
**Tradeoff:** Simplifies access but creates global state; can complicate testing.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## 2. Factory
|
|
45
|
+
|
|
46
|
+
**Problem:** Object creation depends on configuration or runtime type; callers shouldn't know creation details.
|
|
47
|
+
|
|
48
|
+
**Solution:** Centralize creation in a factory function or class.
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
type NotificationType = 'email' | 'sms' | 'push';
|
|
52
|
+
|
|
53
|
+
interface Notification {
|
|
54
|
+
send(message: string): void;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
class EmailNotification implements Notification {
|
|
58
|
+
send(message: string) { /* ... */ }
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
class SmsNotification implements Notification {
|
|
62
|
+
send(message: string) { /* ... */ }
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function createNotification(type: NotificationType): Notification {
|
|
66
|
+
switch (type) {
|
|
67
|
+
case 'email': return new EmailNotification();
|
|
68
|
+
case 'sms': return new SmsNotification();
|
|
69
|
+
default: throw new Error(`Unknown type: ${type}`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
```mermaid
|
|
75
|
+
classDiagram
|
|
76
|
+
class Notification {
|
|
77
|
+
<<interface>>
|
|
78
|
+
+send(message: string)
|
|
79
|
+
}
|
|
80
|
+
class EmailNotification {
|
|
81
|
+
+send(message: string)
|
|
82
|
+
}
|
|
83
|
+
class SmsNotification {
|
|
84
|
+
+send(message: string)
|
|
85
|
+
}
|
|
86
|
+
class createNotification {
|
|
87
|
+
+createNotification(type) Notification
|
|
88
|
+
}
|
|
89
|
+
Notification <|.. EmailNotification
|
|
90
|
+
Notification <|.. SmsNotification
|
|
91
|
+
createNotification ..> Notification : creates
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## 3. Observer
|
|
97
|
+
|
|
98
|
+
**Problem:** Multiple objects need to react when another object changes. Loose coupling is required.
|
|
99
|
+
|
|
100
|
+
**Solution:** Subject holds a list of subscribers; when state changes, it notifies all of them.
|
|
101
|
+
|
|
102
|
+
```typescript
|
|
103
|
+
type Listener<T> = (data: T) => void;
|
|
104
|
+
|
|
105
|
+
class Subject<T> {
|
|
106
|
+
private listeners: Set<Listener<T>> = new Set();
|
|
107
|
+
|
|
108
|
+
subscribe(fn: Listener<T>): () => void {
|
|
109
|
+
this.listeners.add(fn);
|
|
110
|
+
return () => this.listeners.delete(fn);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
notify(data: T): void {
|
|
114
|
+
this.listeners.forEach(fn => fn(data));
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Usage: form.notify({ email, submitted: true })
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
```mermaid
|
|
122
|
+
classDiagram
|
|
123
|
+
class Subject {
|
|
124
|
+
-listeners: Set
|
|
125
|
+
+subscribe(fn)
|
|
126
|
+
+notify(data)
|
|
127
|
+
}
|
|
128
|
+
class Observer {
|
|
129
|
+
<<interface>>
|
|
130
|
+
+update(data)
|
|
131
|
+
}
|
|
132
|
+
Subject --> Observer : notifies
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## 4. Strategy
|
|
138
|
+
|
|
139
|
+
**Problem:** Multiple algorithms for the same task; want to switch at runtime without changing the client.
|
|
140
|
+
|
|
141
|
+
**Solution:** Extract each algorithm into a strategy object; client holds a strategy and delegates.
|
|
142
|
+
|
|
143
|
+
```mermaid
|
|
144
|
+
classDiagram
|
|
145
|
+
class Context {
|
|
146
|
+
-strategy: Strategy
|
|
147
|
+
+setStrategy(s: Strategy)
|
|
148
|
+
+execute()
|
|
149
|
+
}
|
|
150
|
+
class Strategy {
|
|
151
|
+
<<interface>>
|
|
152
|
+
+execute()
|
|
153
|
+
}
|
|
154
|
+
class ConcreteStrategyA {
|
|
155
|
+
+execute()
|
|
156
|
+
}
|
|
157
|
+
class ConcreteStrategyB {
|
|
158
|
+
+execute()
|
|
159
|
+
}
|
|
160
|
+
Context --> Strategy : uses
|
|
161
|
+
Strategy <|.. ConcreteStrategyA
|
|
162
|
+
Strategy <|.. ConcreteStrategyB
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
interface PaymentStrategy {
|
|
167
|
+
pay(amount: number): boolean;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
class CreditCardStrategy implements PaymentStrategy {
|
|
171
|
+
pay(amount: number) { /* ... */ return true; }
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
class PayPalStrategy implements PaymentStrategy {
|
|
175
|
+
pay(amount: number) { /* ... */ return true; }
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
class PaymentProcessor {
|
|
179
|
+
constructor(private strategy: PaymentStrategy) {}
|
|
180
|
+
|
|
181
|
+
setStrategy(s: PaymentStrategy) { this.strategy = s; }
|
|
182
|
+
|
|
183
|
+
execute(amount: number) {
|
|
184
|
+
return this.strategy.pay(amount);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
```mermaid
|
|
190
|
+
classDiagram
|
|
191
|
+
class PaymentStrategy {
|
|
192
|
+
<<interface>>
|
|
193
|
+
+pay(amount: number)
|
|
194
|
+
}
|
|
195
|
+
class CreditCardStrategy {
|
|
196
|
+
+pay(amount: number)
|
|
197
|
+
}
|
|
198
|
+
class PayPalStrategy {
|
|
199
|
+
+pay(amount: number)
|
|
200
|
+
}
|
|
201
|
+
class PaymentProcessor {
|
|
202
|
+
-strategy: PaymentStrategy
|
|
203
|
+
+setStrategy(s)
|
|
204
|
+
+execute(amount)
|
|
205
|
+
}
|
|
206
|
+
PaymentStrategy <|.. CreditCardStrategy
|
|
207
|
+
PaymentStrategy <|.. PayPalStrategy
|
|
208
|
+
PaymentProcessor --> PaymentStrategy : delegates
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## 5. Decorator
|
|
214
|
+
|
|
215
|
+
**Problem:** Add behavior to an object without subclassing; behavior should be stackable.
|
|
216
|
+
|
|
217
|
+
**Solution:** Wrap the object in a decorator that adds behavior and delegates to the wrapped object.
|
|
218
|
+
|
|
219
|
+
```typescript
|
|
220
|
+
interface Logger {
|
|
221
|
+
log(msg: string): void;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
class ConsoleLogger implements Logger {
|
|
225
|
+
log(msg: string) { console.log(msg); }
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
class TimestampDecorator implements Logger {
|
|
229
|
+
constructor(private inner: Logger) {}
|
|
230
|
+
|
|
231
|
+
log(msg: string) {
|
|
232
|
+
this.inner.log(`[${new Date().toISOString()}] ${msg}`);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
class LevelDecorator implements Logger {
|
|
237
|
+
constructor(private inner: Logger, private level: string) {}
|
|
238
|
+
|
|
239
|
+
log(msg: string) {
|
|
240
|
+
this.inner.log(`[${this.level}] ${msg}`);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// Usage: new TimestampDecorator(new LevelDecorator(new ConsoleLogger(), 'INFO'))
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
```mermaid
|
|
248
|
+
classDiagram
|
|
249
|
+
class Logger {
|
|
250
|
+
<<interface>>
|
|
251
|
+
+log(msg: string)
|
|
252
|
+
}
|
|
253
|
+
class ConsoleLogger {
|
|
254
|
+
+log(msg: string)
|
|
255
|
+
}
|
|
256
|
+
class TimestampDecorator {
|
|
257
|
+
-inner: Logger
|
|
258
|
+
+log(msg: string)
|
|
259
|
+
}
|
|
260
|
+
class LevelDecorator {
|
|
261
|
+
-inner: Logger
|
|
262
|
+
-level: string
|
|
263
|
+
+log(msg: string)
|
|
264
|
+
}
|
|
265
|
+
Logger <|.. ConsoleLogger
|
|
266
|
+
Logger <|.. TimestampDecorator
|
|
267
|
+
Logger <|.. LevelDecorator
|
|
268
|
+
TimestampDecorator --> Logger : wraps
|
|
269
|
+
LevelDecorator --> Logger : wraps
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
---
|
|
273
|
+
|
|
274
|
+
## 6. Adapter
|
|
275
|
+
|
|
276
|
+
**Problem:** An existing class has the wrong interface for your needs (e.g., callback-based API, third-party library).
|
|
277
|
+
|
|
278
|
+
**Solution:** Create an adapter that implements your target interface and delegates to the adaptee.
|
|
279
|
+
|
|
280
|
+
```typescript
|
|
281
|
+
function fetchDataLegacy(callback: (err: Error | null, data?: string) => void): void {
|
|
282
|
+
setTimeout(() => callback(null, 'result'), 100);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
function adaptToPromise<T>(
|
|
286
|
+
fn: (cb: (err: Error | null, data?: T) => void) => void
|
|
287
|
+
): Promise<T> {
|
|
288
|
+
return new Promise((resolve, reject) => {
|
|
289
|
+
fn((err, data) => err ? reject(err) : resolve(data as T));
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// Usage: const data = await adaptToPromise(fetchDataLegacy);
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
```mermaid
|
|
297
|
+
classDiagram
|
|
298
|
+
class Target {
|
|
299
|
+
<<interface>>
|
|
300
|
+
+getData() Promise
|
|
301
|
+
}
|
|
302
|
+
class Adapter {
|
|
303
|
+
-adaptee: Adaptee
|
|
304
|
+
+getData() Promise
|
|
305
|
+
}
|
|
306
|
+
class Adaptee {
|
|
307
|
+
+fetch(callback)
|
|
308
|
+
}
|
|
309
|
+
Target <|.. Adapter
|
|
310
|
+
Adapter --> Adaptee : delegates
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
---
|
|
314
|
+
|
|
315
|
+
## Decision Flow
|
|
316
|
+
|
|
317
|
+
| Need | Pattern |
|
|
318
|
+
|------|---------|
|
|
319
|
+
| Same instance everywhere | Singleton |
|
|
320
|
+
| Create objects by type/config | Factory |
|
|
321
|
+
| Notify listeners on change | Observer |
|
|
322
|
+
| Swap algorithm at runtime | Strategy |
|
|
323
|
+
| Add behavior without subclassing | Decorator |
|
|
324
|
+
| Use legacy or wrong API | Adapter |
|
|
325
|
+
|
|
326
|
+
---
|
|
327
|
+
|
|
328
|
+
## Key Takeaways
|
|
329
|
+
|
|
330
|
+
1. **Singleton** — One instance; watch out for global state and testing.
|
|
331
|
+
2. **Factory** — Centralize creation; open for new types, closed for modification.
|
|
332
|
+
3. **Observer** — Loose coupling; subject notifies subscribers.
|
|
333
|
+
4. **Strategy** — Pluggable algorithms; client delegates to strategy.
|
|
334
|
+
5. **Decorator** — Wrap and delegate; stack decorators for layered behavior.
|
|
335
|
+
6. **Adapter** — Translate interfaces; no behavior change, just interface.
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Design Patterns Exercises
|
|
2
|
+
|
|
3
|
+
## Exercise 1: Strategy — Sorting
|
|
4
|
+
|
|
5
|
+
**Task:** Implement a `Sorter` that uses a pluggable sort strategy. Provide `BubbleSort` and `QuickSort` strategies. The Sorter should have `sort(arr)` and `setStrategy(s)`.
|
|
6
|
+
|
|
7
|
+
**Validation:**
|
|
8
|
+
- [ ] Sorter delegates to strategy
|
|
9
|
+
- [ ] Can switch strategies at runtime
|
|
10
|
+
- [ ] Both strategies produce correct output
|
|
11
|
+
|
|
12
|
+
**Hints:**
|
|
13
|
+
1. interface SortStrategy { sort(arr: number[]): number[] }
|
|
14
|
+
2. Sorter holds strategy, calls strategy.sort(arr)
|
|
15
|
+
3. setStrategy replaces the current strategy
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Exercise 2: Factory — Shape Creation
|
|
20
|
+
|
|
21
|
+
**Task:** Create a `ShapeFactory.create(type: 'circle' | 'square' | 'triangle')` that returns the appropriate shape object. Each shape has `area()` and `perimeter()`.
|
|
22
|
+
|
|
23
|
+
**Validation:**
|
|
24
|
+
- [ ] Factory returns correct type for each input
|
|
25
|
+
- [ ] Invalid type throws or returns null
|
|
26
|
+
- [ ] Adding a new shape requires only a new case, not changes to callers
|
|
27
|
+
|
|
28
|
+
**Hints:**
|
|
29
|
+
1. interface Shape { area(): number; perimeter(): number }
|
|
30
|
+
2. switch (type) { case 'circle': return new Circle(...) }
|
|
31
|
+
3. Consider default for unknown type
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Exercise 3: Observer — Event Bus
|
|
36
|
+
|
|
37
|
+
**Task:** Build an `EventBus` with `on(event, handler)`, `off(event, handler)`, and `emit(event, data)`. Support multiple handlers per event. Test with at least 2 events and 2 handlers on one event.
|
|
38
|
+
|
|
39
|
+
**Validation:**
|
|
40
|
+
- [ ] Handlers are called on emit
|
|
41
|
+
- [ ] off removes the correct handler
|
|
42
|
+
- [ ] Multiple handlers work
|
|
43
|
+
- [ ] Same handler can be on multiple events
|
|
44
|
+
|
|
45
|
+
**Hints:**
|
|
46
|
+
1. Map<event, Set<handler>>
|
|
47
|
+
2. emit: get handlers, call each with data
|
|
48
|
+
3. off: remove from Set
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Exercise 4: Decorator — Caching
|
|
53
|
+
|
|
54
|
+
**Task:** Create a `CachedFunction` decorator that wraps any async function `(x) => Promise<y>` and caches results by input. Same input returns cached value without calling the inner function.
|
|
55
|
+
|
|
56
|
+
**Validation:**
|
|
57
|
+
- [ ] First call invokes inner function
|
|
58
|
+
- [ ] Second call with same input returns cache
|
|
59
|
+
- [ ] Different inputs call inner function
|
|
60
|
+
- [ ] Decorator is reusable for any async function
|
|
61
|
+
|
|
62
|
+
**Hints:**
|
|
63
|
+
1. type Fn = (x: T) => Promise<U>
|
|
64
|
+
2. const cache = new Map<T, U>()
|
|
65
|
+
3. if (cache.has(x)) return cache.get(x)!; const r = await fn(x); cache.set(x, r); return r
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Exercise 5: Adapter — Old API to New
|
|
70
|
+
|
|
71
|
+
**Task:** You have `LegacyStorage.getItem(key, callback)` and `LegacyStorage.setItem(key, value, callback)`. Create an adapter with `async get(key): Promise<string | null>` and `async set(key, value): Promise<void>`.
|
|
72
|
+
|
|
73
|
+
**Validation:**
|
|
74
|
+
- [ ] Adapter wraps LegacyStorage
|
|
75
|
+
- [ ] get/set return Promises
|
|
76
|
+
- [ ] Callbacks are correctly translated to Promise resolve
|
|
77
|
+
- [ ] Errors in callback reject the Promise
|
|
78
|
+
|
|
79
|
+
**Hints:**
|
|
80
|
+
1. new Promise((resolve, reject) => legacy.getItem(key, (err, val) => err ? reject(err) : resolve(val)))
|
|
81
|
+
2. Same pattern for setItem
|
|
82
|
+
3. Wrap both in a class or object
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
games:
|
|
2
|
+
- type: memory-match
|
|
3
|
+
title: "Pattern Pairs"
|
|
4
|
+
pairs:
|
|
5
|
+
- term: "Factory"
|
|
6
|
+
definition: "Creates objects without specifying exact class"
|
|
7
|
+
- term: "Observer"
|
|
8
|
+
definition: "Notifies dependents of state changes"
|
|
9
|
+
- term: "Strategy"
|
|
10
|
+
definition: "Swaps algorithms at runtime"
|
|
11
|
+
- term: "Singleton"
|
|
12
|
+
definition: "Single instance globally"
|
|
13
|
+
- term: "Adapter"
|
|
14
|
+
definition: "Wraps incompatible interface"
|
|
15
|
+
- term: "Decorator"
|
|
16
|
+
definition: "Adds behavior without subclassing"
|
|
17
|
+
- term: "Loose Coupling"
|
|
18
|
+
definition: "Minimal dependencies between components"
|
|
19
|
+
- term: "Gang of Four"
|
|
20
|
+
definition: "Original design pattern catalog authors"
|
|
21
|
+
|
|
22
|
+
- type: classify
|
|
23
|
+
title: "Pattern Sorter"
|
|
24
|
+
categories:
|
|
25
|
+
- name: Creational
|
|
26
|
+
color: "#58a6ff"
|
|
27
|
+
- name: Structural
|
|
28
|
+
color: "#3fb950"
|
|
29
|
+
- name: Behavioral
|
|
30
|
+
color: "#d29922"
|
|
31
|
+
items:
|
|
32
|
+
- text: "Factory"
|
|
33
|
+
category: "Creational"
|
|
34
|
+
- text: "Singleton"
|
|
35
|
+
category: "Creational"
|
|
36
|
+
- text: "Builder"
|
|
37
|
+
category: "Creational"
|
|
38
|
+
- text: "Adapter"
|
|
39
|
+
category: "Structural"
|
|
40
|
+
- text: "Decorator"
|
|
41
|
+
category: "Structural"
|
|
42
|
+
- text: "Proxy"
|
|
43
|
+
category: "Structural"
|
|
44
|
+
- text: "Observer"
|
|
45
|
+
category: "Behavioral"
|
|
46
|
+
- text: "Strategy"
|
|
47
|
+
category: "Behavioral"
|
|
48
|
+
- text: "Command"
|
|
49
|
+
category: "Behavioral"
|
|
50
|
+
- text: "Iterator"
|
|
51
|
+
category: "Behavioral"
|
|
52
|
+
- text: "Template Method"
|
|
53
|
+
category: "Behavioral"
|
|
54
|
+
- text: "Composite"
|
|
55
|
+
category: "Structural"
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
slug: design-patterns
|
|
2
|
+
title: "Design Patterns — Factory, Observer, Strategy, and Friends"
|
|
3
|
+
version: 1.0.0
|
|
4
|
+
description: "Learn six essential design patterns with practical TypeScript examples."
|
|
5
|
+
category: fundamentals
|
|
6
|
+
tags: [design-patterns, oop, architecture, gang-of-four, software-design]
|
|
7
|
+
difficulty: intermediate
|
|
8
|
+
|
|
9
|
+
xp:
|
|
10
|
+
read: 15
|
|
11
|
+
walkthrough: 40
|
|
12
|
+
exercise: 25
|
|
13
|
+
quiz: 20
|
|
14
|
+
quiz-perfect-bonus: 10
|
|
15
|
+
game: 25
|
|
16
|
+
game-perfect-bonus: 10
|
|
17
|
+
|
|
18
|
+
time:
|
|
19
|
+
quick: 5
|
|
20
|
+
read: 25
|
|
21
|
+
guided: 60
|
|
22
|
+
|
|
23
|
+
prerequisites: [solid-principles]
|
|
24
|
+
related: [clean-code, system-design]
|
|
25
|
+
|
|
26
|
+
triggers:
|
|
27
|
+
- "What are design patterns?"
|
|
28
|
+
- "When should I use the Factory pattern?"
|
|
29
|
+
- "What is the Observer pattern?"
|
|
30
|
+
- "How do I choose the right design pattern?"
|
|
31
|
+
|
|
32
|
+
visuals:
|
|
33
|
+
diagrams: [diagram-mermaid, diagram-architecture]
|
|
34
|
+
quiz-types: [quiz-matching, quiz-timed-choice]
|
|
35
|
+
game-types: [memory-match, classify]
|
|
36
|
+
playground: javascript
|
|
37
|
+
slides: true
|
|
38
|
+
|
|
39
|
+
sources:
|
|
40
|
+
- url: "https://refactoring.guru/design-patterns"
|
|
41
|
+
label: "Refactoring Guru"
|
|
42
|
+
type: docs
|
|
43
|
+
- url: "https://www.oreilly.com/library/view/head-first-design/0596007124/"
|
|
44
|
+
label: "Head First Design Patterns"
|
|
45
|
+
type: docs
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Design Patterns Quick Reference
|
|
2
|
+
|
|
3
|
+
## Pattern Overview
|
|
4
|
+
|
|
5
|
+
| Pattern | Problem | Solution |
|
|
6
|
+
|---------|---------|----------|
|
|
7
|
+
| Singleton | One instance | Static getInstance, private constructor |
|
|
8
|
+
| Factory | Creation by type/config | Centralized creation function |
|
|
9
|
+
| Observer | One-to-many updates | Subscribe/notify |
|
|
10
|
+
| Strategy | Pluggable algorithm | Delegate to strategy object |
|
|
11
|
+
| Decorator | Stackable behavior | Wrap and delegate |
|
|
12
|
+
| Adapter | Interface mismatch | Translate interface |
|
|
13
|
+
|
|
14
|
+
## When to Use
|
|
15
|
+
|
|
16
|
+
| Need | Pattern |
|
|
17
|
+
|------|---------|
|
|
18
|
+
| Same instance everywhere | Singleton |
|
|
19
|
+
| Create X based on input | Factory |
|
|
20
|
+
| Notify listeners on change | Observer |
|
|
21
|
+
| Swap algorithm at runtime | Strategy |
|
|
22
|
+
| Add behavior without subclassing | Decorator |
|
|
23
|
+
| Use legacy/wrong API | Adapter |
|
|
24
|
+
|
|
25
|
+
## Key Code Shapes
|
|
26
|
+
|
|
27
|
+
**Strategy:** Client holds strategy, calls strategy.do()
|
|
28
|
+
|
|
29
|
+
**Observer:** Subject has subscribe/emit; observers register callbacks
|
|
30
|
+
|
|
31
|
+
**Decorator:** Wraps inner, adds behavior, delegates
|
|
32
|
+
|
|
33
|
+
**Adapter:** Implements target interface, delegates to adaptee
|
|
34
|
+
|
|
35
|
+
## Decision Flow
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
Creation logic? → Factory
|
|
39
|
+
One instance? → Singleton
|
|
40
|
+
Notify many? → Observer
|
|
41
|
+
Switch algorithm? → Strategy
|
|
42
|
+
Add behavior? → Decorator
|
|
43
|
+
Wrong interface? → Adapter
|
|
44
|
+
```
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# Design Patterns Quiz
|
|
2
|
+
|
|
3
|
+
## Question 1
|
|
4
|
+
|
|
5
|
+
When would you use the Factory pattern?
|
|
6
|
+
|
|
7
|
+
A) When you need exactly one instance
|
|
8
|
+
B) When object creation depends on configuration or runtime type
|
|
9
|
+
C) When you need to observe changes
|
|
10
|
+
D) When you want to add behavior to an object
|
|
11
|
+
|
|
12
|
+
<!-- ANSWER: B -->
|
|
13
|
+
<!-- EXPLANATION: Factory centralizes creation logic. Use it when you need to create different concrete types based on config, type string, or other runtime input, without exposing the creation details to callers. -->
|
|
14
|
+
|
|
15
|
+
## Question 2
|
|
16
|
+
|
|
17
|
+
What is the main benefit of the Observer pattern?
|
|
18
|
+
|
|
19
|
+
A) Better performance
|
|
20
|
+
B) Loose coupling between publisher and subscribers
|
|
21
|
+
C) Single instance guarantee
|
|
22
|
+
D) Easier debugging
|
|
23
|
+
|
|
24
|
+
<!-- ANSWER: B -->
|
|
25
|
+
<!-- EXPLANATION: Observer decouples the subject (publisher) from its observers (subscribers). The subject doesn't need to know who is listening. Subscribers can be added/removed at runtime. -->
|
|
26
|
+
|
|
27
|
+
## Question 3
|
|
28
|
+
|
|
29
|
+
The Strategy pattern is useful when:
|
|
30
|
+
|
|
31
|
+
A) You need multiple instances of the same class
|
|
32
|
+
B) You want to switch algorithms at runtime without changing the client
|
|
33
|
+
C) You need to wrap an object with extra behavior
|
|
34
|
+
D) You have an interface mismatch
|
|
35
|
+
|
|
36
|
+
<!-- ANSWER: B -->
|
|
37
|
+
<!-- EXPLANATION: Strategy extracts algorithms into interchangeable objects. The client holds a strategy and delegates to it. You can swap strategies at runtime (e.g., different sort algorithms, payment methods). -->
|
|
38
|
+
|
|
39
|
+
## Question 4
|
|
40
|
+
|
|
41
|
+
How does the Decorator pattern add behavior?
|
|
42
|
+
|
|
43
|
+
A) By subclassing
|
|
44
|
+
B) By wrapping an object and delegating to it
|
|
45
|
+
C) By replacing the object
|
|
46
|
+
D) By using global state
|
|
47
|
+
|
|
48
|
+
<!-- ANSWER: B -->
|
|
49
|
+
<!-- EXPLANATION: Decorator wraps the original object, adds its own behavior, and delegates to the wrapped object. Multiple decorators can stack (DecoratorA(DecoratorB(Core))). -->
|
|
50
|
+
|
|
51
|
+
## Question 5
|
|
52
|
+
|
|
53
|
+
When do you use the Adapter pattern?
|
|
54
|
+
|
|
55
|
+
A) When you want to optimize performance
|
|
56
|
+
B) When an existing class has the wrong interface for your needs
|
|
57
|
+
C) When you need a single instance
|
|
58
|
+
D) When you want to observe changes
|
|
59
|
+
|
|
60
|
+
<!-- ANSWER: B -->
|
|
61
|
+
<!-- EXPLANATION: Adapter translates between your expected interface and the existing class's interface. Use it when integrating legacy code, third-party libraries, or mismatched APIs. -->
|
|
62
|
+
|
|
63
|
+
## Question 6
|
|
64
|
+
|
|
65
|
+
What is a downside of the Singleton pattern?
|
|
66
|
+
|
|
67
|
+
A) It's hard to implement
|
|
68
|
+
B) It can make testing difficult due to global state
|
|
69
|
+
C) It only works in single-threaded environments
|
|
70
|
+
D) It violates encapsulation
|
|
71
|
+
|
|
72
|
+
<!-- ANSWER: B -->
|
|
73
|
+
<!-- EXPLANATION: Singleton creates global state. In tests, you often want fresh or mock instances. With Singleton, you may need reset logic or dependency injection of the instance to test effectively. -->
|
|
74
|
+
|
|
75
|
+
## Question 7
|
|
76
|
+
|
|
77
|
+
<!-- VISUAL: matching -->
|
|
78
|
+
|
|
79
|
+
Match each design pattern to its typical use case:
|
|
80
|
+
|
|
81
|
+
A) Factory → 1) Integrating a third-party API with a different interface
|
|
82
|
+
B) Observer → 2) Creating different UI components based on OS (Windows/Mac)
|
|
83
|
+
C) Adapter → 3) Event system where subscribers react to publisher changes
|
|
84
|
+
D) Strategy → 4) Swapping sort algorithms (quick vs merge) at runtime
|
|
85
|
+
|
|
86
|
+
<!-- ANSWER: A2,B3,C1,D4 -->
|
|
87
|
+
<!-- EXPLANATION: Factory creates objects based on config/type (2). Observer decouples publisher from subscribers (3). Adapter translates interfaces (1). Strategy swaps algorithms (4). -->
|
|
88
|
+
|
|
89
|
+
## Question 8
|
|
90
|
+
|
|
91
|
+
<!-- VISUAL: matching -->
|
|
92
|
+
|
|
93
|
+
Match each pattern to its structural characteristic:
|
|
94
|
+
|
|
95
|
+
A) Decorator → 1) Wraps object, delegates to inner object, adds behavior
|
|
96
|
+
B) Singleton → 2) Single instance, global access
|
|
97
|
+
C) Strategy → 3) Context holds algorithm object, delegates to it
|
|
98
|
+
D) Observer → 4) Subject maintains list of observers, notifies on change
|
|
99
|
+
|
|
100
|
+
<!-- ANSWER: A1,B2,C3,D4 -->
|
|
101
|
+
<!-- EXPLANATION: Decorator wraps and delegates (1). Singleton is single-instance (2). Strategy holds and delegates to strategy object (3). Observer has subject-observer list (4). -->
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Design Patterns — Resources
|
|
2
|
+
|
|
3
|
+
## Videos
|
|
4
|
+
|
|
5
|
+
- [Design Patterns in 5 Minutes](https://www.youtube.com/watch?v=tv-_1er1mWI) — Fireship. Quick overview.
|
|
6
|
+
- [Design Patterns Course](https://www.youtube.com/watch?v=NU_1StN5Tkk) — freeCodeCamp. Full course.
|
|
7
|
+
- [Christopher Okhravi — Design Patterns](https://www.youtube.com/playlist?list=PLrhzvIcii6GNjpARdnO4ueTUAVR9eMBpc) — Detailed pattern explanations.
|
|
8
|
+
|
|
9
|
+
## Articles and Readings
|
|
10
|
+
|
|
11
|
+
- [Refactoring Guru — Design Patterns](https://refactoring.guru/design-patterns) — Catalog with examples and diagrams.
|
|
12
|
+
- [Patterns.dev](https://www.patterns.dev/) — Modern JS/React patterns.
|
|
13
|
+
- [SourceMaking](https://sourcemaking.com/design_patterns) — Patterns with UML and code.
|
|
14
|
+
|
|
15
|
+
## Books
|
|
16
|
+
|
|
17
|
+
- **Head First Design Patterns** by Freeman & Freeman — Accessible intro with visuals.
|
|
18
|
+
- **Design Patterns: Elements of Reusable OOP** by Gang of Four — Original reference.
|
|
19
|
+
- **Refactoring to Patterns** by Joshua Kerievsky — When and how to introduce patterns.
|
|
20
|
+
|
|
21
|
+
## Tools
|
|
22
|
+
|
|
23
|
+
- [TypeScript Design Patterns](https://github.com/torokmark/design_patterns_in_typescript) — TS implementations.
|
|
24
|
+
- [Mermaid Diagrams](https://mermaid.js.org/) — Class and sequence diagrams for patterns.
|
|
25
|
+
|
|
26
|
+
## Podcasts
|
|
27
|
+
|
|
28
|
+
- [Software Engineering Radio — Design Patterns](https://www.se-radio.net/) — Technical episodes on applying patterns in real projects.
|
|
29
|
+
- [Coding Blocks — Design Patterns Series](https://www.codingblocks.net/) — Multi-episode deep dives into Gang of Four patterns.
|
|
30
|
+
|
|
31
|
+
## Interactive and Visual
|
|
32
|
+
|
|
33
|
+
- [Refactoring Guru — Design Patterns](https://refactoring.guru/design-patterns) — Interactive catalog with visual diagrams, code examples in 10 languages, and real-world analogies.
|
|
34
|
+
- [Patterns.dev](https://www.patterns.dev/) — Addy Osmani & Lydia Hallie. Visual, modern JS/React patterns with animated examples.
|
|
35
|
+
- [Design Patterns Card](https://www.mcdonaldland.info/2007/11/28/40/) — Printable reference card for quick pattern lookup.
|
|
36
|
+
|
|
37
|
+
## Courses
|
|
38
|
+
|
|
39
|
+
- [freeCodeCamp — Design Patterns for Humans](https://github.com/kamranahmedse/design-patterns-for-humans) — Plain-English explanation of every GoF pattern with real-world analogies.
|
|
40
|
+
- [Coursera — Design Patterns (University of Alberta)](https://www.coursera.org/learn/design-patterns) — Free to audit course covering creational, structural, and behavioral patterns.
|