مهاجرت کد و ارتقای نسخه با کمک هوش مصنوعی
پروژهای که چهار سال روی نسخهی قدیمی مانده، یک روز مجبور به ارتقا میشود. سؤال این نیست که ابزار کمک میکند یا نه؛ این است که کجا باید جلویش را گرفت.
یک پروژهی داخلی که چهار سال روی نسخهی قدیمی مانده، تیمش عوض شده، مستنداتش کامل نیست و تست هم ندارد. حالا کتابخانهی پرداخت اعلام کرده نسخهی قدیمی را پشتیبانی نمیکند و ارتقا اجباری شده. این سناریو در بیشتر شرکتهای نرمافزاری ایران تکرار میشود.
وسوسهی اول واضح است: کل کد را بدهیم و نسخهی جدید بگیریم. این کار تقریباً همیشه بد تمام میشود — نه چون خروجی بیکیفیت است، چون کسی آن حجم خروجی را واقعاً مرور نمیکند.
چرا مهاجرتها شکست میخورند
مشکل معمولاً فنی نیست. مهاجرت وقتی از دست میرود که مقیاس تغییر از توان مرور تیم بزرگتر شود. وقتی هزار خط تغییر در یک کامیت باشد و همهچیز همزمان عوض شده باشد، هیچکس نمیتواند بگوید کدام تغییر باعث آن رفتار عجیب در تولید شده است.
دومین دلیل شایع، فرض نانوشته است. کد قدیمی معمولاً پر از رفتارهایی است که کسی عمداً ننوشته ولی سیستم به آنها وابسته شده. مدل اینها را نمیبیند و «تمیزشان میکند».
مرحلهی صفر: شبکهی ایمنی
قبل از تغییر یک خط، سه چیز باید سر جایش باشد. بدون اینها، مهاجرت با کمک ابزار فقط سرعت خرابکاری را بالا میبرد.
- کنترل نسخه با شاخهی جدا و کامیتهای کوچک با پیام روشن. اگر لازم شد برگردید، باید بتوانید فقط یک تکه را برگردانید.
- تست برای مسیرهای حیاتی. نه پوشش کامل — همان چند کاری که اگر بشکنند کسبوکار میخوابد: ورود، ثبت سفارش، پرداخت.
- محیط آزمایشی با دادهی واقعیِ ناشناسشده. باگهای مهاجرت معمولاً با دادهی تمیز ظاهر نمیشوند.
اگر پروژه تست ندارد، اولین کار نوشتن تست است، نه ارتقا. خودِ نوشتن این تستها را هم میتوانید بسپارید — ولی حتماً هرکدام را یک بار عمداً بشکنید تا مطمئن شوید واقعاً چیزی را میسنجند. تستی که همیشه سبز است، بدتر از نداشتن تست است.
تکهتکه، نه یکجا
واحد کار درست، یک فایل یا یک ماژول کوچک است. برای هر واحد، همین چرخه: تبدیل، مرور، تست، کامیت. کند بهنظر میرسد و در عمل سریعتر تمام میشود، چون هیچوقت مجبور نمیشوید یک هفته کار را دور بریزید.
این فایل را از [نسخهی مبدأ] به [نسخهی مقصد] ببر.
قواعد:
- فقط چیزهایی را عوض کن که برای سازگاری لازم است
- ساختار، نامها و منطق را دست نزن
- «بهترسازی» نکن؛ هر بهبود سلیقهای را جدا فهرست کن
- اگر جایی مطمئن نیستی، تغییر نده و علامت بزن
خروجی در سه بخش:
۱) کد نهایی
۲) جدول تغییرات: خط | قبل | بعد | دلیل
۳) مواردی که باید انسان بررسی کند
--- کد:
[کد]
بند «بهترسازی نکن» را حذف نکنید. بدون آن، مدل همزمان با مهاجرت شروع میکند به تغییر نام متغیرها و بازچینی توابع، و بعد نمیشود فهمید کدام تغییر ضروری بوده و کدام سلیقهای.
کدام مهاجرتها خوب جواب میدهند
| نوع مهاجرت | کیفیت | نکته |
|---|---|---|
| ارتقای نسخهی زبان | خوب | تغییرات معمولاً مکانیکی و مستندند |
| ارتقای فریمورک، یکی دو نسخه | خوب | راهنمای رسمی را هم در پرامپت بگذارید |
| جایگزینی کتابخانهی مشابه | متوسط | تفاوتهای رفتاری ظریف را چک کنید |
| تبدیل نحو قدیمی به مدرن | خوب | مثل تبدیل callback به async |
| تغییر زبان برنامهنویسی | ضعیف تا متوسط | ترجمهی خطبهخط، کد بیروح میسازد |
| تغییر معماری | ضعیف | تصمیم طراحی لازم است، نه ترجمه |
یک ترفند مؤثر برای ردیف دوم: بخش مربوطه از راهنمای رسمی ارتقا را مستقیم در پرامپت بچسبانید. مثلاً برای PHP، صفحهی رسمی مهاجرت به نسخهی ۸ فهرست دقیق تغییرات ناسازگار را دارد. با این کار، مدل بهجای اتکا به حافظهاش، از سند واقعی استفاده میکند.
خطاهایی که بیسروصدا رد میشوند
خطای خوب، خطایی است که برنامه را متوقف میکند. خطرناکترین باگهای مهاجرت آنهایی هستند که کد را اجرا میکنند، پیامی نمیدهند، و نتیجهی متفاوتی تولید میکنند. چهار جای کلاسیک:
- مقایسه و تبدیل نوع. رفتار مقایسهی رشته و عدد بین نسخهها عوض میشود و شرطهایی که قبلاً درست بودند، بیصدا برعکس میشوند.
- گرد کردن و اعشار. هر جا پول در کار است، خروجی قدیم و جدید را روی چند نمونهی واقعی مقایسه کنید.
- ترتیب پیشفرض مرتبسازی. فهرستی که قبلاً بهطور اتفاقی مرتب میآمد، ممکن است دیگر نیاید.
- منطقهی زمانی و تاریخ. در پروژههای ایرانی با تاریخ شمسی، این بخش بیشترین دردسر را میسازد.
برای هر کدام از این موارد، بهترین بررسی مقایسهی خروجی دو نسخه روی ورودی یکسان است — نه خواندن کد. الگوی کلی همان چیزی است که در مقالهی اشتباهات رایج هم آمده: خروجی مطمئن، دلیل درست بودن نیست.
بازنویسی کامل: کجا واقعبینانه نیست
گاهی تصمیم این است که پروژه از اول با فریمورک دیگری نوشته شود. اینجا مدل در نقش مترجم بد عمل میکند، چون ترجمهی خطبهخط، کدی میسازد که در زبان مقصد غریبه است.
کاری که خوب جواب میدهد، نقش دیگری است: از مدل بخواهید کد قدیمی را توضیح دهد — منطق کسبوکار، ورودی و خروجی، حالتهای لبه — و بعد بر اساس آن توضیح، خودتان طراحی جدید را بنویسید. روش کار با کد ناآشنا در راهنمای برنامهنویسی باز شده است.
جمعبندی
مهاجرت با کمک ابزار، سرعت را دو تا سه برابر میکند به شرطی که مقیاس کار کوچک بماند. فایلبهفایل، کامیتبهکامیت، با تستی که قبلش نوشته شده. هر بار که وسوسه شدید یک ماژول کامل را یکجا بدهید، یادتان باشد که هزینهی مرور نکردن را بعداً در محیط تولید میپردازید.
و یک قاعده که همهی اینها را جمع میکند: هر تغییری که دلیلش را نمیفهمید، نپذیرید. اگر پرسیدید و توضیح قانعکننده نبود، همانجا علامت بزنید و بعداً با آدم بررسی کنید. برای امتحان کردن این چرخه روی یک فایل واقعی، نارنگی نقطهی شروع سادهای است.
مطالب مرتبط: