Repository deseni nedir? Neden kullanılır, ORM varken gerekli midir?
Cevap
Repository, domain nesnelerine erişimi bir koleksiyon benzeri arayüz (get_by_id, add, find_by_email) arkasına saklayan ve veri erişim detaylarını (SQL, ORM, API çağrısı) iş mantığından ayıran bir desendir.
Ne kazandırır?
- Ayrıştırma: servis katmanı verinin PostgreSQL'den mi, cache'ten mi geldiğini bilmez.
- Test edilebilirlik: iş mantığını gerçek veritabanı yerine bellekte çalışan sahte bir repository ile test edebilirsiniz.
- Sorguların tek yerde toplanması: aynı sorgu kod tabanına dağılmaz.
from abc import ABC, abstractmethod
from dataclasses import dataclass
@dataclass
class User:
id: int
email: str
class UserRepository(ABC):
@abstractmethod
def get(self, user_id: int) -> User | None: ...
@abstractmethod
def add(self, user: User) -> None: ...
class SqlUserRepository(UserRepository):
def __init__(self, conn):
self.conn = conn
def get(self, user_id):
row = self.conn.execute("SELECT id, email FROM users WHERE id = ?", (user_id,)).fetchone()
return User(*row) if row else None
def add(self, user):
self.conn.execute("INSERT INTO users (id, email) VALUES (?, ?)", (user.id, user.email))
class InMemoryUserRepository(UserRepository): # testler için
def __init__(self):
self.items = {}
def get(self, user_id):
return self.items.get(user_id)
def add(self, user):
self.items[user.id] = user
class RegisterUser:
def __init__(self, repo: UserRepository):
self.repo = repo
def execute(self, user_id, email):
if self.repo.get(user_id):
raise ValueError("Kullanıcı zaten var")
self.repo.add(User(user_id, email))ORM varken gerekli mi?
Tartışmalı bir konudur:
- Entity Framework
DbContextveya Spring Data JPA zaten repository/unit of work sağlar. Üzerine bir de generic repository (Repository<T>ile sadece CRUD) yazmak çoğu zaman gereksiz bir soyutlama katmanıdır. - Domain'e özgü repository'ler (
OrderRepository.find_overdue()) ise sorguları anlamlı isimlerle toplamak için hâlâ değerlidir.
İlişkili desen: Unit of Work
Birden fazla repository'deki değişikliği tek bir transaction'da commit eder. ORM'lerde session/DbContext bu rolü üstlenir.
İlgili OOP & Tasarım Desenleri soruları
- Clean code nedir? Yaygın code smell'ler nelerdir?
- Dependency Injection nedir? IoC container ne işe yarar?
- Strategy deseni nedir? if/else zincirlerini nasıl ortadan kaldırır?
- Observer deseni nedir? Gerçek hayatta nerelerde karşımıza çıkar?
- Factory deseni nedir? Ne zaman kullanılır?
- Singleton deseni nedir? Neden bazen anti-pattern olarak görülür?
Bu konuda başka bir soru biliyor musun?
Mülakatta karşılaştığın soruları ekle, onaylandıktan sonra yayına alınsın.