TGViewer
C# Geeks (.NET) C# Geeks (.NET) @csharpgeeks · 550 subscribers
Post #493 215
🧩 راحتیِ اشتباهِ “Happy Path”: جدا کردن سرویس‌ها از یکدیگر

بیایید صادق باشیم: همهٔ ما این کد را نوشته‌ایم. 😅
صبح دوشنبه است، یک ددلاین دارید، و باید یک قابلیت ثبت‌نام کاربر را پیاده‌سازی کنید. کار ساده‌ای است: کاربر را ذخیره کنید، یک ایمیل خوش‌آمد بفرستید، و ثبت‌نام را در داشبورد analytics خود ثبت کنید.
شما این را می‌نویسید:
public class UserService(
IUserRepository userRepository,
IEmailService emailService,
IAnalyticsService analyticsService)
{
public async Task RegisterUser(string email, string password)
{
var user = new User(email, password);
await userRepository.SaveAsync(user);

// 1. Directly coupled to email service (external API)
await emailService.SendWelcomeEmail(user.Email);

// 2. Directly coupled to analytics (this could be an external API)
await analyticsService.TrackUserRegistration(user.Id);

// What if we need to add more features?
// This method will keep growing...
}
}

ظاهرش تمیز است. خوانا است. روی ماشین شما هم کار می‌کند.
اما این متد یک بمب ساعتی است. 💣

این متد فرض می‌کند فقط Happy Path وجود دارد.
فرض می‌کند شبکه همیشه پایدار است، سرویس ایمیل همیشه در دسترس است، و API مربوط به analytics همیشه سریع است.
در محیط production هیچ‌کدام تضمین‌شده نیست. ⚠️

اگر بیشتر فکر کنید، احتمالاً مثال مشابهی را در پروژه‌های خودتان هم دیده‌اید. ممکن است همین سناریو نباشد، اما الگو یکسان است:
یک متد که به شکل خطی چندین Side Effect را مدیریت می‌کند.

بیایید بررسی کنیم چرا این کد خطرناک است و چطور می‌توان آن را به یک معماری Event-driven مقاوم تبدیل کرد. 🚀

🔍 خطرات پنهان در “God Method”

سه مشکل اساسی در همین ده خط کد وجود دارد.
1️⃣ Temporal Coupling (تأخیر و زمان‌وابستگی) ⏳

وقتی کاربر روی "Register" کلیک می‌کند، باید منتظر بماند برای:
Database
SMTP Server
Analytics API
اگر سرویس analytics امروز حالش خوب نباشد و پاسخ‌گویی‌اش ۳ ثانیه طول بکشد،
کاربر شما هم باید ۳ ثانیه صبر کند.

شما در واقع کاربر را به خاطر کندی یک سیستم پس‌زمینه که حتی برایش مهم نیست مجازات می‌کنید. 😐

2️⃣ Partial Failure State (وضعیت شکست جزئی) 💥

این مهم‌ترین ریسک است. تصور کنید:

SaveAsync(user) موفق می‌شود →
کاربر در DB ذخیره می‌شود.

SendWelcomeEmail موفق می‌شود
→ کاربر ایمیل خوش‌آمد را دریافت می‌کند.

TrackUserRegistration یک خطای
503 Service Unavailable می‌دهد.

حالا چه؟ 🤔
اگر همه چیز را داخل transaction بگذارید و rollback کنید:
🔸️کاربر از دیتابیس حذف می‌شود
🔸️اما ایمیل خوش‌آمد را قبلاً دریافت کرده است
🔸️کاربر تلاش می‌کند وارد شود → وجود ندارد
🔸️یک تجربهٔ کاربری فاجعه‌بار.

اگر rollback نکنید:
🔹️کاربر در سیستم هست
🔹️اما در analytics ثبت نشده
🔹️عدم سازگاری داده (Data Inconsistency) ایجاد شده است
More from @csharpgeeks
  1. Sep 22, 2026یه مدتی قراره از دنیای NET. فاصله بگیرم، چون وقتشه برم سربازی. راستش نمیدونم این مدت رو چج…
  2. Sep 20, 2026🔥 حالا مشکل اصلی: Alert Storm فرض کن Database از دسترس خارج شده. ۱۰۰ Pod داری. هر Pod می‌…
  3. Sep 20, 2026🚨 طراحی سیستم Monitoring و Alerting در یک سیستم بزرگ فرض کن ساعت ۳ صبح است. سیستم شما با…
  4. Sep 19, 2026#Engineering_Leadership تصمیم نگرفتن هم یک تصمیم است یه چیز عجیب توی تیم‌های مهندسی: گاهی…
  5. Sep 19, 2026☑ چک‌لیست آماده‌سازی تیم، فرایندها و زیرساخت برای توسعه با AI توجه: هیچ چک‌لیستی جهان‌شمول…
  6. Sep 19, 2026📌پایان یک انتظار طولانی: اعتبارسنجی ناهمگام (Async Validation) در NET 11.
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →