Faragiri

همهٔ زبان‌ها

آموزش بازآرایی کدکد تمیز نوشتن

دو بار قبل و بعد، همان دو عدد: ۲۳۹۴۰۰ و ۱۶۶۵۰۰. بدون این دو عدد، هر تغییر شکلی فقط بازنویسی است و بازنویسی ریسک دارد.

۴بخش
۳دقیقه خواندن
۴عمق

دو کرانه، پنج تخته

از تابع یازده سطری به تابع پانزده سطری، بدون تغییر جواب

دو کرانه دو شکل یک تابع‌اند و تخته‌ها ترتیبی هستند که رفتن از این به آن را بی‌خطر می‌کند.

یازده سطر، عمق ۶چهار شرط تودرتو و نرخ تکرارشده در دو جا
  1. ۰۱جواب فعلی را ثبت کنیددو بار نمونه، دو عدد، پیش از دست زدن به هر سطری
  2. ۰۲بازگشت زودهنگامشرط استثنا بالای حلقه، و یک سطح تورفتگی از کل بدنه کم می‌شود
  3. ۰۳استخراج تابعبلوکی که می‌شود نامش را گفت، با همان جمله نام می‌گیرد
  4. ۰۴عدد جادویی به ثابتنرخی که سه جا تکرار شده یک نام می‌گیرد
  5. ۰۵همان دو عدد را دوباره بگیریداگر یکی عوض شده باشد، این دیگر بازآرایی نبود
پانزده سطر، عمق ۳یک تابع کمکی نام‌دار و یک ثابت برای نرخ

این پنج تخته ترتیب دارند و ترتیبشان مهم است. تخته اول را رد کنید و چهار تخته بعدی هیچ چیزی را ثابت نمی‌کنند.

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

تابع کرایه پیش از تغییر یازده سطر است با چهار if تودرتو و بیشترین عمق تودرتویی ۶. پس از تغییر پانزده سطر است، بیشترین عمقش ۳، و یک تابع کمکی جدا شده که کرایه یک قلم را حساب می‌کند. کد بلندتر شد و خواندنش کوتاه‌تر. اثباتش دو عدد است. هر دو نسخه روی دو بار نمونه صدا زده شدند و جفت جواب‌ها یکسان بود: (239400.0, 166500). اگر این دو عدد را پیش از تغییر ثبت نکرده باشید، پس از تغییر هیچ راهی ندارید که بگویید رفتار عوض نشده، و آن دیگر بازآرایی نیست.

چهار تغییری که تقریبا همیشه جواب می‌دهند

بازگشت زودهنگام به‌جای تودرتویی. نوشتن if qalam is None: continue در ابتدای حلقه یک سطح تورفتگی از کل تابع کم می‌کند و شرط استثنا را از منطق اصلی جدا می‌کند. همین یک تغییر بیشتر عمق‌ها را نصف می‌کند.

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

یک تغییر در هر کامیت

وسوسه این است که همه چهار تغییر بالا در یک نشست انجام شوند. مشکلش موقعی پیدا می‌شود که آن دو عدد عوض شوند و ندانید کدام تغییر مقصر است. هر تغییر شکل باید کامیت خودش را داشته باشد و پیام کامیتش باید بگوید چه شکلی عوض شده، نه اینکه «بهبود کد».

و مهم‌تر: بازآرایی و تغییر رفتار هیچ‌وقت نباید در یک کامیت باشند. اگر هم‌زمان یک باگ را درست کنید و کد را مرتب، بازبین نمی‌تواند بگوید کدام سطر باگ را درست کرد، و دنبال چه بگردید، و چطور بگویید همان‌جا از کار می‌افتد.

جایی که کار گیر می‌کند، کدی است که هیچ آزمونی ندارد

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

ابزار، و سالی که این حرف درست است

در سال ۲۰۲۶، استخراج تابع و تغییر نام و استخراج متغیر هر سه در VS Code با یک میان‌بر انجام می‌شوند و ویرایشگر همه ارجاع‌ها را خودش عوض می‌کند؛ جای بریدن و چسباندن دستی را گرفته، که همان جایی است که ارجاع‌های فراموش‌شده ساخته می‌شوند. برای دیدن اینکه عمق تودرتویی و طول تابع واقعا کم شده‌اند، ruff پیچیدگی هر تابع را گزارش می‌دهد و رایگان است؛ همان عدد است که ادعای «خواناتر شد» را قابل بررسی می‌کند.

پرسش بعدی این است که آن آزمون‌های مشخصه‌ای چه شکلی باید داشته باشند و چقدر باید پوشش بدهند، که یک چیز در هر بار، سریع و جدا جوابش را دارد. و اگر کدی که می‌خواهید مرتب کنید هنوز خطاهایش را قورت می‌دهد، اول شکست پرصدا، شکست بی‌خطر، و فرق این دو را درست کنید.

کنار این

بالای این