ویرگول
ورودثبت نام
میلاد محمودی
میلاد محمودیعلاقه‌مند به برنامه‌نویسی و پایتون
میلاد محمودی
میلاد محمودی
خواندن ۵ دقیقه·۶ ماه پیش

چطور کدت رو تمیز کنی؟ تکنیک‌های رفیکتورینگ از کتاب مارتین فاولر فصل ششم

اگه برنامه‌نویس باشی، حتماً یه روزایی به کدت نگاه کردی و گفتی: «این دیگه چیه؟ چرا این‌جوری نوشتم؟» اینجا تکنیک‌های رفیکتورینگ به دادت می‌رسن! کتاب "Refactoring: Improving the Design of Existing Code" مارتین فاولر مثل یه راهنمای جادوییه که بهت نشون میده چطور کدت رو مرتب و خوانا کنی، بدون اینکه خرابش کنی. فصل ششم این کتاب یه سری تکنیک پایه‌ای و باحال معرفی می‌کنه که هر برنامه‌نویسی باید تو جعبه ابزارش داشته باشه. بریم ببینیم این تکنیک‌ها چی‌ان.با یه توضیح مختصر و مثال‌های ساده پایتونی.

قبل از شروع، سه تا چیز رو باید برای هر تکنیک در نظر بگیریم:

  • انگیزه(Motivation): چرا باید این تکنیک رو استفاده کنیم؟ چه مشکلی رو حل می‌کنه؟

  • مکانیزم(Mechanics): قدم‌به‌قدم چطور باید این کار رو انجام بدیم؟

  • مثال(Example): یه نمونه عملی که نشون بده قبل و بعدش چه فرقی می‌کنه.

حالا بریم سراغ تکنیک‌های رفیکتورینگ.

۱. استخراج تابع(Extract Function)

انگیزه:
وقتی یه تیکه کد داری که یه کار مشخص(مثل محاسبه یا چاپ چیزی) انجام میده، بهتره بندازیش تو یه تابع جدا با یه اسم معنی‌دار. این‌جوری کدت خواناتر میشه، می‌تونی تابع رو جای دیگه استفاده کنی، و تست کردنش هم راحت‌تره.

مکانیزم:

  • تیکه کدی رو پیدا کن که یه کار مشخص انجام میده.

  • یه تابع جدید با اسم خوب بساز.

  • متغیرهای مورد نیاز رو به‌عنوان پارامتر به تابع بده.

  • کد اصلی رو با فراخوانی تابع جایگزین کن.

  • تست کن که همه‌چیز درست کار می‌کنه.

مثال(پایتون):

استخراج تابع(Extract Function)
استخراج تابع(Extract Function)

۲. درون‌خط کردن تابع(Inline Function)

انگیزه:
اگه یه تابع خیلی ساده‌ست(مثلاً یه خط کد) و اسمش چیزی به فهم کد اضافه نمی‌کنه، می‌تونی بدنه‌شو بندازی تو جایی که صداش کردی و خود تابع رو حذف کنی. این کار کدت رو جمع‌وجورتر می‌کنه، ولی باید مطمئن شی که خوانایی کدت بهم نمی‌ریزه.

مکانیزم:

  • همه جاهایی که تابع صدا شده رو پیدا کن.

  • بدنه تابع رو جایگزین فراخوانی‌ها کن.

  • تابع رو حذف کن و تست کن.

مثال(پایتون):

درون‌خط کردن تابع(Inline Function)
درون‌خط کردن تابع(Inline Function)

۳. استخراج متغیر(Extract Variable)

انگیزه:
وقتی یه عبارت پیچیده تو کدت داری(مثل یه فرمول بزرگ)، بهتره اونو تو یه متغیر با اسم معنی‌دار بندازی. این کار باعث میشه کدت واضح‌تر بشه، دیباگ کردن راحت‌تره، و اگه بخوای بعداً چیزی بهش اضافه کنی، دستت بازه.

مکانیزم:

  • عبارت پیچیده رو به یه متغیر بده.

  • عبارت رو تو کد با متغیر جایگزین کن.

  • تست کن که چیزی خراب نشده.

مثال(پایتون):

استخراج متغیر(Extract Variable)
استخراج متغیر(Extract Variable)

۴. درون‌خط کردن متغیر(Inline Variable)

انگیزه:
اگه یه متغیر فقط یه بار مقدار گرفته و مستقیم تو یه عبارت استفاده شده، می‌تونی حذفش کنی و مقدارشو مستقیم بندازی تو عبارت. این کار کدت رو ساده‌تر می‌کنه، مخصوصاً وقتی متغیر اضافی فقط داره جا می‌گیره.

مکانیزم:

  • اولین جایی که متغیر استفاده شده رو پیدا کن.

  • مقدار متغیر رو مستقیم تو عبارت بذار.

  • متغیر رو حذف کن و تست کن.

مثال(پایتون):

درون‌خط کردن متغیر(Inline Variable)
درون‌خط کردن متغیر(Inline Variable)

۵. تغییر اعلام تابع(Change Function Declaration)

انگیزه:
اگه اسم یه تابع گنگه یا پارامترهاش با نیازهای پروژه جور درنمیاد، این تکنیک بهت کمک می‌کنه اسم یا پارامترها رو عوض کنی. یه اسم خوب یا پارامترهای درست باعث میشه کدت برای خودت و تیمت قابل فهم‌تر بشه.

  • مکانیزم:

  • برای تغییر اسم، یه تابع جدید با اسم موقت بساز.

  • فراخوانی‌های تابع قدیمی رو به تابع جدید هدایت کن.

  • تابع قدیمی رو حذف کن.

  • برای تغییر پارامتر، تغییرات رو یکی‌یکی اعمال کن و تست کن.

مثال(پایتون):

تغییر اعلام تابع(Change Function Declaration)
تغییر اعلام تابع(Change Function Declaration)

۶. کپسوله کردن متغیر(Encapsulate Variable)

انگیزه:
اگه یه متغیر(مثل یه متغیر global یا تو کلاس) مستقیماً تو کد دستکاری میشه، این تکنیک میگه با توابع getter و setter کنترلش کن. این‌جوری می‌تونی مطمئن شی تغییرات معتبرن، جلوی باگ‌های عجیب رو بگیری، و بعداً منطق اضافی(مثل چک کردن داده) بهش اضافه کنی.

مکانیزم:

  • توابع getter و setter برای متغیر بساز.

  • دسترسی‌های مستقیم به متغیر رو با getter/setter جایگزین کن.

  • متغیر رو خصوصی کن(مثلاً با _ تو پایتون).

  • برای داده‌های mutable(مثل لیست)، تو getter کپی برگردون.

مثال(پایتون):

کپسوله کردن متغیر(Encapsulate Variable)
کپسوله کردن متغیر(Encapsulate Variable)

بحثی که پیش میاد اینه که آیا تو پایتون میشه کپسوله‌سازی(Encapsulation) کرد یا نه؟!

کپسوله‌سازی تو پایتون یه کم با زبان‌های دیگه مثل جاوا یا سی‌پلاس‌پلاس فرق داره و ممکنه به نظر بیاد که «معنی نمیده» یا حداقل به اون شکل کلاسیک تو پایتون پیاده‌سازی نمی‌شه.
تو پایتون، برخلاف زبان‌هایی مثل جاوا که با کلیدواژه‌هایی مثل private یا protected دسترسی به متغیرها و متدها رو سخت‌گیرانه کنترل می‌کنن، فلسفه متفاوتی وجود داره. پایتون خیلی روی «ما همه بزرگسالیم» (We're all consenting adults) تأکید داره، یعنی فرض می‌کنه برنامه‌نویس می‌دونه داره چی کار می‌کنه و نباید بیش از حد محدودش کرد. ولی این به این معنی نیست که کپسوله‌سازی تو پایتون بی‌معنیه! فقط مدلش فرق داره و بیشتر به صورت توافق(convention) پیاده می‌شه تا اجبار.

چرا کپسوله‌سازی تو پایتون متفاوته؟

  • عدم وجود private واقعی: تو پایتون، هیچ متغیر یا متدی کاملاً خصوصی نیست. مثلاً:

    • اگه یه متغیر رو با _ شروع کنی(مثل my_var_)، فقط یه توافقه که «این خصوصی‌ست، مستقیم بهش دست نزن». ولی هنوز می‌تونی بهش دسترسی پیدا کنی.

    • اگه از __ (۲تا ) استفاده کنی(مثل my_var__)، پایتون یه چیزی به اسم name mangling انجام میده و اسم متغیر رو عوض می‌کنه(مثلاً به ClassName__my_var)، ولی بازم می‌تونی با یه کم زحمت بهش دسترسی پیدا کنی.

  • فلسفه پایتونیک: پایتون ترجیح میده به جای قفل کردن داده‌ها، روی خوانایی و سادگی تمرکز کنه. اما این باعث نمی‌شه کپسوله‌سازی بی‌فایده باشه.

  • کاربرد واقعی: حتی تو پایتون، کپسوله‌سازی برای کنترل دسترسی، جلوگیری از تغییرات ناخواسته، و اضافه کردن منطق(مثل اعتبارسنجی) به متغیرها خیلی مهمه.

درنهایت چرا این تکنیک‌ها رو باید بلد باشیم؟

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

مارتین فاولر تو کتاب "Refactoring: Improving the Design of Existing Code" همش میگه: «بعد از هر تغییر، حتی اگه یه خط کد عوض کردی، تست رو ران کن!» این حرفش خیلی کلیدیه. فاولر اعتقاد داره که رفیکتورینگ باید با قدم‌های کوچیک و مطمئن باشه، و تست کردن بعد هر تغییر(حتی اگه به نظرت خیلی ساده‌ست) باعث میشه مطمئن شی کدت هنوز درست کار می‌کنه. این کار مثل یه شبکه ایمنیه که نمی‌ذاره باگ‌های عجیب غافلگیرت کنن.
تو بلندمدت، این تست‌های مداوم دیباگ رو خیلی راحت‌تر می‌کنن، چون می‌دونی هر تیکه کدت تو چه مرحله‌ای سالمه و اگه چیزی خراب بشه، سریع می‌فهمی از کجا بوده.

توی پروژه‌هاتون کدوم‌یک از این تکنیک‌ها رو استفاده کردین؟ یا شاید یه تجربه باحال از رفیکتورینگ دارید که کدتون رو حسابی بهتر کرده؟ تو کامنتا برام بنویسید.

ریفکتورینگکلین کدبرنامه نویسیتوسعه نرم افزار
۲
۰
میلاد محمودی
میلاد محمودی
علاقه‌مند به برنامه‌نویسی و پایتون
شاید از این پست‌ها خوشتان بیاید