در دنیای پرشتاب توسعه نرمافزار، فشار برای تحویل سریع ویژگیها اغلب منجر به کوتاهآمدن میشود. ما راهحلهای سریع و ناکامل مینویسیم، منطق را کپی-پیست میکنیم و پاکسازی را برای «بعداً» به تعویق میاندازیم. اگرچه این کار ممکن است تحویل اولیه را تسریع کند، اما آنچه ما بدهی فنی مینامیم را انباشته میکند. در طول زمان، این بدهی به عنوان مالیاتی نامرئی بر هر ویژگی اضافه شده و هر باگ رفع شده عمل میکند.
بازآرایی (Refactoring) پادزیر این وضعیت است. این فرآیندی منضبط برای ساختاردهی مجدد کد کامپیوتری موجود—بدون تغییر رفتار خارجی آن—است تا ویژگیهای غیرعملکردی آن، مانند خوانایی، ماژولار بودن و قابلیت نگهداری، بهبود یابد. اما بازآرایی تنها درباره تمیزکاری نیست؛ بلکه سرمایهگذاری در طول عمر آینده کدبیس شماست.
بازآرایی چیست و چه چیزی نیست؟
قبل از غرق شدن در تکنیکها، تعریف مرزهای بازآرایی حیاتی است. یک سوءتفاهم رایج این است که بازآرایی شامل افزودن ویژگیهای جدید یا رفع باگها میشود. بر اساس تعریف مارتین فاولر، از پیشگامان این روش، بازآرایی به عنوان تغییری در ساختار داخلی نرمافزار تعریف میشود تا درک آن آسانتر و اصلاح آن ارزانتر شود، بدون اینکه رفتار قابل مشاهده آن تغییر کند.
اگر در حال رفع یک باگ هستید، این اشکالزدایی (Debugging) است. اگر در حال افزودن یک ویژگی هستید، این توسعه است. بازآرایی بهداشتی است که کدبیس شما را بین این فعالیتها سالم نگه میدارد. قانون طلایی این است: ابتدا تست کنید. هرگز بدون یک مجموعه جامع از تستهای واحد، بازآرایی نکنید. تستها به عنوان تور ایمنی شما عمل میکنند و تضمین میکنند که اگر به طور تصادفی رفتاری را تغییر دهید، تستها بلافاصله شکست خورده و شما را از برگرداندن تغییرات آگاه میکنند.
شناسایی بوی بد کد
بازآرایی باید هم واکنشی و هم پیشدستانه باشد. شما زمانی بازآرایی میکنید که «بوی بد کد» را مشاهده کنید—نشانههایی از مشکلات عمیقتر در کد. بویهای رایج عبارتند از:
- کد تکراری: کپی-پیست کردن منطق، مکانهای متعددی برای بهروزرسانی ایجاد میکند زمانی که الزامات تغییر کنند.
- توابع طولانی: توابعی که سعی میکنند کارهای زیادی انجام دهند، سخت تست و درک میشوند.
- کلاسهای بزرگ: کلاسهایی که مسئولیتهای زیادی را مدیریت میکنند، اصل مسئولیت تکگانه را نقض میکنند.
- حسادت به ویژگی (Feature Envy): زمانی که یک روش زمان بیشتری را صرف دسترسی به دادههای یک شیء دیگر میکند تا نمونه خودش.
مثال عملی: استخراج یک روش
یکی از سادهترین و مؤثرترین تکنیکهای بازآرایی، استخراج روش (Extract Method) است. قطعه کد جاوا زیر را در نظر بگیرید که در آن یک حلقه هم پردازش داده و هم قالببندی را انجام میدهد. این جفتشدگی کد را خشک و سختتر برای تست کردن میکند.
// قبل: منطق ترکیب شده
public void processAndPrintData(List<String> items) {
for (String item : items) {
// منطق کسب و کار
String processed = item.toUpperCase().trim();
// منطق خروجی
System.out.println("Result: " + processed);
}
}
با استخراج منطق پردازش به یک روش جداگانه، دغدغهها را از هم جدا میکنیم. این کار حلقه اصلی را تمیزتر میکند و به ما امکان میدهد منطق پردازش را به طور مستقل تست کنیم.
// بعد: دغدغههای جدا شده
public void processAndPrintData(List<String> items) {
for (String item : items) {
System.out.println("Result: " + processItem(item));
}
}
private String processItem(String item) {
return item.toUpperCase().trim();
}
در نسخه بازآرایی شده، processAndPrintData اکنون مانند یک روایت سطح بالا خوانده میشود، در حالی که processItem تبدیل خاص را انجام میدهد. این کار از اصل «بگو، نپرس» (Tell, Don't Ask) پیروی کرده و خوانایی را به طور قابل توجهی بهبود میبخشد.
استراتژی: گامهای کوچک و کامیتهای مکرر
بازآرایی موفقیتآمیز تدریجی است. بازآراییهای بزرگ و ناگهانی (Big-bang) پرریسک و سخت برای اشکالزدایی هستند. در عوض، رویکرد «گامهای کوچک» (Baby Steps) را اتخاذ کنید:
- شناسایی ناحیه خاصی از کد برای بهبود.
- اجرای مجموعه تستها برای ایجاد یک خط پایه.
- انجام یک تغییر کوچک (مثلاً تغییر نام یک متغیر، استخراج یک روش).
- اجرای مجدد تستها. اگر موفق بودند، تغییر را کامیت کنید.
- تکرار تا زمانی که ساختار مطلوب به دست آید.
این استراتژی خطر معرفی باگهای جدید را به حداقل میرساند و شناسایی اینکه کدام تغییر خاص باعث شکست شده است را آسانتر میکند، اگر تستها شروع به شکست خوردن کنند. علاوه بر این، کامیتهای مکرر تضمین میکنند که تاریخچه کنترل نسخه شما به صورت دانهای باقی بماند که برای اشکالزدایی و بررسی کد در آینده مفید است.
نتیجهگیری
بازآرایی یک رویداد یکباره نیست؛ بلکه یک عادت مداوم است. درست همانطور که آشپزخانه خود را پس از آشپزی تمیز میکنید، باید کد خود را پس از نوشتن تمیز کنید. با اولویت دادن به وضوح کد و کاهش بدهی فنی، به تیم خود قدرت میدهید تا در بلندمدت سریعتر حرکت کند. به یاد داشته باشید، کد بسیار بیشتر از آنکه نوشته شود، خوانده میشود. در کیفیت آن سرمایهگذاری کنید، و شما در آینده—همچنین همکارانتان—از شما تشکر خواهند کرد.