حالت نقشه‌ی فنی فعال است — تصمیم‌های طراحی این سایت را ببینید

لایه‌های قابل‌تعویض: چرا هر سرویس بیرونی باید پشت یک قرارداد باشد

پرداخت، پیامک، پایگاه داده و هوش مصنوعی روزی عوض می‌شوند. الگوی «درگاه و مبدل» کمک می‌کند این تغییر با عوض کردن یک فایل انجام شود، نه با بازنویسی محصول. توضیح ساده با مثال واقعی.

هر محصول نرم‌افزاری به چیزهایی بیرون از خودش وابسته است: درگاه پرداخت، سرویس پیامک، پایگاه داده، مدل هوش مصنوعی. همه‌ی این‌ها یک ویژگی مشترک دارند: روزی عوض می‌شوند. قیمت تغییر می‌کند، سرویس قطع می‌شود، یا گزینه‌ی بهتری پیدا می‌شود.

پرسش این نیست که آیا عوض می‌شوند. پرسش این است که عوض کردنشان چقدر برای شما گران تمام می‌شود.

مشکل وابستگی مستقیم

ساده‌ترین راه این است که هر جا لازم شد، سرویس بیرونی را مستقیماً صدا بزنید. کد ثبت سفارش، خودش با درگاه پرداخت حرف می‌زند. کد ثبت‌نام، خودش پیامک می‌فرستد.

این روش در هفته‌ی اول سریع است. مشکل وقتی پیدا می‌شود که نام و جزئیات آن سرویس در ده‌ها جای کد پخش شده و عوض کردنش یعنی دست بردن در همه‌ی آن‌ها.

الگوی درگاه و مبدل

راه‌حل دو قطعه دارد:

  • درگاه (Port): قراردادی که می‌گوید سامانه چه چیزی لازم دارد، بدون اینکه بگوید چه کسی انجامش می‌دهد. مثلاً «اعلان درخواست جدید را بفرست».
  • مبدل (Adapter): پیاده‌سازی آن قرارداد برای یک سرویس مشخص. مبدل تلگرام، مبدل ایمیل، مبدل پیامک.

منطق اصلی محصول فقط درگاه را می‌شناسد. اینکه کدام مبدل فعال است، در یک نقطه و با تنظیمات تعیین می‌شود.

مثال از همین سایت

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

notifyNewInquiry(inquiry) → موفق / ناموفق

پشت این قرارداد چند مبدل وجود دارد: لاگ، تلگرام، بله، ایمیل و اعلان مرورگر. می‌توانند هم‌زمان فعال باشند. کد فرم از هیچ‌کدام خبر ندارد.

همین الگو برای پایگاه داده هم به کار رفته است: در محیط توسعه یک پایگاه سبک فایل‌محور، در محیط عملیاتی PostgreSQL. جابه‌جایی فقط با تغییر یک متغیر انجام می‌شود.

سه فایده‌ی عملی

  1. تعویض ارزان. عوض کردن سرویس یعنی نوشتن یک مبدل جدید. بقیه‌ی سامانه دست نمی‌خورد.
  2. توسعه بدون وابستگی. می‌شود محصول را بدون حساب کاربری در هیچ سرویس بیرونی اجرا و آزمایش کرد، چون مبدل محلی وجود دارد.
  3. آزمون‌پذیری. در تست، مبدل ساختگی جای سرویس واقعی می‌نشیند. تست‌ها سریع و قابل‌اعتماد می‌شوند.

کجا لازم نیست

این الگو برای مرزهای بیرونی است. اگر برای هر تابع داخلی یک قرارداد بسازید، فقط کد را سخت‌خوان کرده‌اید. قاعده‌ی من:

  • چیزی که بیرون از کنترل شماست یا احتمال تعویض دارد → پشت درگاه.
  • منطق داخلی خود محصول → مستقیم و ساده.

نکته‌هایی برای طراحی قرارداد خوب

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

ارتباط با بقیه‌ی معماری

این الگو ستون اصل معماری نهایی از روز اول، پیاده‌سازی چابک در شروع است: مرزها ثابت می‌مانند و آنچه پشت آن‌هاست می‌تواند ساده شروع شود. در محصولات هوش مصنوعی هم همین منطق، تعویض مدل و کنترل هزینه را ممکن می‌کند.

جمع‌بندی

سرویس‌های بیرونی مهمان محصول شما هستند، نه ستون آن. اگر هر مهمان پشت در خودش بایستد، آمدن و رفتنش خانه را به هم نمی‌ریزد.

برای طراحی معماری‌ای که با محصولتان رشد کند، معماری و برنامه‌ریزی فنی را ببینید.

نویسنده

محمد علی اسلامی‌پور

محمد علی اسلامی‌پور معمار محصول دیجیتال است؛ محصولات هوش مصنوعی، SaaS و اپ‌های وب را از تعریف مسئله و معماری سامانه تا انتشار، همراه تیم توسعه‌ی خودش هدایت می‌کند.