پرش به مطلب اصلی

یک پست با برچسب "اینترفیس"

یادداشت‌هایی درباره طراحی اینترفیس‌ها و مدیریت وابستگی

مشاهده تمام برچسب‌ها

اینترفیس بزرگ، کلاس کوچک را هم آلوده می‌کند

· ۱۱ دقیقه مطالعه
مهدی مالوردی
مهندس نرم‌افزار و نویسندهٔ این سایت

یک پریز بزرگ با کابل‌های زیاد که یک دستگاه کوچک فقط به یکی از آن‌ها نیاز دارد.

فرض کنید در یک سامانه‌ی مالی، یک ریپازیتوری بزرگ برای کار با تراکنش‌ها داریم. این ریپازیتوری همه‌چیز را با هم دارد: گرفتن تراکنش، ساخت گزارش، بستن حساب، بازسازی داده، خروجی گرفتن، و چند کار دیگر. روی کاغذ، شاید این طراحی «مرکزی» و «یک‌پارچه» به نظر برسد. اما کافی است یک مصرف‌کننده‌ی کوچک وارد ماجرا شود تا مشکل خودش را نشان دهد.

برای نمونه، یک سرویس داریم که فقط می‌خواهد یک تراکنش را بر اساس شناسه پیدا کند:

interface TransactionRepository {
findById(id: string): Promise<Transaction | null>
save(transaction: Transaction): Promise<void>
delete(id: string): Promise<void>
exportDailyReport(date: string): Promise<ReportFile>
rebuildBalances(): Promise<void>
closeMonth(month: string): Promise<void>
archiveOldTransactions(before: string): Promise<number>
}

و مصرف‌کننده‌ی ما فقط همین را لازم دارد:

class TransactionDetailsService {
constructor(
private readonly repository: TransactionRepository,
) {}

async getDetails(id: string) {
return this.repository.findById(id)
}
}

در نگاه نخست، شاید کسی بگوید: «خب چه اشکالی دارد؟ این سرویس که فقط از findById استفاده می‌کند.» اما مسئله دقیقاً همین‌جاست. این سرویس، حتی اگر فقط به یک متد نیاز داشته باشد، به اینترفیس بزرگی وابسته شده که پر از چیزهای نامربوط است. یعنی یک کلاس کوچک، ناخواسته بار یک قرارداد بزرگ را روی دوش می‌کشد.