Tasarım Desenleri Rehberi: En Çok Kullanılan 10 Design Pattern
Tasarım desenleri, yazılım dünyasının kanıtlanmış çözümleridir. Gang of Four (GoF) tarafından 1994'te kataloglanan bu desenler, bugün hâlâ modern yazılım geliştirmenin temel taşlarıdır.
Tasarım Deseni Nedir?
Tasarım deseni, yazılım tasarımında sık karşılaşılan problemlere verilen tekrar kullanılabilir, kanıtlanmış çözümlerdir. Hazır kod değil, bir çözüm şablonudur.
Üç Kategori
| Kategori | Amaç | Örnekler | |----------|------|----------| | Creational | Nesne oluşturma | Factory, Singleton, Builder | | Structural | Nesne yapılandırma | Adapter, Decorator, Facade | | Behavioral | Nesne davranışı | Observer, Strategy, Command |
Creational Patterns (Oluşturucu Desenler)
1. Factory Method
Nesne oluşturma mantığını alt sınıflara devreder:
interface Notification {
send(message: string): void;
}
class EmailNotification implements Notification {
send(message: string) { /* e-posta gönder */ }
}
class SMSNotification implements Notification {
send(message: string) { /* SMS gönder */ }
}
function createNotification(type: string): Notification {
switch(type) {
case 'email': return new EmailNotification();
case 'sms': return new SMSNotification();
default: throw new Error('Bilinmeyen tür');
}
}
2. Singleton
Bir sınıftan yalnızca tek bir instance oluşturulmasını garanti eder:
class DatabaseConnection {
private static instance: DatabaseConnection;
private constructor() {}
static getInstance(): DatabaseConnection {
if (!DatabaseConnection.instance) {
DatabaseConnection.instance = new DatabaseConnection();
}
return DatabaseConnection.instance;
}
}
3. Builder
Karmaşık nesneleri adım adım oluşturur:
const order = new OrderBuilder()
.setCustomer('Ali')
.addItem('Laptop', 15000)
.addItem('Mouse', 200)
.setShipping('express')
.build();
Structural Patterns (Yapısal Desenler)
4. Adapter
Uyumsuz arayüzleri birbirine uyumlu hale getirir:
// Eski ödeme sistemi
class OldPaymentSystem {
processPayment(amount: number) { /* ... */ }
}
// Yeni arayüz
interface ModernPayment {
pay(amount: number, currency: string): Promise<boolean>;
}
// Adapter
class PaymentAdapter implements ModernPayment {
constructor(private oldSystem: OldPaymentSystem) {}
async pay(amount: number, currency: string) {
this.oldSystem.processPayment(amount);
return true;
}
}
5. Decorator
Mevcut nesneye yeni davranışlar ekler:
// Temel logger
class Logger {
log(message: string) { console.log(message); }
}
// Timestamp ekleyen decorator
class TimestampLogger extends Logger {
log(message: string) {
super.log(`[${new Date().toISOString()}] ${message}`);
}
}
6. Facade
Karmaşık alt sistemleri basit bir arayüzün arkasına gizler:
class OrderFacade {
async placeOrder(cart: Cart) {
await inventory.reserve(cart.items);
const payment = await paymentService.charge(cart.total);
await shippingService.schedule(cart.address);
await notificationService.sendConfirmation(cart.customer);
return { orderId: generateId(), payment, status: 'confirmed' };
}
}
Behavioral Patterns (Davranışsal Desenler)
7. Observer
Bir nesnedeki değişikliği, ona abone olan nesnelere otomatik bildirir:
class EventEmitter {
private listeners: Map<string, Function[]> = new Map();
on(event: string, callback: Function) {
const list = this.listeners.get(event) || [];
list.push(callback);
this.listeners.set(event, list);
}
emit(event: string, data: any) {
this.listeners.get(event)?.forEach(cb => cb(data));
}
}
8. Strategy
Algoritmaları değiştirilebilir (swap) hale getirir:
interface SortStrategy {
sort(data: number[]): number[];
}
class QuickSort implements SortStrategy {
sort(data: number[]) { /* quick sort */ return data; }
}
class MergeSort implements SortStrategy {
sort(data: number[]) { /* merge sort */ return data; }
}
class Sorter {
constructor(private strategy: SortStrategy) {}
execute(data: number[]) { return this.strategy.sort(data); }
}
9. Command
İstekleri nesne olarak kapsüller:
interface Command {
execute(): void;
undo(): void;
}
class AddItemCommand implements Command {
constructor(private cart: Cart, private item: Item) {}
execute() { this.cart.add(this.item); }
undo() { this.cart.remove(this.item); }
}
10. Template Method
Algoritmanın iskeletini tanımlar, detayları alt sınıflara bırakır:
abstract class DataExporter {
export() {
const data = this.fetchData();
const formatted = this.format(data);
this.save(formatted);
}
abstract fetchData(): any;
abstract format(data: any): string;
abstract save(output: string): void;
}
Hangi Deseni Ne Zaman Kullanmalı?
| Sorun | Desen | |-------|-------| | Farklı türde nesneler oluşturmak | Factory | | Tek instance gerekiyor | Singleton | | Karmaşık nesneyi adım adım kurmak | Builder | | Uyumsuz arayüzleri bağlamak | Adapter | | Dinamik özellik eklemek | Decorator | | Karmaşıklığı gizlemek | Facade | | Değişiklikleri dinlemek | Observer | | Algoritmayı değiştirmek | Strategy |
Sonuç
Tasarım desenleri bir amaç değil, bir araçtır. Her yerde kullanmaya çalışmak, kullanmamak kadar zararlıdır. Doğru soruna doğru deseni uygulayın.
Tasarım desenlerini pratik ederek öğrenmek için LabLudus platformunda Foundation kariyer yolundaki görevleri tamamlayın.