بازآرایی کردن — یک اصطلاح عامیانه IT است که به معنای تغییر ساختار داخلی کد بدون تغییر رفتار خارجی آن میباشد. هدف بازآرایی — تمیزتر، قابلفهمتر و آسانتر کردن کد برای پشتیبانی است. به گفته مارتین فاولر در کتاب «Refactoring: Improving the Design of Existing Code» (Addison-Wesley، 2019)، بازآرایی یک عمل اجباری برای حفظ سلامت پایه کد است و استفاده منظم از آن هزینه کل مالکیت پروژه را 20-30% کاهش میدهد.
نکات اصلی
بازآرایی کردن — فرآیند تغییر ساختار داخلی کد برنامه با هدف بهبود ویژگیهای کیفی آن بدون تغییر رفتار مشاهدهپذیر است. این اصطلاح توسط مارتین فاولر در سال 1999 وارد استفاده گسترده شد و خود این عمل به یکی از پایههای توسعه چابک و برنامهنویسی افراطی تبدیل شد.
ویژگی کلیدی بازآرایی — حفظ عملکرد است. پس از بازآرایی، برنامه باید دقیقاً همان اقدامات را انجام دهد و همان نتایج را قبل از تغییرات برگرداند. تضمین این امر تستهای خودکار هستند که پس از هر گام کوچک بازآرایی اجرا میشوند. اگر تستها سبز باشند — رفتار حفظ شده است. اگر قرمز باشند — بازآرایی نادرست انجام شده یا رفتار تغییر کرده است، به این معنی که این دیگر بازآرایی نیست، بلکه تغییر عملکرد است.
در صنعت یک باور غلط رایج وجود دارد: هر تعمیر کدی را بازآرایی مینامند. در واقع بازنویسی کد با تغییر رفتار “rewrite” یا “rework” است، نه بازآرایی. تفاوت اساسی است: بازآرایی — یک فرآیند کنترلشده و ایمن است، در حالی که بازنویسی با تغییر منطق — توسعه جدید کامل با تمام ریسکهای همراه است.
سرمایهگذاری دانش درباره بازآرایی در محیط فارسیزبان از طریق همان مکانیسمهای سایر اصطلاحات IT انجام میشود: قرضگیری از انگلیسی refactor با افزودن پسوند فارسی. برنامههای آموزشی مهندسی نرمافزار و ترجمههای کتاب این اصطلاح را در واژگان حرفهای تثبیت کردهاند.
تشخیص بازآرایی از بازنویسی کامل کد (rewrite) مهم است. بازآرایی — مجموعهای از تغییرات کوچک و ایمن است که هر کدام رفتار را حفظ میکنند. بازنویسی — ایجاد پیادهسازی جدید از ابتدا، اغلب با تغییر معماری، فناوریها و رفتارها است. تحقیق Standish Group (2023) نشان میدهد که پروژههایی که بازنویسی کامل را انتخاب میکنند در 40% موارد شکست میخورند، در حالی که پروژههایی که بازآرایی منظم انجام میدهند 25% سطح بدهی فنی کمتری دارند.
بازآرایی چندین وظیفه کلیدی را حل میکند که هر کدام مستقیماً بر سرعت و هزینه توسعه تأثیر میگذارد. درک این اهداف به تیم کمک میکند تا اولویتها را درست تعیین کند و زمان صرف شده برای بازآرایی را در برابر ذینفعان توجیه کند.
کد یک بار نوشته میشود، اما دهها و صدها بار خوانده میشود. اگر یک توسعهدهنده 30 دقیقه برای فهمیدن کار یک تابع صرف کند — این یک از دست دادن مستقیم بهرهوری است. کد خوانا بار شناختی را کاهش میدهد و ورود اعضای جدید تیم را سرعت میبخشد. تکنیکهایی مانند Rename Method، Extract Variable و Introduce Explaining Variable دقیقاً برای افزایش فهمپذیری کد طراحی شدهاند. بر اساس تحقیق Developer Productivity (Microsoft Research، 2023)، توسعهدهندگان تا 60% زمان خود را صرف خواندن کد میکنند، نه نوشتن آن، که خوانایی را به یکی از عوامل اصلی بهرهوری تبدیل میکند.
اصل DRY (Don’t Repeat Yourself) — یکی از اصول اساسی در برنامهنویسی است. تکرار کد منجر به این میشود که همان تغییر باید در چندین مکان اعمال شود، که ریسک خطاها و اصلاحات فراموششده را افزایش میدهد. بازآرایی با تکنیکهای Extract Method و Pull Up Method امکان حذف تکرار و متمرکز کردن منطق را فراهم میکند.
معیارهای پیچیدگی سیکلوماتیک و عمق تو در تویی مستقیماً با تعداد نقصها در کد همبستگی دارند. اگر یک تابع پیچیدگی سیکلوماتیک بالای 15-10 داشته باشد، تست کردن آن دشوار است و به راحتی شکسته میشود. بازآرایی با استفاده از Replace Conditional with Polymorphism، Decompose Conditional و Extract Method امکان کاهش پیچیدگی به سطح قابل کنترل را فراهم میکند. تحقیق NIST (2024) نشان میدهد که ماژولهای با پیچیدگی بالا 2-3 برابر بیشتر نقص به ازای هر هزار خط کد دارند.
یکی از دلایل اصلی بازآرایی — نیاز به افزودن قابلیت جدید است. اگر ساختار فعلی کد اجازه اعمال تغییر بدون شکستن رفتار موجود را ندهد، بازآرایی به آمادهسازی زمینه کمک میکند. «قاعده کمپینگ» (کد را تمیزتر از آنچه یافتی رها کن) — یکی از توصیههای مارتین فاولر است که بازآرایی را از یک فعالیت موردی به یک عمل دائمی تبدیل میکند.
دادههای تحلیل 500 پروژه متنباز در GitHub (IEEE Transactions on Software Engineering، 2024) نشان میدهد که پروژههای با بازآرایی منظم 30% کمتر «بوی کد» (code smells) و 15% شاخص بدهی فنی پایینتر در مقایسه با پروژههایی دارند که بازآرایی در آنها گاهبهگاه انجام میشود.
مارتین فاولر در کتاب خود بیش از 70 تکنیک بازآرایی را فهرست کرده است. در عمل بیشتر تیمها به طور منظم از 15-10 تای آنها استفاده میکنند. بیایید تکنیکهای کلیدی را که هر توسعهدهنده باید بداند مرور کنیم.
پراستفادهترین تکنیک. اگر یک قطعه کد را میتوان از نظر منطقی به یک تابع جداگانه استخراج کرد — باید این کار را انجام داد. Extract Method خوانایی را بهبود میبخشد، امکان نامگذاری عملیات را فراهم میکند و تست را آسانتر میکند. قاعده: اگر نظری میبینید که توضیح میدهد یک بلوک کد چه میکند — آن بلوک را میتوان به یک متد جداگانه استخراج کرد.
// قبل از بازآرایی
double total = amount * price;
double discounted = total * (1 - discountRate);
double tax = discounted * taxRate;
// بعد از بازآرایی
double total = calculateTotal(amount, price);
double finalPrice = applyDiscountAndTax(total);
نام باید ماهیت را منعکس کند. اگر نام متغیر یا متد به سوال «اینجا چه ذخیره/انجام میشود» پاسخ ندهد — باید تغییر نام داد. IDEهای مدرن این عملیات را ساده میکنند. نامهای تمیز — ارزانترین و مؤثرترین راه برای بهبود کد هستند.
وقتی منطق شرطی بیش از حد رشد کرده و گیجکننده شده است، چندریختی جایگزین تمیزتری ارائه میدهد. به جای switch-case بر اساس نوع — یک سلسلهمراتب کلاس با متد بازنویسی شده ایجاد کنید. چندریختی کد را قابل توسعه میکند: افزودن نوع جدید نیاز به تغییر شرایط موجود ندارد، فقط ایجاد یک زیرکلاس جدید کافی است.
// قبل از بازآرایی (عبارات شرطی)
if (type.equals("email")) {
sendEmail(message);
} else if (type.equals("sms")) {
sendSms(message);
}
// بعد از بازآرایی (چندریختی)
Notifier notifier = new EmailNotifier();
notifier.send(message);
وقتی یک تابع پارامترهای زیادی میگیرد (بیش از 4-3)، خواندن و ارسال آنها دشوار است. گروهبندی پارامترهای مرتبط در یک شیء-پارامتر امضا را کوتاهتر میکند، خوانایی را بهبود میبخشد و تغییرات بعدی را آسانتر میکند.
| تکنیک | هدف | چه زمانی به کار ببریم |
|---|---|---|
| Extract Method | استخراج منطق به تابع جداگانه | بلوک کد را میتوان با یک جمله توصیف کرد |
| Rename Variable | دقیقتر کردن نام متغیر/متد | نام ماهیت را منعکس نمیکند |
| Replace Conditional | جایگزینی switch-case با چندریختی | شرطها بر اساس نوع شیء |
| Extract Interface | استخراج قرارداد از کلاس | نیاز به پیوند ضعیف است |
تصمیم به بازآرایی — نه فنی، بلکه مدیریتی است. نیاز به تعادل بین بهرهوری فعلی و سلامت بلندمدت پایه کد دارد. بیایید موقعیتهای معمولی را بررسی کنیم که بازآرایی موجه است و چه زمانی بهتر است خودداری کنیم.
موقعیت اول — شما کدی را که باید تغییر دهید نمیفهمید. اگر درک کد موجود بیشتر از پیادهسازی قابلیت جدید زمان میبرد — این سیگنالی است که اول باید بازآرایی کرد. موقعیت دوم — تکراری پیدا کردهاید که توسعه را کند میکند و ریسک خطاها را افزایش میدهد. سوم — افزودن قابلیت جدید بدون نقض ساختار موجود غیرممکن است.
همچنین وقتی پایه کد حاوی \u00abبوی کد» (code smells) است باید بازآرایی کرد: متدهای طولانی، کلاسهای بزرگ، نظرات اضافی، زنجیرههای فراخوانی، سلسلهمراتب وراثت موازی. کاتالوگ بوی کد از کتاب فاولر شامل بیش از 20 شاخص معمول مشکلات است که هر کدام تکنیک بازآرایی مربوط به خود را دارند.
اگر کد پایدار کار میکند و برنامهای برای تغییر آن نیست، بازآرایی لازم نیست. اصل \u00abکار میکند — دست نزن» (if it ain’t broke, don’t fix it) به ویژه برای کدی که به ندرت تغییر میکند صدق میکند. بازآرایی به خاطر بازآرایی — یکی از اشکال کمالگرایی مهندسی است که بیشتر ضرر دارد تا فایده.
همچنین نباید کدی را که در آینده نزدیک کاملاً جایگزین میشود بازآرایی کرد. اگر تیم قصد بازنویسی ماژول به زبان یا معماری دیگر را دارد، بازآرایی نسخه فعلی اتلاف وقت است. و در نهایت، بازآرایی بدون تست — ماجراجویی است، به ویژه اگر پایه کد بزرگ و پیچیده باشد. استثنا — تغییرات ساده با استفاده از IDE که قابل بازگشت هستند.
بازآرایی ایمن — نظم و انضباط است. چندین اصل وجود دارد که رعایت آنها ریسکها را به حداقل میرساند و فرآیند را قابل پیشبینی میکند. اولین و مهمترین — بازآرایی فقط تحت پوشش تستها. اگر تستهایی که کد در حال تغییر را پوشش میدهند ندارید — ابتدا آنها را بنویسید.
اصل دوم — گامهای کوچک. هر عملیات بازآرایی باید حداقلی باشد: تغییر نام یک متغیر، استخراج یک متد، جداسازی یک کلاس. پس از هر گام — کامپایل کنید و تستها را اجرا کنید. تقسیم به گامهای کوچک امکان تشخیص فوری خطا و بازگرداندن آخرین تغییر را فراهم میکند. به گفته مارتین فاولر، گامهای کوچک بازآرایی را 3-4 برابر ایمنتر از تغییرات بزرگ میکند.
اصل سوم — استفاده از ابزارها. IDEهای مدرن (IntelliJ IDEA، VS Code، Eclipse) بازآراییهای خودکار ارائه میدهند: rename، extract method، extract variable، move class و دهها مورد دیگر. بازآراییهای ابزاری صحت تغییر را تضمین میکنند و نیاز به جستجوی دستی همه مکانهایی که باید کد تغییر کند را از بین میبرند.
اصل چهارم — بازآرایی را با تغییر عملکرد مخلوط نکنید. اگر همزمان بازآرایی میکنید و منطق جدید اضافه میکنید، نمیتوان فهمید کدام تغییر باعث خطا شده است. تقسیم کامیتها به \u00abبازآرایی» و ابویژگی» — استاندارد صنعتی است که بازبینی کد و بازگرداندن تغییرات را ساده میکند. ساختار توصیه شده: ابتدا کامیت با بازآرایی (فقط تغییرات ساختاری، رفتار حفظ شده)، سپس کامیت با قابلیت جدید.
گردش کار Git برای بازآرایی: یک شاخه جداگانه ایجاد کنید، بازآرایی را انجام دهید، به تستهای سبز برسید، کامیت کنید، سپس در همان شاخه قابلیت جدید اضافه کنید. اگر چیزی اشتباه پیش رفت — تغییرات بازآرایی همیشه از طریق git revert قابل بازگشت هستند.
# گامهای کوچک بازآرایی در Git
git checkout -b refactor/extract-payment
# گام 1: استخراج متد محاسبه
# ...تغییرات... → کامپایل → تستها
git commit -m "refactor: extract calculatePayment method"
# گام 2: تغییر نام متغیرها
# ...تغییرات... → کامپایل → تستها
git commit -m "refactor: rename amount to grossAmount"
سوالات متداول
خیر، اینها فرآیندهای متفاوتی هستند. بازآرایی کردن — بهبود کد موجود بدون تغییر رفتار آن. بازنویسی (rewrite) — ایجاد پیادهسازی جدید از ابتدا، اغلب با تغییر معماری و فناوریها. بازآرایی ایمنتر، ارزانتر و قابل پیشبینیتر است.
قاعده توصیه شده — 20% زمان اسپرینت برای بهبودهای فنی و بازآرایی. این امکان را فراهم میکند که بدهی فنی را در سطح قابل قبولی بدون کند کردن تحویل قابلیتهای تجاری نگه دارید.
میتوان، اما پرریسک است. برای تغییرات ساده از طریق IDE (تغییر نام، استخراج ثابت) تستها الزامی نیستند. برای تغییرات پیچیده — تستها الزامی هستند. اگر تستی نیست — ابتدا تستهای مشخصهای بنویسید که رفتار فعلی را ثبت کنند.
از طریق هزینه تغییرات استدلال کنید. اگر افزودن یک ویژگی ساده به دلیل کد بهم ریخته یک هفته طول میکشد — نشان دهید که بازآرایی زمان تغییرات آینده را کاهش میدهد. از معیارها استفاده کنید: زمان بازبینی کد، تعداد باگها، پیچیدگی سیکلوماتیک.
آخرین تغییر را بازگردانید. اگر از Git استفاده میشود — git revert آخرین کامیت. اگر گامهای کوچک به اندازه کافی کوچک بودند، حجم تغییرات از دست رفته حداقل خواهد بود. به همین دلیل بازآرایی بزرگ همیشه به یک سری گامهای کوچک تقسیم میشود.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.