جلسه 12 (Refactoring) بازآرایی کد
مقدمه:
بازآرایی کد فرآیندی است که در آن ساختار کد یک برنامه بدون تغییر رفتار بیرونی آن، بهبود مییابد. هدف اصلی از بازآرایی، افزایش خوانایی، کاهش پیچیدگی، بهبود قابلیت نگهداری و بهینهسازی عملکرد کد است. این کار به خصوص در پروژههای نرمافزاری بزرگ و طولانیمدت که نیاز به توسعه و نگهداری مداوم دارند، اهمیت بالایی پیدا میکند.
چرا بازآرایی کد مهم است؟
- افزایش خوانایی: کد بازآرایی شده، واضحتر و قابل فهمتر است و به سایر توسعهدهندگان (و حتی خودتان در آینده) کمک میکند تا منطق برنامه را سریعتر درک کنند.
- کاهش پیچیدگی: با حذف کدهای تکراری، توابع طولانی و منطقهای پیچیده، کد سادهتر شده و احتمال بروز خطا کاهش مییابد.
- بهبود قابلیت نگهداری: کد تمیز و سازمانیافته، نگهداری و رفع اشکال آن را آسانتر میکند. اضافه کردن ویژگیهای جدید نیز با سهولت بیشتری انجام میشود.
- کاهش باگها: بازآرایی منظم میتواند به کشف و رفع باگهای پنهان کمک کند، زیرا در فرآیند بازنگری کد، با دقت بیشتری به جزئیات توجه میشود.
- بهینهسازی عملکرد: اگرچه هدف اصلی بازآرایی، بهبود ساختار است، اما گاهی اوقات میتواند منجر به بهینهسازیهای عملکردی نیز بشود.
چه زمانی باید کد را بازآرایی کرد؟
- قبل از افزودن ویژگی جدید: بازآرایی کد موجود قبل از اضافه کردن قابلیتهای جدید، از پیچیده شدن بیش از حد کد جلوگیری میکند.
- قبل از رفع اشکال: گاهی اوقات، برای رفع یک باگ، لازم است ابتدا بخشی از کد را بازآرایی کنید تا درک آن آسانتر شود.
- پس از افزودن ویژگی: پس از پیادهسازی یک ویژگی، ممکن است متوجه شوید که کد میتواند سازماندهی بهتری داشته باشد.
- در طول مرور کد (Code Review): بازآرایی میتواند بخشی از فرآیند مرور کد باشد، جایی که تیم به دنبال راههایی برای بهبود کد هستند.
- زمانی که با “بوی کد” (Code Smell) مواجه میشوید: “بوی کد” نشانههایی هستند که حاکی از مشکلات احتمالی در طراحی یا پیادهسازی کد میباشند (مثلاً توابع بسیار طولانی، نامهای متغیر نامفهوم، کدهای تکراری).
تکنیکهای رایج بازآرایی کد:
- استخراج تابع (Extract Function): اگر بخشی از کد در چندین مکان تکرار شده یا یک تابع بسیار طولانی است، آن بخش را به یک تابع جداگانه منتقل کنید.
- تغییر نام (Rename): نامهای واضح و گویا برای متغیرها، توابع، کلاسها و فایلها انتخاب کنید تا هدف آنها به راحتی مشخص باشد.
- جایگزینی ثابت با ثابت (Replace Magic Number with Symbolic Constant): مقادیر عددی ثابت که معنای خاصی دارند (Magic Numbers) را با ثابتهای نامگذاری شده جایگزین کنید.
- استخراج کلاس (Extract Class): اگر یک کلاس مسئولیتهای زیادی بر عهده دارد، آن را به کلاسهای کوچکتر و متمرکزتر تقسیم کنید.
- جایگزینی شرط با پلیمورفیزم (Replace Conditional with Polymorphism): در شرایطی که از بلوکهای شرطی (if/else یا switch) برای انتخاب رفتار بر اساس نوع یا وضعیت یک شی استفاده میشود، میتوان از الگوهای پلیمورفیزم برای سادهسازی کد بهره برد.
- شکستن کلاس غولپیکر (Decompose Superclass/Replace Inheritance with Delegation): اگر یک کلاس والد کارهای زیادی انجام میدهد یا وراثت باعث وابستگیهای ناخواسته شده است، میتوان از تکنیکهای تفویض اختیار (Delegation) استفاده کرد.
- حذف کد مرده (Remove Dead Code): کدهایی که دیگر استفاده نمیشوند را شناسایی و حذف کنید.
نکات کلیدی برای موفقیت در بازآرایی:
- تست واحد (Unit Tests): قبل از شروع بازآرایی، اطمینان حاصل کنید که تستهای واحد پوشش خوبی از کد موجود دارند. این تستها به شما کمک میکنند تا مطمئن شوید رفتار کد پس از بازآرایی تغییر نکرده است.
- تغییرات کوچک و مکرر: بازآرایی را به صورت گام به گام و با تغییرات کوچک انجام دهید. پس از هر تغییر، تستها را اجرا کنید.
- استفاده از ابزارهای کمکی: بسیاری از IDEها ابزارهای داخلی برای بازآرایی خودکار (مانند تغییر نام، استخراج تابع) ارائه میدهند که میتوانند فرآیند را تسریع کنند.
- تمرکز بر یک مشکل در هر زمان: سعی نکنید همه مشکلات کد را همزمان حل کنید. روی یک تکنیک بازآرایی یا یک بخش از کد تمرکز کنید.
خلاصه نکات کلیدی:
- بازآرایی کد، بهبود ساختار کد بدون تغییر رفتار آن است.
- اهداف اصلی شامل افزایش خوانایی، کاهش پیچیدگی و بهبود نگهداری است.
- همیشه قبل از بازآرایی، از پوشش مناسب تستهای واحد اطمینان حاصل کنید.
- تغییرات کوچک و مکرر، همراه با اجرای مداوم تستها، رویکردی امن برای بازآرایی است.
- ابزارهای IDE میتوانند در اجرای بسیاری از تکنیکهای بازآرایی کمککننده باشند.
تمرین پایان فصل:
- کد زیر را در نظر بگیرید. چه “بوی کدی” در این تابع مشاهده میکنید؟ چگونه میتوانید با استفاده از تکنیک “استخراج تابع” آن را بازآرایی کنید؟
python def process_order(order):
total_price = 0
# Calculate item prices
for item in order['items']:
price = item['quantity'] * item['unit_price']
total_price += price
# Apply discount if applicable
if item['discount_eligible']:
discount_amount = price * item.get('discount_rate', 0.05) # Default discount 5%
total_price -= discount_amount
# Add shipping cost
shipping_cost = calculate_shipping(order['destination'])
total_price += shipping_cost
# Apply taxes
tax_rate = get_tax_rate(order['destination']['country'])
final_price = total_price * (1 + tax_rate)
return final_price
# Assume calculate_shipping and get_tax_rate are defined elsewhere
کدام یک از تکنیکهای بازآرایی ذکر شده، به طور مستقیم به بهبود خوانایی کد کمک میکند؟ و کدام یک بیشتر به کاهش پیچیدگی؟ توضیح دهید.
چرا داشتن تستهای واحد قبل از شروع بازآرایی، حیاتی است؟ سناریویی را شرح دهید که در آن نداشتن تست واحد میتواند منجر به بروز مشکل شود.