devflow-kit 1.0.0 → 1.2.0

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.
Files changed (134) hide show
  1. package/CHANGELOG.md +69 -0
  2. package/README.md +35 -11
  3. package/dist/cli.js +5 -1
  4. package/dist/commands/ambient.d.ts +18 -0
  5. package/dist/commands/ambient.js +136 -0
  6. package/dist/commands/init.d.ts +2 -0
  7. package/dist/commands/init.js +97 -10
  8. package/dist/commands/memory.d.ts +22 -0
  9. package/dist/commands/memory.js +175 -0
  10. package/dist/commands/uninstall.js +72 -5
  11. package/dist/plugins.js +74 -3
  12. package/dist/utils/post-install.d.ts +12 -0
  13. package/dist/utils/post-install.js +82 -1
  14. package/dist/utils/safe-delete-install.d.ts +7 -0
  15. package/dist/utils/safe-delete-install.js +40 -5
  16. package/package.json +2 -1
  17. package/plugins/devflow-accessibility/.claude-plugin/plugin.json +15 -0
  18. package/plugins/devflow-ambient/.claude-plugin/plugin.json +7 -0
  19. package/plugins/devflow-ambient/README.md +49 -0
  20. package/plugins/devflow-ambient/commands/ambient.md +110 -0
  21. package/plugins/devflow-ambient/skills/ambient-router/SKILL.md +89 -0
  22. package/plugins/devflow-ambient/skills/ambient-router/references/skill-catalog.md +68 -0
  23. package/plugins/devflow-audit-claude/.claude-plugin/plugin.json +1 -1
  24. package/plugins/devflow-code-review/.claude-plugin/plugin.json +1 -4
  25. package/plugins/devflow-code-review/agents/reviewer.md +8 -0
  26. package/plugins/devflow-code-review/commands/code-review-teams.md +11 -1
  27. package/plugins/devflow-code-review/commands/code-review.md +12 -2
  28. package/plugins/devflow-core-skills/.claude-plugin/plugin.json +3 -6
  29. package/plugins/devflow-core-skills/skills/docs-framework/SKILL.md +10 -6
  30. package/plugins/devflow-core-skills/skills/test-driven-development/SKILL.md +139 -0
  31. package/plugins/devflow-core-skills/skills/test-driven-development/references/rationalization-prevention.md +111 -0
  32. package/plugins/devflow-debug/.claude-plugin/plugin.json +1 -1
  33. package/plugins/devflow-frontend-design/.claude-plugin/plugin.json +15 -0
  34. package/plugins/devflow-go/.claude-plugin/plugin.json +15 -0
  35. package/plugins/devflow-go/skills/go/SKILL.md +187 -0
  36. package/plugins/devflow-go/skills/go/references/concurrency.md +312 -0
  37. package/plugins/devflow-go/skills/go/references/detection.md +129 -0
  38. package/plugins/devflow-go/skills/go/references/patterns.md +232 -0
  39. package/plugins/devflow-go/skills/go/references/violations.md +205 -0
  40. package/plugins/devflow-implement/.claude-plugin/plugin.json +1 -3
  41. package/plugins/devflow-implement/agents/coder.md +11 -6
  42. package/plugins/devflow-java/.claude-plugin/plugin.json +15 -0
  43. package/plugins/devflow-java/skills/java/SKILL.md +183 -0
  44. package/plugins/devflow-java/skills/java/references/detection.md +120 -0
  45. package/plugins/devflow-java/skills/java/references/modern-java.md +270 -0
  46. package/plugins/devflow-java/skills/java/references/patterns.md +235 -0
  47. package/plugins/devflow-java/skills/java/references/violations.md +213 -0
  48. package/plugins/devflow-python/.claude-plugin/plugin.json +15 -0
  49. package/plugins/devflow-python/skills/python/SKILL.md +188 -0
  50. package/plugins/devflow-python/skills/python/references/async.md +220 -0
  51. package/plugins/devflow-python/skills/python/references/detection.md +128 -0
  52. package/plugins/devflow-python/skills/python/references/patterns.md +226 -0
  53. package/plugins/devflow-python/skills/python/references/violations.md +204 -0
  54. package/plugins/devflow-react/.claude-plugin/plugin.json +15 -0
  55. package/plugins/{devflow-core-skills → devflow-react}/skills/react/SKILL.md +1 -1
  56. package/plugins/{devflow-core-skills → devflow-react}/skills/react/references/patterns.md +3 -3
  57. package/plugins/devflow-resolve/.claude-plugin/plugin.json +1 -1
  58. package/plugins/devflow-rust/.claude-plugin/plugin.json +15 -0
  59. package/plugins/devflow-rust/skills/rust/SKILL.md +193 -0
  60. package/plugins/devflow-rust/skills/rust/references/detection.md +131 -0
  61. package/plugins/devflow-rust/skills/rust/references/ownership.md +242 -0
  62. package/plugins/devflow-rust/skills/rust/references/patterns.md +210 -0
  63. package/plugins/devflow-rust/skills/rust/references/violations.md +191 -0
  64. package/plugins/devflow-self-review/.claude-plugin/plugin.json +1 -1
  65. package/plugins/devflow-specify/.claude-plugin/plugin.json +1 -1
  66. package/plugins/devflow-typescript/.claude-plugin/plugin.json +15 -0
  67. package/plugins/{devflow-core-skills → devflow-typescript}/skills/typescript/references/patterns.md +3 -3
  68. package/scripts/hooks/ambient-prompt.sh +48 -0
  69. package/scripts/hooks/background-memory-update.sh +49 -8
  70. package/scripts/hooks/ensure-memory-gitignore.sh +17 -0
  71. package/scripts/hooks/pre-compact-memory.sh +12 -6
  72. package/scripts/hooks/session-start-memory.sh +50 -8
  73. package/scripts/hooks/stop-update-memory.sh +10 -6
  74. package/shared/agents/coder.md +11 -6
  75. package/shared/agents/reviewer.md +8 -0
  76. package/shared/skills/ambient-router/SKILL.md +89 -0
  77. package/shared/skills/ambient-router/references/skill-catalog.md +68 -0
  78. package/shared/skills/docs-framework/SKILL.md +10 -6
  79. package/shared/skills/go/SKILL.md +187 -0
  80. package/shared/skills/go/references/concurrency.md +312 -0
  81. package/shared/skills/go/references/detection.md +129 -0
  82. package/shared/skills/go/references/patterns.md +232 -0
  83. package/shared/skills/go/references/violations.md +205 -0
  84. package/shared/skills/java/SKILL.md +183 -0
  85. package/shared/skills/java/references/detection.md +120 -0
  86. package/shared/skills/java/references/modern-java.md +270 -0
  87. package/shared/skills/java/references/patterns.md +235 -0
  88. package/shared/skills/java/references/violations.md +213 -0
  89. package/shared/skills/python/SKILL.md +188 -0
  90. package/shared/skills/python/references/async.md +220 -0
  91. package/shared/skills/python/references/detection.md +128 -0
  92. package/shared/skills/python/references/patterns.md +226 -0
  93. package/shared/skills/python/references/violations.md +204 -0
  94. package/shared/skills/react/SKILL.md +1 -1
  95. package/shared/skills/react/references/patterns.md +3 -3
  96. package/shared/skills/rust/SKILL.md +193 -0
  97. package/shared/skills/rust/references/detection.md +131 -0
  98. package/shared/skills/rust/references/ownership.md +242 -0
  99. package/shared/skills/rust/references/patterns.md +210 -0
  100. package/shared/skills/rust/references/violations.md +191 -0
  101. package/shared/skills/test-driven-development/SKILL.md +139 -0
  102. package/shared/skills/test-driven-development/references/rationalization-prevention.md +111 -0
  103. package/shared/skills/typescript/references/patterns.md +3 -3
  104. package/src/templates/managed-settings.json +14 -0
  105. package/plugins/devflow-code-review/skills/react/SKILL.md +0 -276
  106. package/plugins/devflow-code-review/skills/react/references/patterns.md +0 -1331
  107. package/plugins/devflow-core-skills/skills/accessibility/SKILL.md +0 -229
  108. package/plugins/devflow-core-skills/skills/accessibility/references/detection.md +0 -171
  109. package/plugins/devflow-core-skills/skills/accessibility/references/patterns.md +0 -670
  110. package/plugins/devflow-core-skills/skills/accessibility/references/violations.md +0 -419
  111. package/plugins/devflow-core-skills/skills/frontend-design/SKILL.md +0 -254
  112. package/plugins/devflow-core-skills/skills/frontend-design/references/detection.md +0 -184
  113. package/plugins/devflow-core-skills/skills/frontend-design/references/patterns.md +0 -511
  114. package/plugins/devflow-core-skills/skills/frontend-design/references/violations.md +0 -453
  115. package/plugins/devflow-core-skills/skills/react/references/violations.md +0 -565
  116. package/plugins/devflow-implement/skills/accessibility/SKILL.md +0 -229
  117. package/plugins/devflow-implement/skills/accessibility/references/detection.md +0 -171
  118. package/plugins/devflow-implement/skills/accessibility/references/patterns.md +0 -670
  119. package/plugins/devflow-implement/skills/accessibility/references/violations.md +0 -419
  120. package/plugins/devflow-implement/skills/frontend-design/SKILL.md +0 -254
  121. package/plugins/devflow-implement/skills/frontend-design/references/detection.md +0 -184
  122. package/plugins/devflow-implement/skills/frontend-design/references/patterns.md +0 -511
  123. package/plugins/devflow-implement/skills/frontend-design/references/violations.md +0 -453
  124. /package/plugins/{devflow-code-review → devflow-accessibility}/skills/accessibility/SKILL.md +0 -0
  125. /package/plugins/{devflow-code-review → devflow-accessibility}/skills/accessibility/references/detection.md +0 -0
  126. /package/plugins/{devflow-code-review → devflow-accessibility}/skills/accessibility/references/patterns.md +0 -0
  127. /package/plugins/{devflow-code-review → devflow-accessibility}/skills/accessibility/references/violations.md +0 -0
  128. /package/plugins/{devflow-code-review → devflow-frontend-design}/skills/frontend-design/SKILL.md +0 -0
  129. /package/plugins/{devflow-code-review → devflow-frontend-design}/skills/frontend-design/references/detection.md +0 -0
  130. /package/plugins/{devflow-code-review → devflow-frontend-design}/skills/frontend-design/references/patterns.md +0 -0
  131. /package/plugins/{devflow-code-review → devflow-frontend-design}/skills/frontend-design/references/violations.md +0 -0
  132. /package/plugins/{devflow-code-review → devflow-react}/skills/react/references/violations.md +0 -0
  133. /package/plugins/{devflow-core-skills → devflow-typescript}/skills/typescript/SKILL.md +0 -0
  134. /package/plugins/{devflow-core-skills → devflow-typescript}/skills/typescript/references/violations.md +0 -0
@@ -0,0 +1,120 @@
1
+ # Detection Patterns for Java Issues
2
+
3
+ Grep and regex patterns for automated detection of Java violations. Reference from main SKILL.md.
4
+
5
+ ---
6
+
7
+ ## Null Returns
8
+
9
+ ```bash
10
+ # Methods returning null instead of Optional
11
+ rg 'return\s+null\s*;' --type java
12
+
13
+ # Nullable method parameters without validation
14
+ rg 'public\s+\w+\s+\w+\((?!.*@NonNull).*\)' --type java
15
+ ```
16
+
17
+ ---
18
+
19
+ ## Raw Types
20
+
21
+ ```bash
22
+ # Raw List, Map, Set, Collection usage
23
+ rg '\b(List|Map|Set|Collection|Iterator|Iterable)\b(?!\s*<)' --type java
24
+
25
+ # Raw Comparable implementation
26
+ rg 'implements\s+Comparable\b(?!\s*<)' --type java
27
+
28
+ # Unsafe casts from Object
29
+ rg '\(\s*(String|Integer|Long|Double)\s*\)\s*\w+\.get' --type java
30
+ ```
31
+
32
+ ---
33
+
34
+ ## Deep Inheritance
35
+
36
+ ```bash
37
+ # Classes extending non-Object/non-interface classes (potential deep hierarchy)
38
+ rg 'class\s+\w+\s+extends\s+(?!Object\b)\w+' --type java
39
+
40
+ # Abstract class chains (look for multiple levels)
41
+ rg 'abstract\s+class\s+\w+\s+extends\s+Abstract' --type java
42
+
43
+ # Count inheritance depth per file
44
+ rg 'extends\s+\w+' --type java --count
45
+ ```
46
+
47
+ ---
48
+
49
+ ## Missing Try-with-Resources
50
+
51
+ ```bash
52
+ # Manual close() calls (should use try-with-resources)
53
+ rg '\.close\(\)\s*;' --type java
54
+
55
+ # InputStream/OutputStream/Connection created outside try-with-resources
56
+ rg 'new\s+(FileInputStream|FileOutputStream|BufferedReader|BufferedWriter|Socket)\(' --type java
57
+
58
+ # getConnection() without try-with-resources context
59
+ rg '\.getConnection\(\)' --type java
60
+ ```
61
+
62
+ ---
63
+
64
+ ## Checked Exception Abuse
65
+
66
+ ```bash
67
+ # Broad throws declarations
68
+ rg 'throws\s+Exception\b' --type java
69
+
70
+ # Empty catch blocks
71
+ rg -U 'catch\s*\([^)]+\)\s*\{\s*\}' --type java --multiline
72
+
73
+ # Catch-and-ignore (catch with only a comment or log)
74
+ rg -U 'catch\s*\([^)]+\)\s*\{\s*(//|/\*|logger\.(debug|trace))' --type java --multiline
75
+ ```
76
+
77
+ ---
78
+
79
+ ## Mutable Data Objects
80
+
81
+ ```bash
82
+ # Setter methods (JavaBean anti-pattern for data objects)
83
+ rg 'public\s+void\s+set[A-Z]\w*\(' --type java
84
+
85
+ # Mutable collections returned from getters
86
+ rg 'return\s+(this\.)?(list|map|set|collection)\s*;' --type java -i
87
+
88
+ # Missing defensive copies in constructors
89
+ rg 'this\.\w+\s*=\s*\w+\s*;' --type java
90
+ ```
91
+
92
+ ---
93
+
94
+ ## Concurrency Issues
95
+
96
+ ```bash
97
+ # HashMap in concurrent context (should be ConcurrentHashMap)
98
+ rg 'new\s+HashMap\b' --type java
99
+
100
+ # Missing volatile on shared fields
101
+ rg 'private\s+(?!volatile\s)(?!final\s)\w+\s+\w+\s*=' --type java
102
+
103
+ # Synchronized on non-private lock object
104
+ rg 'synchronized\s*\(\s*this\s*\)' --type java
105
+ ```
106
+
107
+ ---
108
+
109
+ ## Streams Anti-Patterns
110
+
111
+ ```bash
112
+ # Stream.forEach with side effects (should use for-loop or collect)
113
+ rg '\.stream\(\).*\.forEach\(' --type java
114
+
115
+ # Nested streams (performance concern)
116
+ rg '\.stream\(\).*\.stream\(\)' --type java
117
+
118
+ # collect(Collectors.toList()) instead of .toList() (Java 16+)
119
+ rg 'collect\(Collectors\.toList\(\)\)' --type java
120
+ ```
@@ -0,0 +1,270 @@
1
+ # Modern Java Features (17-21+)
2
+
3
+ Deep-dive on modern Java language features. Reference from main SKILL.md.
4
+
5
+ ---
6
+
7
+ ## Records (Java 16+)
8
+
9
+ ### Basic Record
10
+
11
+ ```java
12
+ // Immutable data carrier with auto-generated equals, hashCode, toString
13
+ public record Point(double x, double y) {}
14
+
15
+ // Usage
16
+ var p = new Point(3.0, 4.0);
17
+ double x = p.x(); // Accessor method, not getX()
18
+ ```
19
+
20
+ ### Compact Constructor (Validation)
21
+
22
+ ```java
23
+ public record Email(String value) {
24
+ public Email {
25
+ Objects.requireNonNull(value, "email must not be null");
26
+ if (!value.contains("@")) {
27
+ throw new IllegalArgumentException("Invalid email: " + value);
28
+ }
29
+ value = value.toLowerCase().strip(); // Reassign before final assignment
30
+ }
31
+ }
32
+ ```
33
+
34
+ ### Record with Custom Methods
35
+
36
+ ```java
37
+ public record Range(int start, int end) {
38
+ public Range {
39
+ if (start > end) throw new IllegalArgumentException("start must be <= end");
40
+ }
41
+
42
+ public int length() { return end - start; }
43
+ public boolean contains(int value) { return value >= start && value <= end; }
44
+ public Range overlap(Range other) {
45
+ int newStart = Math.max(start, other.start);
46
+ int newEnd = Math.min(end, other.end);
47
+ return newStart <= newEnd ? new Range(newStart, newEnd) : null;
48
+ }
49
+ }
50
+ ```
51
+
52
+ ### Records as Local Classes
53
+
54
+ ```java
55
+ public List<String> processOrders(List<Order> orders) {
56
+ // Local record for intermediate computation
57
+ record OrderTotal(String orderId, Money total) {}
58
+
59
+ return orders.stream()
60
+ .map(o -> new OrderTotal(o.id(), o.calculateTotal()))
61
+ .filter(ot -> ot.total().isGreaterThan(Money.of(100)))
62
+ .map(OrderTotal::orderId)
63
+ .toList();
64
+ }
65
+ ```
66
+
67
+ ---
68
+
69
+ ## Sealed Classes (Java 17+)
70
+
71
+ ### Sealed Interface
72
+
73
+ ```java
74
+ public sealed interface Shape permits Circle, Rectangle, Triangle {
75
+ double area();
76
+ }
77
+
78
+ public record Circle(double radius) implements Shape {
79
+ public double area() { return Math.PI * radius * radius; }
80
+ }
81
+
82
+ public record Rectangle(double width, double height) implements Shape {
83
+ public double area() { return width * height; }
84
+ }
85
+
86
+ public record Triangle(double base, double height) implements Shape {
87
+ public double area() { return 0.5 * base * height; }
88
+ }
89
+ ```
90
+
91
+ ### Sealed Class with Abstract Methods
92
+
93
+ ```java
94
+ public sealed abstract class Payment permits CreditCard, BankTransfer, Crypto {
95
+ abstract Money amount();
96
+ abstract String reference();
97
+ }
98
+
99
+ public final class CreditCard extends Payment {
100
+ private final String cardLast4;
101
+ private final Money amount;
102
+ // ...
103
+ }
104
+
105
+ public final class BankTransfer extends Payment { /* ... */ }
106
+ public final class Crypto extends Payment { /* ... */ }
107
+ ```
108
+
109
+ ---
110
+
111
+ ## Pattern Matching (Java 21+)
112
+
113
+ ### Switch with Patterns
114
+
115
+ ```java
116
+ // Exhaustive pattern matching on sealed types
117
+ public String describe(Shape shape) {
118
+ return switch (shape) {
119
+ case Circle c -> "Circle with radius %.2f".formatted(c.radius());
120
+ case Rectangle r -> "Rectangle %s x %s".formatted(r.width(), r.height());
121
+ case Triangle t -> "Triangle with base %.2f".formatted(t.base());
122
+ };
123
+ }
124
+ ```
125
+
126
+ ### Guarded Patterns
127
+
128
+ ```java
129
+ public String classifyTemperature(Object obj) {
130
+ return switch (obj) {
131
+ case Integer i when i < 0 -> "Freezing";
132
+ case Integer i when i < 15 -> "Cold";
133
+ case Integer i when i < 25 -> "Comfortable";
134
+ case Integer i -> "Hot";
135
+ case Double d when d < 0.0 -> "Freezing";
136
+ case Double d -> "Warm-ish (%.1f)".formatted(d);
137
+ case String s -> "Not a temperature: " + s;
138
+ case null -> "No reading";
139
+ default -> "Unknown type";
140
+ };
141
+ }
142
+ ```
143
+
144
+ ### Record Patterns (Destructuring)
145
+
146
+ ```java
147
+ // Nested destructuring
148
+ record Address(String city, String country) {}
149
+ record Person(String name, Address address) {}
150
+
151
+ public String greet(Object obj) {
152
+ return switch (obj) {
153
+ case Person(var name, Address(var city, _)) ->
154
+ "Hello %s from %s".formatted(name, city);
155
+ default -> "Hello stranger";
156
+ };
157
+ }
158
+ ```
159
+
160
+ ---
161
+
162
+ ## Text Blocks (Java 15+)
163
+
164
+ ```java
165
+ // Multi-line strings with proper indentation
166
+ String json = """
167
+ {
168
+ "name": "%s",
169
+ "email": "%s",
170
+ "active": true
171
+ }
172
+ """.formatted(user.name(), user.email());
173
+
174
+ String sql = """
175
+ SELECT u.id, u.name, u.email
176
+ FROM users u
177
+ JOIN orders o ON o.user_id = u.id
178
+ WHERE u.active = true
179
+ AND o.created_at > ?
180
+ ORDER BY u.name
181
+ """;
182
+ ```
183
+
184
+ ---
185
+
186
+ ## Virtual Threads (Java 21+)
187
+
188
+ ### Basic Virtual Thread
189
+
190
+ ```java
191
+ // Lightweight thread - does not pin platform thread during I/O
192
+ Thread.startVirtualThread(() -> {
193
+ var result = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
194
+ process(result.body());
195
+ });
196
+ ```
197
+
198
+ ### Structured Concurrency (Preview)
199
+
200
+ ```java
201
+ // All subtasks complete or cancel together
202
+ try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
203
+ Subtask<User> userTask = scope.fork(() -> fetchUser(userId));
204
+ Subtask<List<Order>> ordersTask = scope.fork(() -> fetchOrders(userId));
205
+
206
+ scope.join().throwIfFailed();
207
+
208
+ return new UserDashboard(userTask.get(), ordersTask.get());
209
+ }
210
+ ```
211
+
212
+ ### ExecutorService with Virtual Threads
213
+
214
+ ```java
215
+ // Process thousands of concurrent I/O tasks
216
+ try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
217
+ List<Future<Response>> futures = urls.stream()
218
+ .map(url -> executor.submit(() -> httpClient.send(
219
+ HttpRequest.newBuilder(URI.create(url)).build(),
220
+ HttpResponse.BodyHandlers.ofString()
221
+ )))
222
+ .toList();
223
+
224
+ List<Response> responses = futures.stream()
225
+ .map(f -> {
226
+ try { return f.get(); }
227
+ catch (Exception e) { throw new RuntimeException(e); }
228
+ })
229
+ .toList();
230
+ }
231
+ ```
232
+
233
+ ---
234
+
235
+ ## Other Modern Features
236
+
237
+ ### Enhanced instanceof (Java 16+)
238
+
239
+ ```java
240
+ // Pattern variable binding eliminates explicit cast
241
+ if (obj instanceof String s && s.length() > 5) {
242
+ System.out.println(s.toUpperCase());
243
+ }
244
+
245
+ // Works with negation
246
+ if (!(obj instanceof String s)) {
247
+ throw new IllegalArgumentException("Expected String");
248
+ }
249
+ // s is in scope here
250
+ process(s);
251
+ ```
252
+
253
+ ### Helpful NullPointerExceptions (Java 14+)
254
+
255
+ ```java
256
+ // JVM now tells you exactly which reference was null:
257
+ // java.lang.NullPointerException: Cannot invoke "String.length()"
258
+ // because the return value of "User.name()" is null
259
+ // Enable with: -XX:+ShowCodeDetailsInExceptionMessages (default since Java 17)
260
+ ```
261
+
262
+ ### Stream Gatherers (Java 22+ Preview)
263
+
264
+ ```java
265
+ // Custom intermediate stream operations
266
+ var windowedAverages = temperatures.stream()
267
+ .gather(Gatherers.windowSliding(5))
268
+ .map(window -> window.stream().mapToDouble(d -> d).average().orElse(0))
269
+ .toList();
270
+ ```
@@ -0,0 +1,235 @@
1
+ # Extended Java Patterns
2
+
3
+ Correct patterns for Java development. Reference from main SKILL.md.
4
+
5
+ ---
6
+
7
+ ## Builder Pattern (Type-Safe)
8
+
9
+ ```java
10
+ // Compile-time enforcement of required fields
11
+ public record EmailMessage(String to, String subject, String body, List<String> cc) {
12
+
13
+ public static Builder builder() { return new Builder(); }
14
+
15
+ public static class Builder {
16
+ private String to;
17
+ private String subject;
18
+ private String body;
19
+ private List<String> cc = List.of();
20
+
21
+ public Builder to(String to) { this.to = Objects.requireNonNull(to); return this; }
22
+ public Builder subject(String subject) { this.subject = Objects.requireNonNull(subject); return this; }
23
+ public Builder body(String body) { this.body = Objects.requireNonNull(body); return this; }
24
+ public Builder cc(List<String> cc) { this.cc = List.copyOf(cc); return this; }
25
+
26
+ public EmailMessage build() {
27
+ Objects.requireNonNull(to, "to is required");
28
+ Objects.requireNonNull(subject, "subject is required");
29
+ Objects.requireNonNull(body, "body is required");
30
+ return new EmailMessage(to, subject, body, cc);
31
+ }
32
+ }
33
+ }
34
+
35
+ // Usage
36
+ var email = EmailMessage.builder()
37
+ .to("user@example.com")
38
+ .subject("Welcome")
39
+ .body("Hello!")
40
+ .build();
41
+ ```
42
+
43
+ ---
44
+
45
+ ## Strategy via Interfaces
46
+
47
+ ```java
48
+ // Define strategy as functional interface
49
+ @FunctionalInterface
50
+ public interface PricingStrategy {
51
+ Money calculatePrice(Order order);
52
+ }
53
+
54
+ // Implementations as lambdas or classes
55
+ PricingStrategy standard = order -> order.subtotal();
56
+ PricingStrategy discounted = order -> order.subtotal().multiply(0.9);
57
+ PricingStrategy tiered = order -> {
58
+ if (order.itemCount() > 10) return order.subtotal().multiply(0.8);
59
+ if (order.itemCount() > 5) return order.subtotal().multiply(0.9);
60
+ return order.subtotal();
61
+ };
62
+
63
+ // Inject strategy
64
+ public class OrderService {
65
+ private final PricingStrategy pricing;
66
+
67
+ public OrderService(PricingStrategy pricing) {
68
+ this.pricing = pricing;
69
+ }
70
+
71
+ public Money calculateTotal(Order order) {
72
+ return pricing.calculatePrice(order);
73
+ }
74
+ }
75
+ ```
76
+
77
+ ---
78
+
79
+ ## Repository Pattern
80
+
81
+ ```java
82
+ public interface UserRepository {
83
+ Optional<User> findById(String id);
84
+ List<User> findByEmail(String email);
85
+ User save(User user);
86
+ void deleteById(String id);
87
+ boolean existsById(String id);
88
+ }
89
+
90
+ // Implementation with constructor injection
91
+ public class JpaUserRepository implements UserRepository {
92
+ private final EntityManager em;
93
+
94
+ public JpaUserRepository(EntityManager em) {
95
+ this.em = em;
96
+ }
97
+
98
+ @Override
99
+ public Optional<User> findById(String id) {
100
+ return Optional.ofNullable(em.find(User.class, id));
101
+ }
102
+
103
+ @Override
104
+ public User save(User user) {
105
+ return em.merge(user);
106
+ }
107
+ }
108
+ ```
109
+
110
+ ---
111
+
112
+ ## Value Objects
113
+
114
+ ```java
115
+ // Immutable value object with validation
116
+ public record Money(BigDecimal amount, Currency currency) {
117
+ public Money {
118
+ Objects.requireNonNull(amount, "amount must not be null");
119
+ Objects.requireNonNull(currency, "currency must not be null");
120
+ if (amount.scale() > currency.getDefaultFractionDigits()) {
121
+ throw new IllegalArgumentException("Scale exceeds currency precision");
122
+ }
123
+ }
124
+
125
+ public Money add(Money other) {
126
+ requireSameCurrency(other);
127
+ return new Money(amount.add(other.amount), currency);
128
+ }
129
+
130
+ public Money multiply(double factor) {
131
+ return new Money(
132
+ amount.multiply(BigDecimal.valueOf(factor))
133
+ .setScale(currency.getDefaultFractionDigits(), RoundingMode.HALF_UP),
134
+ currency
135
+ );
136
+ }
137
+
138
+ private void requireSameCurrency(Money other) {
139
+ if (!currency.equals(other.currency)) {
140
+ throw new IllegalArgumentException(
141
+ "Cannot combine %s and %s".formatted(currency, other.currency)
142
+ );
143
+ }
144
+ }
145
+ }
146
+ ```
147
+
148
+ ---
149
+
150
+ ## Event-Driven Pattern
151
+
152
+ ```java
153
+ // Domain event as sealed interface
154
+ public sealed interface OrderEvent permits OrderCreated, OrderShipped, OrderCancelled {
155
+ String orderId();
156
+ Instant occurredAt();
157
+ }
158
+
159
+ public record OrderCreated(String orderId, Instant occurredAt, List<LineItem> items)
160
+ implements OrderEvent {}
161
+
162
+ public record OrderShipped(String orderId, Instant occurredAt, String trackingNumber)
163
+ implements OrderEvent {}
164
+
165
+ public record OrderCancelled(String orderId, Instant occurredAt, String reason)
166
+ implements OrderEvent {}
167
+
168
+ // Event handler with exhaustive matching
169
+ public class OrderEventHandler {
170
+ public void handle(OrderEvent event) {
171
+ switch (event) {
172
+ case OrderCreated e -> notifyWarehouse(e.items());
173
+ case OrderShipped e -> sendTrackingEmail(e.trackingNumber());
174
+ case OrderCancelled e -> processRefund(e.orderId(), e.reason());
175
+ }
176
+ }
177
+ }
178
+ ```
179
+
180
+ ---
181
+
182
+ ## Stream Pipelines
183
+
184
+ ```java
185
+ // Declarative collection processing
186
+ public List<String> getActiveUserEmails(List<User> users) {
187
+ return users.stream()
188
+ .filter(User::isActive)
189
+ .map(User::email)
190
+ .filter(email -> email.contains("@"))
191
+ .sorted()
192
+ .toList(); // Unmodifiable list (Java 16+)
193
+ }
194
+
195
+ // Grouping and aggregation
196
+ public Map<Department, Long> countByDepartment(List<Employee> employees) {
197
+ return employees.stream()
198
+ .collect(Collectors.groupingBy(Employee::department, Collectors.counting()));
199
+ }
200
+
201
+ // Reducing to summary
202
+ public record OrderSummary(int count, Money total) {}
203
+
204
+ public OrderSummary summarize(List<Order> orders) {
205
+ return orders.stream()
206
+ .reduce(
207
+ new OrderSummary(0, Money.ZERO),
208
+ (summary, order) -> new OrderSummary(
209
+ summary.count() + 1,
210
+ summary.total().add(order.total())
211
+ ),
212
+ (a, b) -> new OrderSummary(a.count() + b.count(), a.total().add(b.total()))
213
+ );
214
+ }
215
+ ```
216
+
217
+ ---
218
+
219
+ ## Dependency Injection (Manual)
220
+
221
+ ```java
222
+ // Composition root wires everything together
223
+ public class Application {
224
+ public static void main(String[] args) {
225
+ var config = Config.load();
226
+ var dataSource = createDataSource(config);
227
+ var userRepo = new JpaUserRepository(dataSource);
228
+ var eventBus = new InMemoryEventBus();
229
+ var userService = new UserService(userRepo, eventBus);
230
+ var userController = new UserController(userService);
231
+
232
+ startServer(config.port(), userController);
233
+ }
234
+ }
235
+ ```