@mytechtoday/augment-extensions 1.2.2 → 1.3.1
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/LICENSE +22 -22
- package/augment-extensions/domain-rules/software-architecture/README.md +143 -143
- package/augment-extensions/domain-rules/software-architecture/examples/banking-layered.md +961 -961
- package/augment-extensions/domain-rules/software-architecture/examples/ecommerce-microservices.md +990 -990
- package/augment-extensions/domain-rules/software-architecture/examples/iot-eventdriven.md +882 -882
- package/augment-extensions/domain-rules/software-architecture/examples/monolith-to-microservices-migration.md +703 -703
- package/augment-extensions/domain-rules/software-architecture/examples/serverless-imageprocessing.md +957 -957
- package/augment-extensions/domain-rules/software-architecture/examples/trading-eventdriven.md +747 -747
- package/augment-extensions/domain-rules/software-architecture/module.json +119 -119
- package/augment-extensions/domain-rules/software-architecture/rules/challenges-solutions.md +763 -763
- package/augment-extensions/domain-rules/software-architecture/rules/definitions-terminology.md +409 -409
- package/augment-extensions/domain-rules/software-architecture/rules/design-principles.md +684 -684
- package/augment-extensions/domain-rules/software-architecture/rules/evaluation-testing.md +1381 -1381
- package/augment-extensions/domain-rules/software-architecture/rules/event-driven-architecture.md +616 -616
- package/augment-extensions/domain-rules/software-architecture/rules/fundamentals.md +306 -306
- package/augment-extensions/domain-rules/software-architecture/rules/industry-architectures.md +554 -554
- package/augment-extensions/domain-rules/software-architecture/rules/layered-architecture.md +776 -776
- package/augment-extensions/domain-rules/software-architecture/rules/microservices-architecture.md +503 -503
- package/augment-extensions/domain-rules/software-architecture/rules/modeling-documentation.md +1199 -1199
- package/augment-extensions/domain-rules/software-architecture/rules/monolithic-architecture.md +351 -351
- package/augment-extensions/domain-rules/software-architecture/rules/principles.md +556 -556
- package/augment-extensions/domain-rules/software-architecture/rules/quality-attributes.md +797 -797
- package/augment-extensions/domain-rules/software-architecture/rules/scalability-performance.md +1345 -1345
- package/augment-extensions/domain-rules/software-architecture/rules/security-architecture.md +1039 -1039
- package/augment-extensions/domain-rules/software-architecture/rules/serverless-architecture.md +711 -711
- package/augment-extensions/domain-rules/software-architecture/rules/skills-development.md +568 -568
- package/augment-extensions/domain-rules/software-architecture/rules/tools-methodologies.md +961 -961
- package/augment-extensions/visual-design/CHANGELOG.md +132 -0
- package/augment-extensions/visual-design/README.md +255 -0
- package/augment-extensions/visual-design/__tests__/README.md +119 -0
- package/augment-extensions/visual-design/__tests__/style-selector.test.ts +172 -0
- package/augment-extensions/visual-design/__tests__/vendor-styles.test.ts +214 -0
- package/augment-extensions/visual-design/domains/other/ai-prompt-helper.ts +157 -0
- package/augment-extensions/visual-design/domains/other/dotnet-application.ts +156 -0
- package/augment-extensions/visual-design/domains/other/linux-platform.ts +156 -0
- package/augment-extensions/visual-design/domains/other/mobile-application.ts +157 -0
- package/augment-extensions/visual-design/domains/other/motion-picture.ts +156 -0
- package/augment-extensions/visual-design/domains/other/os-application.ts +156 -0
- package/augment-extensions/visual-design/domains/other/print-campaigns.ts +158 -0
- package/augment-extensions/visual-design/domains/other/web-app.ts +157 -0
- package/augment-extensions/visual-design/domains/other/website.ts +161 -0
- package/augment-extensions/visual-design/domains/other/windows-platform.ts +156 -0
- package/augment-extensions/visual-design/domains/web-page-styles/amazon-cloudscape.ts +506 -0
- package/augment-extensions/visual-design/domains/web-page-styles/google-modern.ts +615 -0
- package/augment-extensions/visual-design/domains/web-page-styles/microsoft-fluent.ts +531 -0
- package/augment-extensions/visual-design/examples/README.md +97 -0
- package/augment-extensions/visual-design/examples/ai-prompt-generation.md +233 -0
- package/augment-extensions/visual-design/examples/basic-usage.md +216 -0
- package/augment-extensions/visual-design/examples/domain-workflows.md +257 -0
- package/augment-extensions/visual-design/examples/vendor-comparison.md +247 -0
- package/augment-extensions/visual-design/module.json +78 -0
- package/augment-extensions/visual-design/style-selector.ts +177 -0
- package/augment-extensions/visual-design/types.ts +302 -0
- package/augment-extensions/visual-design/visual-design-core.ts +469 -0
- package/augment-extensions/workflows/adr-support/README.md +227 -0
- package/augment-extensions/workflows/adr-support/__tests__/adr-validator.test.ts +203 -0
- package/augment-extensions/workflows/adr-support/adr-validator.ts +162 -0
- package/augment-extensions/workflows/adr-support/examples/complete-lifecycle-example.md +449 -0
- package/augment-extensions/workflows/adr-support/examples/integration-example.md +580 -0
- package/augment-extensions/workflows/adr-support/examples/superseding-example.md +436 -0
- package/augment-extensions/workflows/adr-support/module.json +112 -0
- package/augment-extensions/workflows/adr-support/rules/adr-creation.md +372 -0
- package/augment-extensions/workflows/adr-support/rules/beads-integration.md +443 -0
- package/augment-extensions/workflows/adr-support/rules/conflict-detection.md +486 -0
- package/augment-extensions/workflows/adr-support/rules/decision-detection.md +362 -0
- package/augment-extensions/workflows/adr-support/rules/lifecycle-management.md +427 -0
- package/augment-extensions/workflows/adr-support/rules/openspec-integration.md +465 -0
- package/augment-extensions/workflows/adr-support/rules/template-selection.md +405 -0
- package/augment-extensions/workflows/adr-support/rules/validation-rules.md +543 -0
- package/augment-extensions/workflows/adr-support/schemas/adr-config.json +191 -0
- package/augment-extensions/workflows/adr-support/schemas/adr-metadata.json +172 -0
- package/augment-extensions/workflows/adr-support/templates/business-case.md +235 -0
- package/augment-extensions/workflows/adr-support/templates/madr-elaborate.md +197 -0
- package/augment-extensions/workflows/adr-support/templates/madr-simple.md +68 -0
- package/augment-extensions/workflows/adr-support/templates/nygard.md +84 -0
- package/augment-extensions/writing-standards/screenplay/rules/file-organization.md +213 -213
- package/augment-extensions/writing-standards/screenplay/utils/__tests__/file-organization.test.ts +169 -169
- package/augment-extensions/writing-standards/screenplay/utils/file-organization.ts +165 -165
- package/cli/dist/utils/auto-sync.js +19 -19
- package/package.json +5 -3
- package/augment-extensions/workflows/openspec/README.md +0 -96
- package/augment-extensions/workflows/openspec/examples/complete-change-example.md +0 -244
- package/augment-extensions/workflows/openspec/module.json +0 -54
- package/augment-extensions/workflows/openspec/rules/best-practices.md +0 -272
- package/augment-extensions/workflows/openspec/rules/manual-setup.md +0 -231
- package/augment-extensions/workflows/openspec/rules/spec-format.md +0 -236
- package/augment-extensions/workflows/openspec/rules/workflow.md +0 -214
|
@@ -1,556 +1,556 @@
|
|
|
1
|
-
# Software Architecture Principles
|
|
2
|
-
|
|
3
|
-
## Overview
|
|
4
|
-
|
|
5
|
-
This document covers fundamental architectural principles that guide the design of robust, maintainable, and scalable software systems.
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## Knowledge
|
|
10
|
-
|
|
11
|
-
### Modularity
|
|
12
|
-
|
|
13
|
-
**Definition**
|
|
14
|
-
- Decomposition of system into discrete, independent modules
|
|
15
|
-
- Each module encapsulates specific functionality
|
|
16
|
-
- Modules interact through well-defined interfaces
|
|
17
|
-
- Enables parallel development and independent deployment
|
|
18
|
-
|
|
19
|
-
**Benefits**
|
|
20
|
-
- Easier to understand (smaller, focused units)
|
|
21
|
-
- Easier to test (isolated testing)
|
|
22
|
-
- Easier to maintain (localized changes)
|
|
23
|
-
- Enables reuse (modules as building blocks)
|
|
24
|
-
|
|
25
|
-
**Characteristics of Good Modules**
|
|
26
|
-
- Single, well-defined purpose
|
|
27
|
-
- Clear interface (contract)
|
|
28
|
-
- Information hiding (encapsulation)
|
|
29
|
-
- Minimal dependencies
|
|
30
|
-
|
|
31
|
-
### Separation of Concerns
|
|
32
|
-
|
|
33
|
-
**Definition**
|
|
34
|
-
- Distinct features should be managed by distinct components
|
|
35
|
-
- Each component addresses a specific concern
|
|
36
|
-
- Reduces overlap and interdependencies
|
|
37
|
-
- Examples: presentation vs. business logic vs. data access
|
|
38
|
-
|
|
39
|
-
**Common Separations**
|
|
40
|
-
|
|
41
|
-
**Horizontal Separation (Layering)**
|
|
42
|
-
- Presentation Layer (UI)
|
|
43
|
-
- Business Logic Layer (domain)
|
|
44
|
-
- Data Access Layer (persistence)
|
|
45
|
-
- Infrastructure Layer (cross-cutting)
|
|
46
|
-
|
|
47
|
-
**Vertical Separation (Features)**
|
|
48
|
-
- User Management
|
|
49
|
-
- Product Catalog
|
|
50
|
-
- Order Processing
|
|
51
|
-
- Payment Processing
|
|
52
|
-
|
|
53
|
-
**Cross-Cutting Concerns**
|
|
54
|
-
- Logging
|
|
55
|
-
- Security
|
|
56
|
-
- Caching
|
|
57
|
-
- Error handling
|
|
58
|
-
|
|
59
|
-
### Loose Coupling
|
|
60
|
-
|
|
61
|
-
**Definition**
|
|
62
|
-
- Minimize dependencies between components
|
|
63
|
-
- Components can change independently
|
|
64
|
-
- Reduces ripple effects of changes
|
|
65
|
-
- Enables flexibility and adaptability
|
|
66
|
-
|
|
67
|
-
**Coupling Types (Low to High)**
|
|
68
|
-
|
|
69
|
-
1. **No Coupling**: Components are independent
|
|
70
|
-
2. **Data Coupling**: Share data through parameters
|
|
71
|
-
3. **Stamp Coupling**: Share composite data structures
|
|
72
|
-
4. **Control Coupling**: One component controls another's flow
|
|
73
|
-
5. **Common Coupling**: Share global data
|
|
74
|
-
6. **Content Coupling**: One component modifies another's internals
|
|
75
|
-
|
|
76
|
-
**Achieving Loose Coupling**
|
|
77
|
-
- Dependency injection
|
|
78
|
-
- Interface-based programming
|
|
79
|
-
- Event-driven architecture
|
|
80
|
-
- Message queues
|
|
81
|
-
- API contracts
|
|
82
|
-
|
|
83
|
-
### High Cohesion
|
|
84
|
-
|
|
85
|
-
**Definition**
|
|
86
|
-
- Degree to which elements within a module belong together
|
|
87
|
-
- Related functionality grouped together
|
|
88
|
-
- Unrelated functionality separated
|
|
89
|
-
- Complements loose coupling
|
|
90
|
-
|
|
91
|
-
**Cohesion Types (Low to High)**
|
|
92
|
-
|
|
93
|
-
1. **Coincidental**: Random grouping (worst)
|
|
94
|
-
2. **Logical**: Similar operations grouped
|
|
95
|
-
3. **Temporal**: Operations performed at same time
|
|
96
|
-
4. **Procedural**: Operations in sequence
|
|
97
|
-
5. **Communicational**: Operate on same data
|
|
98
|
-
6. **Sequential**: Output of one is input to another
|
|
99
|
-
7. **Functional**: All elements contribute to single task (best)
|
|
100
|
-
|
|
101
|
-
**Achieving High Cohesion**
|
|
102
|
-
- Single Responsibility Principle
|
|
103
|
-
- Domain-Driven Design
|
|
104
|
-
- Feature-based organization
|
|
105
|
-
- Clear module boundaries
|
|
106
|
-
|
|
107
|
-
---
|
|
108
|
-
|
|
109
|
-
## Skills
|
|
110
|
-
|
|
111
|
-
### Applying Modularity
|
|
112
|
-
|
|
113
|
-
**Module Identification Process**
|
|
114
|
-
|
|
115
|
-
1. **Identify Responsibilities**: List system capabilities
|
|
116
|
-
2. **Group Related Responsibilities**: Cluster by domain/function
|
|
117
|
-
3. **Define Module Boundaries**: Establish clear interfaces
|
|
118
|
-
4. **Minimize Dependencies**: Reduce inter-module coupling
|
|
119
|
-
5. **Validate**: Ensure each module has single, clear purpose
|
|
120
|
-
|
|
121
|
-
**Module Design Checklist**
|
|
122
|
-
|
|
123
|
-
✅ Does module have single, well-defined purpose?
|
|
124
|
-
✅ Can module be understood independently?
|
|
125
|
-
✅ Can module be tested in isolation?
|
|
126
|
-
✅ Does module hide implementation details?
|
|
127
|
-
✅ Are module dependencies minimal and explicit?
|
|
128
|
-
|
|
129
|
-
### Implementing Separation of Concerns
|
|
130
|
-
|
|
131
|
-
**Layered Architecture Example**
|
|
132
|
-
|
|
133
|
-
```
|
|
134
|
-
┌─────────────────────────────────┐
|
|
135
|
-
│ Presentation Layer │ ← UI, Controllers, Views
|
|
136
|
-
├─────────────────────────────────┤
|
|
137
|
-
│ Business Logic Layer │ ← Domain Models, Services
|
|
138
|
-
├─────────────────────────────────┤
|
|
139
|
-
│ Data Access Layer │ ← Repositories, ORM
|
|
140
|
-
├─────────────────────────────────┤
|
|
141
|
-
│ Infrastructure Layer │ ← Logging, Config, Security
|
|
142
|
-
└─────────────────────────────────┘
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
**Layer Responsibilities**
|
|
146
|
-
|
|
147
|
-
**Presentation**: User interaction, input validation, display
|
|
148
|
-
**Business Logic**: Business rules, workflows, domain logic
|
|
149
|
-
**Data Access**: CRUD operations, queries, persistence
|
|
150
|
-
**Infrastructure**: Cross-cutting concerns, utilities
|
|
151
|
-
|
|
152
|
-
**Layer Rules**
|
|
153
|
-
|
|
154
|
-
✅ Upper layers depend on lower layers
|
|
155
|
-
✅ Lower layers don't know about upper layers
|
|
156
|
-
✅ Each layer has clear responsibility
|
|
157
|
-
❌ Skip layers (presentation → data access directly)
|
|
158
|
-
❌ Circular dependencies between layers
|
|
159
|
-
|
|
160
|
-
### Reducing Coupling
|
|
161
|
-
|
|
162
|
-
**Dependency Injection Pattern**
|
|
163
|
-
|
|
164
|
-
```typescript
|
|
165
|
-
// ❌ Tight Coupling
|
|
166
|
-
class OrderService {
|
|
167
|
-
private paymentGateway = new StripePaymentGateway();
|
|
168
|
-
|
|
169
|
-
processOrder(order: Order) {
|
|
170
|
-
this.paymentGateway.charge(order.total);
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
// ✅ Loose Coupling
|
|
175
|
-
interface PaymentGateway {
|
|
176
|
-
charge(amount: number): Promise<void>;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
class OrderService {
|
|
180
|
-
constructor(private paymentGateway: PaymentGateway) {}
|
|
181
|
-
|
|
182
|
-
processOrder(order: Order) {
|
|
183
|
-
this.paymentGateway.charge(order.total);
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
**Event-Driven Decoupling**
|
|
189
|
-
|
|
190
|
-
```typescript
|
|
191
|
-
// ❌ Direct Coupling
|
|
192
|
-
class OrderService {
|
|
193
|
-
constructor(
|
|
194
|
-
private inventoryService: InventoryService,
|
|
195
|
-
private emailService: EmailService
|
|
196
|
-
) {}
|
|
197
|
-
|
|
198
|
-
createOrder(order: Order) {
|
|
199
|
-
// ... create order
|
|
200
|
-
this.inventoryService.decrementStock(order.items);
|
|
201
|
-
this.emailService.sendConfirmation(order);
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
// ✅ Event-Driven Decoupling
|
|
206
|
-
class OrderService {
|
|
207
|
-
constructor(private eventBus: EventBus) {}
|
|
208
|
-
|
|
209
|
-
createOrder(order: Order) {
|
|
210
|
-
// ... create order
|
|
211
|
-
this.eventBus.publish('order.created', order);
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
### Increasing Cohesion
|
|
217
|
-
|
|
218
|
-
**Functional Cohesion Example**
|
|
219
|
-
|
|
220
|
-
```typescript
|
|
221
|
-
// ❌ Low Cohesion (Coincidental)
|
|
222
|
-
class Utilities {
|
|
223
|
-
formatDate(date: Date): string { }
|
|
224
|
-
sendEmail(to: string, body: string): void { }
|
|
225
|
-
calculateTax(amount: number): number { }
|
|
226
|
-
validatePassword(password: string): boolean { }
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
// ✅ High Cohesion (Functional)
|
|
230
|
-
class DateFormatter {
|
|
231
|
-
format(date: Date): string { }
|
|
232
|
-
parse(dateString: string): Date { }
|
|
233
|
-
isValid(dateString: string): boolean { }
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
class EmailService {
|
|
237
|
-
send(to: string, subject: string, body: string): void { }
|
|
238
|
-
sendBulk(recipients: string[], subject: string, body: string): void { }
|
|
239
|
-
validateEmail(email: string): boolean { }
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
class TaxCalculator {
|
|
243
|
-
calculate(amount: number, region: string): number { }
|
|
244
|
-
getRate(region: string): number { }
|
|
245
|
-
applyExemptions(amount: number, exemptions: string[]): number { }
|
|
246
|
-
}
|
|
247
|
-
```
|
|
248
|
-
|
|
249
|
-
**Domain-Driven Cohesion**
|
|
250
|
-
|
|
251
|
-
```typescript
|
|
252
|
-
// ✅ High Cohesion - Order Aggregate
|
|
253
|
-
class Order {
|
|
254
|
-
private items: OrderItem[] = [];
|
|
255
|
-
private status: OrderStatus = 'pending';
|
|
256
|
-
|
|
257
|
-
addItem(product: Product, quantity: number): void {
|
|
258
|
-
// Related to order management
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
removeItem(productId: string): void {
|
|
262
|
-
// Related to order management
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
calculateTotal(): number {
|
|
266
|
-
// Related to order management
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
submit(): void {
|
|
270
|
-
// Related to order lifecycle
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
cancel(): void {
|
|
274
|
-
// Related to order lifecycle
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
```
|
|
278
|
-
|
|
279
|
-
---
|
|
280
|
-
|
|
281
|
-
## Examples
|
|
282
|
-
|
|
283
|
-
### Example 1: E-Commerce System Architecture
|
|
284
|
-
|
|
285
|
-
**Modularity Applied**
|
|
286
|
-
|
|
287
|
-
```
|
|
288
|
-
Modules:
|
|
289
|
-
├── User Management
|
|
290
|
-
│ ├── Authentication
|
|
291
|
-
│ ├── Authorization
|
|
292
|
-
│ └── Profile Management
|
|
293
|
-
├── Product Catalog
|
|
294
|
-
│ ├── Product Search
|
|
295
|
-
│ ├── Category Management
|
|
296
|
-
│ └── Inventory Tracking
|
|
297
|
-
├── Shopping Cart
|
|
298
|
-
│ ├── Cart Operations
|
|
299
|
-
│ └── Session Management
|
|
300
|
-
└── Order Processing
|
|
301
|
-
├── Order Creation
|
|
302
|
-
├── Payment Processing
|
|
303
|
-
└── Order Fulfillment
|
|
304
|
-
```
|
|
305
|
-
|
|
306
|
-
**Separation of Concerns**
|
|
307
|
-
|
|
308
|
-
```
|
|
309
|
-
Presentation Layer:
|
|
310
|
-
- Web UI (React)
|
|
311
|
-
- Mobile App (React Native)
|
|
312
|
-
- Admin Dashboard
|
|
313
|
-
|
|
314
|
-
Business Logic Layer:
|
|
315
|
-
- Order Service
|
|
316
|
-
- Product Service
|
|
317
|
-
- User Service
|
|
318
|
-
- Payment Service
|
|
319
|
-
|
|
320
|
-
Data Access Layer:
|
|
321
|
-
- Order Repository
|
|
322
|
-
- Product Repository
|
|
323
|
-
- User Repository
|
|
324
|
-
|
|
325
|
-
Infrastructure:
|
|
326
|
-
- Logging (Winston)
|
|
327
|
-
- Caching (Redis)
|
|
328
|
-
- Authentication (JWT)
|
|
329
|
-
```
|
|
330
|
-
|
|
331
|
-
**Loose Coupling via Interfaces**
|
|
332
|
-
|
|
333
|
-
```typescript
|
|
334
|
-
// Payment abstraction
|
|
335
|
-
interface PaymentGateway {
|
|
336
|
-
charge(amount: number, token: string): Promise<PaymentResult>;
|
|
337
|
-
refund(transactionId: string): Promise<void>;
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
// Multiple implementations
|
|
341
|
-
class StripeGateway implements PaymentGateway { }
|
|
342
|
-
class PayPalGateway implements PaymentGateway { }
|
|
343
|
-
class MockGateway implements PaymentGateway { } // for testing
|
|
344
|
-
```
|
|
345
|
-
|
|
346
|
-
**High Cohesion in Services**
|
|
347
|
-
|
|
348
|
-
```typescript
|
|
349
|
-
// ✅ Cohesive - All methods relate to order processing
|
|
350
|
-
class OrderService {
|
|
351
|
-
createOrder(cart: Cart, user: User): Order { }
|
|
352
|
-
cancelOrder(orderId: string): void { }
|
|
353
|
-
getOrderStatus(orderId: string): OrderStatus { }
|
|
354
|
-
getOrderHistory(userId: string): Order[] { }
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
// ✅ Cohesive - All methods relate to product catalog
|
|
358
|
-
class ProductService {
|
|
359
|
-
searchProducts(query: string): Product[] { }
|
|
360
|
-
getProductDetails(productId: string): Product { }
|
|
361
|
-
updateInventory(productId: string, quantity: number): void { }
|
|
362
|
-
}
|
|
363
|
-
```
|
|
364
|
-
|
|
365
|
-
### Example 2: Banking Application
|
|
366
|
-
|
|
367
|
-
**Modularity with Bounded Contexts (DDD)**
|
|
368
|
-
|
|
369
|
-
```
|
|
370
|
-
Bounded Contexts:
|
|
371
|
-
├── Account Management
|
|
372
|
-
│ ├── Account Creation
|
|
373
|
-
│ ├── Account Closure
|
|
374
|
-
│ └── Balance Inquiry
|
|
375
|
-
├── Transaction Processing
|
|
376
|
-
│ ├── Deposits
|
|
377
|
-
│ ├── Withdrawals
|
|
378
|
-
│ └── Transfers
|
|
379
|
-
├── Loan Management
|
|
380
|
-
│ ├── Loan Application
|
|
381
|
-
│ ├── Loan Approval
|
|
382
|
-
│ └── Payment Scheduling
|
|
383
|
-
└── Customer Service
|
|
384
|
-
├── Customer Profile
|
|
385
|
-
├── Communication History
|
|
386
|
-
└── Support Tickets
|
|
387
|
-
```
|
|
388
|
-
|
|
389
|
-
**Loose Coupling via Events**
|
|
390
|
-
|
|
391
|
-
```typescript
|
|
392
|
-
// Account service publishes events
|
|
393
|
-
class AccountService {
|
|
394
|
-
createAccount(customer: Customer): Account {
|
|
395
|
-
const account = new Account(customer);
|
|
396
|
-
// ... save account
|
|
397
|
-
this.eventBus.publish('account.created', {
|
|
398
|
-
accountId: account.id,
|
|
399
|
-
customerId: customer.id
|
|
400
|
-
});
|
|
401
|
-
return account;
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
// Other services subscribe to events
|
|
406
|
-
class NotificationService {
|
|
407
|
-
@Subscribe('account.created')
|
|
408
|
-
onAccountCreated(event: AccountCreatedEvent): void {
|
|
409
|
-
this.sendWelcomeEmail(event.customerId);
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
class AuditService {
|
|
414
|
-
@Subscribe('account.created')
|
|
415
|
-
onAccountCreated(event: AccountCreatedEvent): void {
|
|
416
|
-
this.logAccountCreation(event);
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
```
|
|
420
|
-
|
|
421
|
-
---
|
|
422
|
-
|
|
423
|
-
## Understanding
|
|
424
|
-
|
|
425
|
-
### Why Modularity Matters
|
|
426
|
-
|
|
427
|
-
**Cognitive Load Reduction**
|
|
428
|
-
- Humans can only hold 7±2 items in working memory
|
|
429
|
-
- Modules reduce complexity by hiding details
|
|
430
|
-
- Easier to reason about smaller, focused units
|
|
431
|
-
|
|
432
|
-
**Parallel Development**
|
|
433
|
-
- Teams can work on different modules independently
|
|
434
|
-
- Reduces coordination overhead
|
|
435
|
-
- Faster development cycles
|
|
436
|
-
|
|
437
|
-
**Technology Diversity**
|
|
438
|
-
- Different modules can use different technologies
|
|
439
|
-
- Choose best tool for each job
|
|
440
|
-
- Easier to adopt new technologies incrementally
|
|
441
|
-
|
|
442
|
-
### The Coupling-Cohesion Balance
|
|
443
|
-
|
|
444
|
-
**Ideal State**
|
|
445
|
-
- Low coupling between modules
|
|
446
|
-
- High cohesion within modules
|
|
447
|
-
- Modules are independent but internally focused
|
|
448
|
-
|
|
449
|
-
**Trade-offs**
|
|
450
|
-
- Too much decoupling: excessive indirection, complexity
|
|
451
|
-
- Too much coupling: rigid, hard to change
|
|
452
|
-
- Balance depends on context and requirements
|
|
453
|
-
|
|
454
|
-
**Metrics**
|
|
455
|
-
- Coupling: count of dependencies between modules
|
|
456
|
-
- Cohesion: LCOM (Lack of Cohesion of Methods)
|
|
457
|
-
- Tools: SonarQube, NDepend, Structure101
|
|
458
|
-
|
|
459
|
-
### Principles in Practice
|
|
460
|
-
|
|
461
|
-
**Microservices Architecture**
|
|
462
|
-
- Modularity: Each service is independent module
|
|
463
|
-
- Separation: Services separated by business capability
|
|
464
|
-
- Loose Coupling: Services communicate via APIs/events
|
|
465
|
-
- High Cohesion: Each service has single responsibility
|
|
466
|
-
|
|
467
|
-
**Monolithic Architecture**
|
|
468
|
-
- Modularity: Packages/namespaces as modules
|
|
469
|
-
- Separation: Layers separate concerns
|
|
470
|
-
- Loose Coupling: Dependency injection, interfaces
|
|
471
|
-
- High Cohesion: Classes grouped by feature
|
|
472
|
-
|
|
473
|
-
**Serverless Architecture**
|
|
474
|
-
- Modularity: Functions as modules
|
|
475
|
-
- Separation: Functions separated by trigger/purpose
|
|
476
|
-
- Loose Coupling: Event-driven, stateless
|
|
477
|
-
- High Cohesion: Each function does one thing
|
|
478
|
-
|
|
479
|
-
---
|
|
480
|
-
|
|
481
|
-
## Best Practices
|
|
482
|
-
|
|
483
|
-
### Modularity
|
|
484
|
-
|
|
485
|
-
✅ **Define Clear Boundaries**: Explicit module interfaces
|
|
486
|
-
✅ **Minimize Public API**: Expose only what's necessary
|
|
487
|
-
✅ **Version Interfaces**: Support backward compatibility
|
|
488
|
-
✅ **Document Dependencies**: Make dependencies explicit
|
|
489
|
-
❌ **God Modules**: Avoid modules that do everything
|
|
490
|
-
❌ **Circular Dependencies**: Prevent module cycles
|
|
491
|
-
|
|
492
|
-
### Separation of Concerns
|
|
493
|
-
|
|
494
|
-
✅ **Layer Isolation**: Each layer has distinct responsibility
|
|
495
|
-
✅ **Cross-Cutting Concerns**: Use AOP or middleware
|
|
496
|
-
✅ **Feature Slicing**: Organize by business capability
|
|
497
|
-
❌ **Layer Skipping**: Don't bypass layers
|
|
498
|
-
❌ **Leaky Abstractions**: Don't expose implementation details
|
|
499
|
-
|
|
500
|
-
### Coupling and Cohesion
|
|
501
|
-
|
|
502
|
-
✅ **Depend on Abstractions**: Use interfaces, not implementations
|
|
503
|
-
✅ **Event-Driven**: Decouple via events when appropriate
|
|
504
|
-
✅ **Single Responsibility**: One reason to change
|
|
505
|
-
✅ **Feature Envy**: Keep related data and behavior together
|
|
506
|
-
❌ **Tight Coupling**: Avoid direct dependencies
|
|
507
|
-
❌ **Low Cohesion**: Don't mix unrelated functionality
|
|
508
|
-
|
|
509
|
-
---
|
|
510
|
-
|
|
511
|
-
## Common Pitfalls
|
|
512
|
-
|
|
513
|
-
### Over-Modularization
|
|
514
|
-
|
|
515
|
-
**Problem**: Too many small modules
|
|
516
|
-
**Impact**: Excessive complexity, hard to navigate
|
|
517
|
-
**Solution**: Balance granularity with understandability
|
|
518
|
-
|
|
519
|
-
### Under-Modularization
|
|
520
|
-
|
|
521
|
-
**Problem**: Too few large modules
|
|
522
|
-
**Impact**: Hard to maintain, test, and understand
|
|
523
|
-
**Solution**: Apply Single Responsibility Principle
|
|
524
|
-
|
|
525
|
-
### Premature Abstraction
|
|
526
|
-
|
|
527
|
-
**Problem**: Creating abstractions before understanding needs
|
|
528
|
-
**Impact**: Wrong abstractions, unnecessary complexity
|
|
529
|
-
**Solution**: Wait for patterns to emerge (Rule of Three)
|
|
530
|
-
|
|
531
|
-
### Leaky Abstractions
|
|
532
|
-
|
|
533
|
-
**Problem**: Implementation details leak through interfaces
|
|
534
|
-
**Impact**: Tight coupling, hard to change implementations
|
|
535
|
-
**Solution**: Design interfaces based on client needs, not implementation
|
|
536
|
-
|
|
537
|
-
---
|
|
538
|
-
|
|
539
|
-
## References
|
|
540
|
-
|
|
541
|
-
- **Clean Architecture** (Robert C. Martin) - Separation of concerns, dependency rule
|
|
542
|
-
- **Domain-Driven Design** (Eric Evans) - Bounded contexts, modularity
|
|
543
|
-
- **Software Architecture in Practice** (Bass, Clements, Kazman) - Quality attributes
|
|
544
|
-
- **Structured Design** (Stevens, Myers, Constantine) - Coupling and cohesion
|
|
545
|
-
|
|
546
|
-
---
|
|
547
|
-
|
|
548
|
-
## Related Topics
|
|
549
|
-
|
|
550
|
-
- [Fundamentals](./fundamentals.md) - Core architectural elements
|
|
551
|
-
- [Definitions and Terminology](./definitions-terminology.md) - Key concepts
|
|
552
|
-
- [Design Principles](./design-principles.md) - SOLID, DRY, KISS
|
|
553
|
-
- [Microservices Architecture](./microservices.md) - Modularity in practice
|
|
554
|
-
- [Layered Architecture](./layered.md) - Separation of concerns pattern
|
|
555
|
-
|
|
556
|
-
|
|
1
|
+
# Software Architecture Principles
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
This document covers fundamental architectural principles that guide the design of robust, maintainable, and scalable software systems.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Knowledge
|
|
10
|
+
|
|
11
|
+
### Modularity
|
|
12
|
+
|
|
13
|
+
**Definition**
|
|
14
|
+
- Decomposition of system into discrete, independent modules
|
|
15
|
+
- Each module encapsulates specific functionality
|
|
16
|
+
- Modules interact through well-defined interfaces
|
|
17
|
+
- Enables parallel development and independent deployment
|
|
18
|
+
|
|
19
|
+
**Benefits**
|
|
20
|
+
- Easier to understand (smaller, focused units)
|
|
21
|
+
- Easier to test (isolated testing)
|
|
22
|
+
- Easier to maintain (localized changes)
|
|
23
|
+
- Enables reuse (modules as building blocks)
|
|
24
|
+
|
|
25
|
+
**Characteristics of Good Modules**
|
|
26
|
+
- Single, well-defined purpose
|
|
27
|
+
- Clear interface (contract)
|
|
28
|
+
- Information hiding (encapsulation)
|
|
29
|
+
- Minimal dependencies
|
|
30
|
+
|
|
31
|
+
### Separation of Concerns
|
|
32
|
+
|
|
33
|
+
**Definition**
|
|
34
|
+
- Distinct features should be managed by distinct components
|
|
35
|
+
- Each component addresses a specific concern
|
|
36
|
+
- Reduces overlap and interdependencies
|
|
37
|
+
- Examples: presentation vs. business logic vs. data access
|
|
38
|
+
|
|
39
|
+
**Common Separations**
|
|
40
|
+
|
|
41
|
+
**Horizontal Separation (Layering)**
|
|
42
|
+
- Presentation Layer (UI)
|
|
43
|
+
- Business Logic Layer (domain)
|
|
44
|
+
- Data Access Layer (persistence)
|
|
45
|
+
- Infrastructure Layer (cross-cutting)
|
|
46
|
+
|
|
47
|
+
**Vertical Separation (Features)**
|
|
48
|
+
- User Management
|
|
49
|
+
- Product Catalog
|
|
50
|
+
- Order Processing
|
|
51
|
+
- Payment Processing
|
|
52
|
+
|
|
53
|
+
**Cross-Cutting Concerns**
|
|
54
|
+
- Logging
|
|
55
|
+
- Security
|
|
56
|
+
- Caching
|
|
57
|
+
- Error handling
|
|
58
|
+
|
|
59
|
+
### Loose Coupling
|
|
60
|
+
|
|
61
|
+
**Definition**
|
|
62
|
+
- Minimize dependencies between components
|
|
63
|
+
- Components can change independently
|
|
64
|
+
- Reduces ripple effects of changes
|
|
65
|
+
- Enables flexibility and adaptability
|
|
66
|
+
|
|
67
|
+
**Coupling Types (Low to High)**
|
|
68
|
+
|
|
69
|
+
1. **No Coupling**: Components are independent
|
|
70
|
+
2. **Data Coupling**: Share data through parameters
|
|
71
|
+
3. **Stamp Coupling**: Share composite data structures
|
|
72
|
+
4. **Control Coupling**: One component controls another's flow
|
|
73
|
+
5. **Common Coupling**: Share global data
|
|
74
|
+
6. **Content Coupling**: One component modifies another's internals
|
|
75
|
+
|
|
76
|
+
**Achieving Loose Coupling**
|
|
77
|
+
- Dependency injection
|
|
78
|
+
- Interface-based programming
|
|
79
|
+
- Event-driven architecture
|
|
80
|
+
- Message queues
|
|
81
|
+
- API contracts
|
|
82
|
+
|
|
83
|
+
### High Cohesion
|
|
84
|
+
|
|
85
|
+
**Definition**
|
|
86
|
+
- Degree to which elements within a module belong together
|
|
87
|
+
- Related functionality grouped together
|
|
88
|
+
- Unrelated functionality separated
|
|
89
|
+
- Complements loose coupling
|
|
90
|
+
|
|
91
|
+
**Cohesion Types (Low to High)**
|
|
92
|
+
|
|
93
|
+
1. **Coincidental**: Random grouping (worst)
|
|
94
|
+
2. **Logical**: Similar operations grouped
|
|
95
|
+
3. **Temporal**: Operations performed at same time
|
|
96
|
+
4. **Procedural**: Operations in sequence
|
|
97
|
+
5. **Communicational**: Operate on same data
|
|
98
|
+
6. **Sequential**: Output of one is input to another
|
|
99
|
+
7. **Functional**: All elements contribute to single task (best)
|
|
100
|
+
|
|
101
|
+
**Achieving High Cohesion**
|
|
102
|
+
- Single Responsibility Principle
|
|
103
|
+
- Domain-Driven Design
|
|
104
|
+
- Feature-based organization
|
|
105
|
+
- Clear module boundaries
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## Skills
|
|
110
|
+
|
|
111
|
+
### Applying Modularity
|
|
112
|
+
|
|
113
|
+
**Module Identification Process**
|
|
114
|
+
|
|
115
|
+
1. **Identify Responsibilities**: List system capabilities
|
|
116
|
+
2. **Group Related Responsibilities**: Cluster by domain/function
|
|
117
|
+
3. **Define Module Boundaries**: Establish clear interfaces
|
|
118
|
+
4. **Minimize Dependencies**: Reduce inter-module coupling
|
|
119
|
+
5. **Validate**: Ensure each module has single, clear purpose
|
|
120
|
+
|
|
121
|
+
**Module Design Checklist**
|
|
122
|
+
|
|
123
|
+
✅ Does module have single, well-defined purpose?
|
|
124
|
+
✅ Can module be understood independently?
|
|
125
|
+
✅ Can module be tested in isolation?
|
|
126
|
+
✅ Does module hide implementation details?
|
|
127
|
+
✅ Are module dependencies minimal and explicit?
|
|
128
|
+
|
|
129
|
+
### Implementing Separation of Concerns
|
|
130
|
+
|
|
131
|
+
**Layered Architecture Example**
|
|
132
|
+
|
|
133
|
+
```
|
|
134
|
+
┌─────────────────────────────────┐
|
|
135
|
+
│ Presentation Layer │ ← UI, Controllers, Views
|
|
136
|
+
├─────────────────────────────────┤
|
|
137
|
+
│ Business Logic Layer │ ← Domain Models, Services
|
|
138
|
+
├─────────────────────────────────┤
|
|
139
|
+
│ Data Access Layer │ ← Repositories, ORM
|
|
140
|
+
├─────────────────────────────────┤
|
|
141
|
+
│ Infrastructure Layer │ ← Logging, Config, Security
|
|
142
|
+
└─────────────────────────────────┘
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
**Layer Responsibilities**
|
|
146
|
+
|
|
147
|
+
**Presentation**: User interaction, input validation, display
|
|
148
|
+
**Business Logic**: Business rules, workflows, domain logic
|
|
149
|
+
**Data Access**: CRUD operations, queries, persistence
|
|
150
|
+
**Infrastructure**: Cross-cutting concerns, utilities
|
|
151
|
+
|
|
152
|
+
**Layer Rules**
|
|
153
|
+
|
|
154
|
+
✅ Upper layers depend on lower layers
|
|
155
|
+
✅ Lower layers don't know about upper layers
|
|
156
|
+
✅ Each layer has clear responsibility
|
|
157
|
+
❌ Skip layers (presentation → data access directly)
|
|
158
|
+
❌ Circular dependencies between layers
|
|
159
|
+
|
|
160
|
+
### Reducing Coupling
|
|
161
|
+
|
|
162
|
+
**Dependency Injection Pattern**
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
// ❌ Tight Coupling
|
|
166
|
+
class OrderService {
|
|
167
|
+
private paymentGateway = new StripePaymentGateway();
|
|
168
|
+
|
|
169
|
+
processOrder(order: Order) {
|
|
170
|
+
this.paymentGateway.charge(order.total);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// ✅ Loose Coupling
|
|
175
|
+
interface PaymentGateway {
|
|
176
|
+
charge(amount: number): Promise<void>;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
class OrderService {
|
|
180
|
+
constructor(private paymentGateway: PaymentGateway) {}
|
|
181
|
+
|
|
182
|
+
processOrder(order: Order) {
|
|
183
|
+
this.paymentGateway.charge(order.total);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
**Event-Driven Decoupling**
|
|
189
|
+
|
|
190
|
+
```typescript
|
|
191
|
+
// ❌ Direct Coupling
|
|
192
|
+
class OrderService {
|
|
193
|
+
constructor(
|
|
194
|
+
private inventoryService: InventoryService,
|
|
195
|
+
private emailService: EmailService
|
|
196
|
+
) {}
|
|
197
|
+
|
|
198
|
+
createOrder(order: Order) {
|
|
199
|
+
// ... create order
|
|
200
|
+
this.inventoryService.decrementStock(order.items);
|
|
201
|
+
this.emailService.sendConfirmation(order);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// ✅ Event-Driven Decoupling
|
|
206
|
+
class OrderService {
|
|
207
|
+
constructor(private eventBus: EventBus) {}
|
|
208
|
+
|
|
209
|
+
createOrder(order: Order) {
|
|
210
|
+
// ... create order
|
|
211
|
+
this.eventBus.publish('order.created', order);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### Increasing Cohesion
|
|
217
|
+
|
|
218
|
+
**Functional Cohesion Example**
|
|
219
|
+
|
|
220
|
+
```typescript
|
|
221
|
+
// ❌ Low Cohesion (Coincidental)
|
|
222
|
+
class Utilities {
|
|
223
|
+
formatDate(date: Date): string { }
|
|
224
|
+
sendEmail(to: string, body: string): void { }
|
|
225
|
+
calculateTax(amount: number): number { }
|
|
226
|
+
validatePassword(password: string): boolean { }
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// ✅ High Cohesion (Functional)
|
|
230
|
+
class DateFormatter {
|
|
231
|
+
format(date: Date): string { }
|
|
232
|
+
parse(dateString: string): Date { }
|
|
233
|
+
isValid(dateString: string): boolean { }
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
class EmailService {
|
|
237
|
+
send(to: string, subject: string, body: string): void { }
|
|
238
|
+
sendBulk(recipients: string[], subject: string, body: string): void { }
|
|
239
|
+
validateEmail(email: string): boolean { }
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
class TaxCalculator {
|
|
243
|
+
calculate(amount: number, region: string): number { }
|
|
244
|
+
getRate(region: string): number { }
|
|
245
|
+
applyExemptions(amount: number, exemptions: string[]): number { }
|
|
246
|
+
}
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
**Domain-Driven Cohesion**
|
|
250
|
+
|
|
251
|
+
```typescript
|
|
252
|
+
// ✅ High Cohesion - Order Aggregate
|
|
253
|
+
class Order {
|
|
254
|
+
private items: OrderItem[] = [];
|
|
255
|
+
private status: OrderStatus = 'pending';
|
|
256
|
+
|
|
257
|
+
addItem(product: Product, quantity: number): void {
|
|
258
|
+
// Related to order management
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
removeItem(productId: string): void {
|
|
262
|
+
// Related to order management
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
calculateTotal(): number {
|
|
266
|
+
// Related to order management
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
submit(): void {
|
|
270
|
+
// Related to order lifecycle
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
cancel(): void {
|
|
274
|
+
// Related to order lifecycle
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
---
|
|
280
|
+
|
|
281
|
+
## Examples
|
|
282
|
+
|
|
283
|
+
### Example 1: E-Commerce System Architecture
|
|
284
|
+
|
|
285
|
+
**Modularity Applied**
|
|
286
|
+
|
|
287
|
+
```
|
|
288
|
+
Modules:
|
|
289
|
+
├── User Management
|
|
290
|
+
│ ├── Authentication
|
|
291
|
+
│ ├── Authorization
|
|
292
|
+
│ └── Profile Management
|
|
293
|
+
├── Product Catalog
|
|
294
|
+
│ ├── Product Search
|
|
295
|
+
│ ├── Category Management
|
|
296
|
+
│ └── Inventory Tracking
|
|
297
|
+
├── Shopping Cart
|
|
298
|
+
│ ├── Cart Operations
|
|
299
|
+
│ └── Session Management
|
|
300
|
+
└── Order Processing
|
|
301
|
+
├── Order Creation
|
|
302
|
+
├── Payment Processing
|
|
303
|
+
└── Order Fulfillment
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
**Separation of Concerns**
|
|
307
|
+
|
|
308
|
+
```
|
|
309
|
+
Presentation Layer:
|
|
310
|
+
- Web UI (React)
|
|
311
|
+
- Mobile App (React Native)
|
|
312
|
+
- Admin Dashboard
|
|
313
|
+
|
|
314
|
+
Business Logic Layer:
|
|
315
|
+
- Order Service
|
|
316
|
+
- Product Service
|
|
317
|
+
- User Service
|
|
318
|
+
- Payment Service
|
|
319
|
+
|
|
320
|
+
Data Access Layer:
|
|
321
|
+
- Order Repository
|
|
322
|
+
- Product Repository
|
|
323
|
+
- User Repository
|
|
324
|
+
|
|
325
|
+
Infrastructure:
|
|
326
|
+
- Logging (Winston)
|
|
327
|
+
- Caching (Redis)
|
|
328
|
+
- Authentication (JWT)
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
**Loose Coupling via Interfaces**
|
|
332
|
+
|
|
333
|
+
```typescript
|
|
334
|
+
// Payment abstraction
|
|
335
|
+
interface PaymentGateway {
|
|
336
|
+
charge(amount: number, token: string): Promise<PaymentResult>;
|
|
337
|
+
refund(transactionId: string): Promise<void>;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// Multiple implementations
|
|
341
|
+
class StripeGateway implements PaymentGateway { }
|
|
342
|
+
class PayPalGateway implements PaymentGateway { }
|
|
343
|
+
class MockGateway implements PaymentGateway { } // for testing
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
**High Cohesion in Services**
|
|
347
|
+
|
|
348
|
+
```typescript
|
|
349
|
+
// ✅ Cohesive - All methods relate to order processing
|
|
350
|
+
class OrderService {
|
|
351
|
+
createOrder(cart: Cart, user: User): Order { }
|
|
352
|
+
cancelOrder(orderId: string): void { }
|
|
353
|
+
getOrderStatus(orderId: string): OrderStatus { }
|
|
354
|
+
getOrderHistory(userId: string): Order[] { }
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// ✅ Cohesive - All methods relate to product catalog
|
|
358
|
+
class ProductService {
|
|
359
|
+
searchProducts(query: string): Product[] { }
|
|
360
|
+
getProductDetails(productId: string): Product { }
|
|
361
|
+
updateInventory(productId: string, quantity: number): void { }
|
|
362
|
+
}
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
### Example 2: Banking Application
|
|
366
|
+
|
|
367
|
+
**Modularity with Bounded Contexts (DDD)**
|
|
368
|
+
|
|
369
|
+
```
|
|
370
|
+
Bounded Contexts:
|
|
371
|
+
├── Account Management
|
|
372
|
+
│ ├── Account Creation
|
|
373
|
+
│ ├── Account Closure
|
|
374
|
+
│ └── Balance Inquiry
|
|
375
|
+
├── Transaction Processing
|
|
376
|
+
│ ├── Deposits
|
|
377
|
+
│ ├── Withdrawals
|
|
378
|
+
│ └── Transfers
|
|
379
|
+
├── Loan Management
|
|
380
|
+
│ ├── Loan Application
|
|
381
|
+
│ ├── Loan Approval
|
|
382
|
+
│ └── Payment Scheduling
|
|
383
|
+
└── Customer Service
|
|
384
|
+
├── Customer Profile
|
|
385
|
+
├── Communication History
|
|
386
|
+
└── Support Tickets
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
**Loose Coupling via Events**
|
|
390
|
+
|
|
391
|
+
```typescript
|
|
392
|
+
// Account service publishes events
|
|
393
|
+
class AccountService {
|
|
394
|
+
createAccount(customer: Customer): Account {
|
|
395
|
+
const account = new Account(customer);
|
|
396
|
+
// ... save account
|
|
397
|
+
this.eventBus.publish('account.created', {
|
|
398
|
+
accountId: account.id,
|
|
399
|
+
customerId: customer.id
|
|
400
|
+
});
|
|
401
|
+
return account;
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
// Other services subscribe to events
|
|
406
|
+
class NotificationService {
|
|
407
|
+
@Subscribe('account.created')
|
|
408
|
+
onAccountCreated(event: AccountCreatedEvent): void {
|
|
409
|
+
this.sendWelcomeEmail(event.customerId);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
class AuditService {
|
|
414
|
+
@Subscribe('account.created')
|
|
415
|
+
onAccountCreated(event: AccountCreatedEvent): void {
|
|
416
|
+
this.logAccountCreation(event);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
---
|
|
422
|
+
|
|
423
|
+
## Understanding
|
|
424
|
+
|
|
425
|
+
### Why Modularity Matters
|
|
426
|
+
|
|
427
|
+
**Cognitive Load Reduction**
|
|
428
|
+
- Humans can only hold 7±2 items in working memory
|
|
429
|
+
- Modules reduce complexity by hiding details
|
|
430
|
+
- Easier to reason about smaller, focused units
|
|
431
|
+
|
|
432
|
+
**Parallel Development**
|
|
433
|
+
- Teams can work on different modules independently
|
|
434
|
+
- Reduces coordination overhead
|
|
435
|
+
- Faster development cycles
|
|
436
|
+
|
|
437
|
+
**Technology Diversity**
|
|
438
|
+
- Different modules can use different technologies
|
|
439
|
+
- Choose best tool for each job
|
|
440
|
+
- Easier to adopt new technologies incrementally
|
|
441
|
+
|
|
442
|
+
### The Coupling-Cohesion Balance
|
|
443
|
+
|
|
444
|
+
**Ideal State**
|
|
445
|
+
- Low coupling between modules
|
|
446
|
+
- High cohesion within modules
|
|
447
|
+
- Modules are independent but internally focused
|
|
448
|
+
|
|
449
|
+
**Trade-offs**
|
|
450
|
+
- Too much decoupling: excessive indirection, complexity
|
|
451
|
+
- Too much coupling: rigid, hard to change
|
|
452
|
+
- Balance depends on context and requirements
|
|
453
|
+
|
|
454
|
+
**Metrics**
|
|
455
|
+
- Coupling: count of dependencies between modules
|
|
456
|
+
- Cohesion: LCOM (Lack of Cohesion of Methods)
|
|
457
|
+
- Tools: SonarQube, NDepend, Structure101
|
|
458
|
+
|
|
459
|
+
### Principles in Practice
|
|
460
|
+
|
|
461
|
+
**Microservices Architecture**
|
|
462
|
+
- Modularity: Each service is independent module
|
|
463
|
+
- Separation: Services separated by business capability
|
|
464
|
+
- Loose Coupling: Services communicate via APIs/events
|
|
465
|
+
- High Cohesion: Each service has single responsibility
|
|
466
|
+
|
|
467
|
+
**Monolithic Architecture**
|
|
468
|
+
- Modularity: Packages/namespaces as modules
|
|
469
|
+
- Separation: Layers separate concerns
|
|
470
|
+
- Loose Coupling: Dependency injection, interfaces
|
|
471
|
+
- High Cohesion: Classes grouped by feature
|
|
472
|
+
|
|
473
|
+
**Serverless Architecture**
|
|
474
|
+
- Modularity: Functions as modules
|
|
475
|
+
- Separation: Functions separated by trigger/purpose
|
|
476
|
+
- Loose Coupling: Event-driven, stateless
|
|
477
|
+
- High Cohesion: Each function does one thing
|
|
478
|
+
|
|
479
|
+
---
|
|
480
|
+
|
|
481
|
+
## Best Practices
|
|
482
|
+
|
|
483
|
+
### Modularity
|
|
484
|
+
|
|
485
|
+
✅ **Define Clear Boundaries**: Explicit module interfaces
|
|
486
|
+
✅ **Minimize Public API**: Expose only what's necessary
|
|
487
|
+
✅ **Version Interfaces**: Support backward compatibility
|
|
488
|
+
✅ **Document Dependencies**: Make dependencies explicit
|
|
489
|
+
❌ **God Modules**: Avoid modules that do everything
|
|
490
|
+
❌ **Circular Dependencies**: Prevent module cycles
|
|
491
|
+
|
|
492
|
+
### Separation of Concerns
|
|
493
|
+
|
|
494
|
+
✅ **Layer Isolation**: Each layer has distinct responsibility
|
|
495
|
+
✅ **Cross-Cutting Concerns**: Use AOP or middleware
|
|
496
|
+
✅ **Feature Slicing**: Organize by business capability
|
|
497
|
+
❌ **Layer Skipping**: Don't bypass layers
|
|
498
|
+
❌ **Leaky Abstractions**: Don't expose implementation details
|
|
499
|
+
|
|
500
|
+
### Coupling and Cohesion
|
|
501
|
+
|
|
502
|
+
✅ **Depend on Abstractions**: Use interfaces, not implementations
|
|
503
|
+
✅ **Event-Driven**: Decouple via events when appropriate
|
|
504
|
+
✅ **Single Responsibility**: One reason to change
|
|
505
|
+
✅ **Feature Envy**: Keep related data and behavior together
|
|
506
|
+
❌ **Tight Coupling**: Avoid direct dependencies
|
|
507
|
+
❌ **Low Cohesion**: Don't mix unrelated functionality
|
|
508
|
+
|
|
509
|
+
---
|
|
510
|
+
|
|
511
|
+
## Common Pitfalls
|
|
512
|
+
|
|
513
|
+
### Over-Modularization
|
|
514
|
+
|
|
515
|
+
**Problem**: Too many small modules
|
|
516
|
+
**Impact**: Excessive complexity, hard to navigate
|
|
517
|
+
**Solution**: Balance granularity with understandability
|
|
518
|
+
|
|
519
|
+
### Under-Modularization
|
|
520
|
+
|
|
521
|
+
**Problem**: Too few large modules
|
|
522
|
+
**Impact**: Hard to maintain, test, and understand
|
|
523
|
+
**Solution**: Apply Single Responsibility Principle
|
|
524
|
+
|
|
525
|
+
### Premature Abstraction
|
|
526
|
+
|
|
527
|
+
**Problem**: Creating abstractions before understanding needs
|
|
528
|
+
**Impact**: Wrong abstractions, unnecessary complexity
|
|
529
|
+
**Solution**: Wait for patterns to emerge (Rule of Three)
|
|
530
|
+
|
|
531
|
+
### Leaky Abstractions
|
|
532
|
+
|
|
533
|
+
**Problem**: Implementation details leak through interfaces
|
|
534
|
+
**Impact**: Tight coupling, hard to change implementations
|
|
535
|
+
**Solution**: Design interfaces based on client needs, not implementation
|
|
536
|
+
|
|
537
|
+
---
|
|
538
|
+
|
|
539
|
+
## References
|
|
540
|
+
|
|
541
|
+
- **Clean Architecture** (Robert C. Martin) - Separation of concerns, dependency rule
|
|
542
|
+
- **Domain-Driven Design** (Eric Evans) - Bounded contexts, modularity
|
|
543
|
+
- **Software Architecture in Practice** (Bass, Clements, Kazman) - Quality attributes
|
|
544
|
+
- **Structured Design** (Stevens, Myers, Constantine) - Coupling and cohesion
|
|
545
|
+
|
|
546
|
+
---
|
|
547
|
+
|
|
548
|
+
## Related Topics
|
|
549
|
+
|
|
550
|
+
- [Fundamentals](./fundamentals.md) - Core architectural elements
|
|
551
|
+
- [Definitions and Terminology](./definitions-terminology.md) - Key concepts
|
|
552
|
+
- [Design Principles](./design-principles.md) - SOLID, DRY, KISS
|
|
553
|
+
- [Microservices Architecture](./microservices.md) - Modularity in practice
|
|
554
|
+
- [Layered Architecture](./layered.md) - Separation of concerns pattern
|
|
555
|
+
|
|
556
|
+
|