ai-factory.architecture
1
总安装量
1
周安装量
#78060
全站排名
安装命令
npx skills add https://github.com/lee-to/ai-factory --skill ai-factory.architecture
Agent 安装分布
windsurf
1
opencode
1
cursor
1
codex
1
claude-code
1
antigravity
1
Skill 文档
Architecture Patterns Guide
Practical guidelines for software architecture decisions.
Quick Reference
/ai-factory.architectureâ Overview and decision guide/ai-factory.architecture cleanâ Clean Architecture/ai-factory.architecture dddâ Domain-Driven Design/ai-factory.architecture microservicesâ Microservices patterns/ai-factory.architecture monolithâ Modular monolith/ai-factory.architecture layersâ Layered architecture
Choosing an Architecture
Decision Matrix
| Factor | Monolith | Modular Monolith | Microservices |
|---|---|---|---|
| Team size | 1-10 | 5-30 | 20+ |
| Domain complexity | Low-Medium | Medium-High | High |
| Scale requirements | Moderate | Moderate-High | Very High |
| Deploy independence | â | Partial | â |
| Initial velocity | â Fast | â Fast | â Slow |
| Operational complexity | â Low | â Low | â High |
Start Here
New project? â Start with Modular Monolith
â
Growing team + clear domain boundaries? â Extract to Microservices
â
Single team + unclear boundaries? â Stay Monolith, refine modules
Clean Architecture
Core Principle
Dependencies point inward. Inner layers know nothing about outer layers.
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â Frameworks & Drivers â
â âââââââââââââââââââââââââââââââââââââââââââââââââââ â
â â Interface Adapters â â
â â âââââââââââââââââââââââââââââââââââââââââââ â â
â â â Application Layer â â â
â â â âââââââââââââââââââââââââââââââââââ â â â
â â â â Domain Layer â â â â
â â â â (Entities & Business Rules) â â â â
â â â âââââââââââââââââââââââââââââââââââ â â â
â â âââââââââââââââââââââââââââââââââââââââââââ â â
â âââââââââââââââââââââââââââââââââââââââââââââââââââ â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
Folder Structure
src/
âââ domain/ # Core business logic (no dependencies)
â âââ entities/
â â âââ User.ts
â âââ value-objects/
â â âââ Email.ts
â âââ repositories/ # Interfaces only
â âââ IUserRepository.ts
â
âââ application/ # Use cases (depends on domain)
â âââ use-cases/
â â âââ CreateUser.ts
â â âââ GetUserById.ts
â âââ services/
â âââ AuthService.ts
â
âââ infrastructure/ # External concerns (implements interfaces)
â âââ database/
â â âââ PrismaUserRepository.ts
â âââ external/
â â âââ StripePaymentGateway.ts
â âââ config/
â
âââ presentation/ # UI/API layer
âââ api/
â âââ routes/
âââ controllers/
âââ dto/
Dependency Rule Example
// â
domain/repositories/IUserRepository.ts (interface)
interface IUserRepository {
findById(id: string): Promise<User | null>;
save(user: User): Promise<void>;
}
// â
infrastructure/database/PrismaUserRepository.ts (implementation)
class PrismaUserRepository implements IUserRepository {
constructor(private prisma: PrismaClient) {}
async findById(id: string): Promise<User | null> {
const data = await this.prisma.user.findUnique({ where: { id } });
return data ? User.fromPersistence(data) : null;
}
}
// â
application/use-cases/GetUserById.ts (depends on interface)
class GetUserById {
constructor(private userRepo: IUserRepository) {}
async execute(id: string): Promise<User> {
const user = await this.userRepo.findById(id);
if (!user) throw new UserNotFoundError(id);
return user;
}
}
Domain-Driven Design (DDD)
Strategic Patterns
Bounded Contexts: Explicit boundaries around domain models
âââââââââââââââââââ âââââââââââââââââââ âââââââââââââââââââ
â Ordering â â Inventory â â Shipping â
â Context ââââââ¶â Context ââââââ¶â Context â
â â â â â â
â Order â â Product â â Shipment â
â OrderLine â â Stock â â Carrier â
â Customer â â Warehouse â â TrackingInfo â
âââââââââââââââââââ âââââââââââââââââââ âââââââââââââââââââ
Context Mapping: How contexts communicate
- Shared Kernel: Common code between contexts
- Customer/Supplier: Upstream/downstream relationship
- Anti-Corruption Layer: Translation between contexts
Tactical Patterns
Entities: Identity-based objects
class Order {
constructor(
public readonly id: OrderId,
private items: OrderItem[],
private status: OrderStatus
) {}
addItem(product: Product, quantity: number): void {
if (this.status !== 'draft') {
throw new Error('Cannot modify confirmed order');
}
this.items.push(new OrderItem(product, quantity));
}
}
Value Objects: Immutable, equality by value
class Money {
constructor(
public readonly amount: number,
public readonly currency: string
) {
if (amount < 0) throw new Error('Amount cannot be negative');
}
add(other: Money): Money {
if (this.currency !== other.currency) {
throw new Error('Currency mismatch');
}
return new Money(this.amount + other.amount, this.currency);
}
equals(other: Money): boolean {
return this.amount === other.amount && this.currency === other.currency;
}
}
Aggregates: Consistency boundaries
// Order is the Aggregate Root
// OrderItems can only be modified through Order
class Order {
private items: OrderItem[] = [];
// All invariants enforced here
addItem(item: OrderItem): void {
if (this.items.length >= 100) {
throw new Error('Order cannot have more than 100 items');
}
this.items.push(item);
}
}
Domain Events: Communicate state changes
class OrderPlaced implements DomainEvent {
constructor(
public readonly orderId: string,
public readonly customerId: string,
public readonly occurredAt: Date = new Date()
) {}
}
// Usage
order.place();
eventBus.publish(new OrderPlaced(order.id, order.customerId));
Microservices Patterns
When to Use
- â Large teams needing independent deployment
- â Different scaling requirements per service
- â Polyglot persistence needs
- â Small team (< 10 people)
- â Unclear domain boundaries
- â Startups exploring product-market fit
Service Boundaries
â
Good boundaries:
- User Service (authentication, profiles)
- Order Service (order lifecycle)
- Payment Service (transactions, refunds)
- Notification Service (email, SMS, push)
â Bad boundaries:
- Database Service (too technical)
- Validation Service (too generic)
- Utils Service (not a domain)
Communication Patterns
Synchronous (HTTP/gRPC)
Order Service ââHTTPâââ¶ Inventory Service
"Check stock for product X"
Use for: Queries, real-time validation
Asynchronous (Events/Messages)
Order Service ââEventâââ¶ Message Broker âââ¶ Notification Service
"OrderPlaced" (sends email)
Use for: Side effects, eventual consistency
Data Patterns
Database per Service
âââââââââââââââ âââââââââââââââ âââââââââââââââ
â Orders â â Inventory â â Payments â
â Service â â Service â â Service â
ââââââââ¬âââââââ ââââââââ¬âââââââ ââââââââ¬âââââââ
â â â
âââââ¼ââââ âââââ¼ââââ âââââ¼ââââ
â PostgreSQL â MongoDB â â PostgreSQL
âââââââââ âââââââââ âââââââââ
Saga Pattern for distributed transactions
Order Saga:
1. Create Order (Orders Service)
2. Reserve Inventory (Inventory Service)
3. Process Payment (Payment Service)
4. Confirm Order (Orders Service)
If step fails â Compensate previous steps
Modular Monolith
Best of Both Worlds
- Single deployment unit (simple ops)
- Strong module boundaries (future extraction ready)
- Shared database with logical separation
Structure
src/
âââ modules/
â âââ users/
â â âââ api/ # HTTP handlers
â â âââ domain/ # Business logic
â â âââ infra/ # Database, external
â â âââ index.ts # Public API only
â â
â âââ orders/
â â âââ api/
â â âââ domain/
â â âââ infra/
â â âââ index.ts
â â
â âââ payments/
â âââ ...
â
âââ shared/ # Truly shared code
â âââ kernel/ # Base classes, interfaces
â âââ utils/ # Pure utilities
â
âââ main.ts # Composition root
Module Communication Rules
// â
Good: Module exposes explicit public API
// modules/users/index.ts
export { UserService } from './domain/UserService';
export { User } from './domain/User';
export type { CreateUserDTO } from './api/dto';
// â
Good: Other modules use public API
import { UserService } from '@/modules/users';
// â Bad: Reaching into module internals
import { UserRepository } from '@/modules/users/infra/UserRepository';
Quick Decision Guide
Q: New greenfield project?
A: Start with Modular Monolith
Q: Existing messy codebase?
A: Apply Clean Architecture gradually
Q: Team > 50 engineers?
A: Consider Microservices with clear domain boundaries
Q: Need to scale one component independently?
A: Extract that component as a service
Q: Unclear requirements?
A: Keep it simple, refactor when patterns emerge