Hexagonal Mimari Nedir? Ports & Adapters Rehberi
Veritabanını değiştirmek tüm uygulamayı mı etkiliyor? Framework'e kilitlenmiş misiniz? Hexagonal Architecture ile iş mantığınızı dış dünyadan izole edin, test edilebilir ve değiştirilebilir hale getirin.
Hexagonal Mimari Tanımı
Hexagonal Architecture (Altıgen Mimari), Alistair Cockburn tarafından 2005'te tanımlanan bir mimari desendir. Ports & Adapters olarak da bilinir. Temel fikir: İş mantığını (domain) merkeze koyun, dış bağımlılıkları (DB, API, UI) çevre adaptörlerine taşıyın.
┌──────────────────────┐
│ Adapters │
│ ┌────────────────┐ │
│ │ Ports │ │
│ │ ┌──────────┐ │ │
Input ──►│ │ │ Domain │ │ │──► Output
│ │ │ (Core) │ │ │
│ │ └──────────┘ │ │
│ └────────────────┘ │
└──────────────────────┘
Neden Hexagonal?
Geleneksel Katmanlı Mimari Sorunları
Controller → Service → Repository → Database
↓ ↓ ↓
Framework Business DB Logic
kilitli karışık bağımlı
Hexagonal Çözümü
HTTP Adapter → [Port] → Domain Logic → [Port] → DB Adapter
REST/GraphQL PostgreSQL/MongoDB
- Domain katmanı hiçbir dış bağımlılığa sahip değildir
- Adaptörler değiştirilebilir (PostgreSQL → MongoDB, REST → GraphQL)
- Test edilmesi kolay — domain'i izole test edin
Temel Kavramlar
Domain (Core)
İş kurallarınız. Hiçbir framework, DB veya HTTP kavramı içermez.
Port
Domain'in dış dünya ile iletişim kurmak için tanımladığı arayüz (interface).
Adapter
Port arayüzünü gerçekleştiren somut uygulama.
Pratik Örnek: Sipariş Sistemi
Port (Interface)
// domain/ports/OrderRepository.ts
interface OrderRepository {
save(order: Order): Promise<void>;
findById(id: string): Promise<Order | null>;
findByCustomer(customerId: string): Promise<Order[]>;
}
// domain/ports/PaymentGateway.ts
interface PaymentGateway {
charge(amount: number, token: string): Promise<PaymentResult>;
}
// domain/ports/NotificationService.ts
interface NotificationService {
sendOrderConfirmation(order: Order): Promise<void>;
}
Domain (Core Logic)
// domain/services/OrderService.ts
class OrderService {
constructor(
private orderRepo: OrderRepository,
private payment: PaymentGateway,
private notification: NotificationService
) {}
async createOrder(items: Item[], paymentToken: string): Promise<Order> {
const order = Order.create(items);
const result = await this.payment.charge(order.total, paymentToken);
if (!result.success) throw new PaymentError(result.error);
order.markAsPaid(result.transactionId);
await this.orderRepo.save(order);
await this.notification.sendOrderConfirmation(order);
return order;
}
}
Adapter (Infrastructure)
// adapters/PostgresOrderRepository.ts
class PostgresOrderRepository implements OrderRepository {
async save(order: Order): Promise<void> {
await db.query('INSERT INTO orders ...', [order.id, order.total]);
}
async findById(id: string): Promise<Order | null> {
const row = await db.query('SELECT * FROM orders WHERE id = $1', [id]);
return row ? Order.fromRow(row) : null;
}
}
// adapters/StripePaymentGateway.ts
class StripePaymentGateway implements PaymentGateway {
async charge(amount: number, token: string): Promise<PaymentResult> {
const result = await stripe.charges.create({ amount, source: token });
return { success: true, transactionId: result.id };
}
}
Hexagonal vs Diğer Mimariler
| Özellik | Katmanlı | Hexagonal | Clean Architecture | |---------|----------|-----------|-------------------| | Domain izolasyonu | Zayıf | Güçlü | Güçlü | | Test edilebilirlik | Orta | Yüksek | Yüksek | | Karmaşıklık | Düşük | Orta | Yüksek | | DB bağımsızlığı | Düşük | Yüksek | Yüksek | | Öğrenme eğrisi | Düşük | Orta | Yüksek |
Best Practices
- Dependency Rule — Bağımlılık her zaman dıştan içe doğru olmalı
- Domain'de framework kullanmayın — Saf TypeScript/Java/Python
- Port'ları küçük tutun — Interface Segregation prensibini uygulayın
- Adapter'ları kolayca değiştirilebilir yapın — Dependency Injection kullanın
- Domain event'leri kullanın — Yan etkileri decouple edin
Sonuç
Hexagonal Architecture, iş mantığınızı teknik detaylardan izole ederek sürdürülebilir, test edilebilir ve esnek bir mimari sunar. Karmaşıklık maliyeti vardır, ama orta-büyük projeler için uzun vadede karşılığını fazlasıyla verir.
Hexagonal mimariyi LabLudus platformunda interaktif görevlerle öğrenin.