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

چرا بازنویسی کامل خطرناک است

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

مشکل‌های دیگر هم هست:

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

الگوی Strangler Fig

مارتین فاولر این الگو را از درختی نام‌گذاری کرده که دور درخت میزبان رشد می‌کند و کم‌کم جای آن را می‌گیرد. ایده ساده است: سیستم تازه را کنار سیستم قدیمی می‌سازید و قابلیت‌ها را یکی‌یکی منتقل می‌کنید تا روزی که سیستم قدیمی را بتوان خاموش کرد.

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

در عمل چطور انجام می‌شود

  1. لایه‌ای جلوی سیستم بگذارید. یک مسیریاب یا لایه API درخواست‌ها را می‌گیرد و تصمیم می‌گیرد کدام به قدیم و کدام به جدید برود.
  2. یک تکه کوچک و کم‌ریسک انتخاب کنید. تکه‌ای که مرزش روشن است. مثلاً گزارش‌گیری یا یک بخش فقط‌خواندنی. هسته سفارش و پرداخت را برای اول کار نگذارید.
  3. برای رفتار فعلی تست بنویسید. پیش از انتقال، باید بدانید سیستم الان چه می‌کند، حتی اگر رفتارش عجیب باشد.
  4. ترافیک را کم‌کم منتقل کنید. اول درصد کمی از کاربران، و با امکان برگشت سریع.
  5. داده را با احتیاط جابه‌جا کنید. بخش سخت معمولاً داده است. برای مدتی شاید لازم باشد دو سیستم هم‌زمان به‌روز بمانند.
  6. کد قدیمی را واقعاً حذف کنید. اگر این مرحله انجام نشود، به‌جای یک سیستم قدیمی دو سیستم نگه می‌دارید.

چه زمانی بازنویسی کامل منطقی است

جایگزینی تدریجی همیشه جواب نیست. بازنویسی می‌تواند انتخاب درستی باشد وقتی:

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

حتی در این حالت‌ها هم نسخه کوچک را زود به دست کاربر واقعی برسانید و تا مطمئن نشده‌اید سیستم قدیمی را خاموش نکنید.

پیش از هر تصمیمی این پرسش‌ها را بپرسید

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

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

منابع