کد مهمتر نباید به کد کماهمیتتر وابسته باشد

فرض کنید در یک سامانهی مالی، مهمترین قانون کسبوکار این است که فقط کاربرانی که موجودی کافی دارند بتوانند درخواست برداشت ثبت کنند. این قانون، از جنس سیاست اصلی سیستم است؛ یعنی همان چیزی که اگر روزی دیتابیس، فریمورک، یا روش ارتباط با سرویسهای بیرونی عوض شود، هنوز باید معتبر بماند.
اما در عمل، خیلی وقتها این قانون را مستقیم به جزئیات فنی میدوزیم. چیزی شبیه این:
import {PrismaClient} from '@prisma/client'
import axios from 'axios'
const prisma = new PrismaClient()
class WithdrawService {
async withdraw(userId: string, amount: number) {
const user = await prisma.user.findUnique({
where: {id: userId},
})
if (!user) {
throw new Error('User not found')
}
if (user.balance < amount) {
throw new Error('Insufficient balance')
}
await axios.post('https://wallet-service.example.com/withdraw', {
userId,
amount,
})
await prisma.withdrawRequest.create({
data: {
userId,
amount,
status: 'submitted',
},
})
}
}
در این کد، منطق اصلی برداشت مستقیماً هم به ORM وابسته است، هم به یک کارخواه وب. یعنی مهمترین بخش تصمیمگیری سیستم، به چیزهایی وصل شده که در اصل فقط ابزار اجرا هستند.
مسئله فقط این نیست که کد کمی شلوغ شده است. مسئله این است که جهت وابستگی برعکس چیزی است که طراحی خوب میخواهد. اینجا سیاست سطح بالا به جزئیات سطح پایین آویزان شده است.




