بوی کد

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

اصطلاح کد بو توسط کنت بک در WardsWiki در اواخر ۱۹۹۰ رواج داده شد. بعد از به کار رفتن در کتاب Refactoring: Improving the Design of Existing Code نوشتهٔ مارتین فاولر در سال ۱۹۹۹، استفاده از این اصطلاح بیشتر هم شد. همچنین در متد توسعهٔ چابک نرم‌افزار این اصطلاح به کار می‌رود.

تعریف 
یک شیوه برای نگاه به کد بو در نظر گرفتن اصول و کیفیت طراحی است: «بوهای کد ساختارهایی مشخص در کد هستند که اصول پایه‌ای برنامه‌نویسی را به گونه‌ای نقض کرده‌اند و کیفیت طراحی را پایین آورده‌اند».

در واقع بوهای بد کد باگ محسوب نمی‌شوند به این معنا که مانع از کارکرد صحیح برنامه نمی‌شوند. آنها ضعف‌هایی در طراحی را نمایان می‌کنند که باعث کند شدن روند توسعه هستند یا ریسک ایجاد باگ یا خرابی در آینده را افزایش می‌دهند.

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

یک تحقیق در سال 2015 نیم میلیون کامیت را به صورت خودکار و ۹۱۶۴ کامیت را به صورت دستی بررسی کرد و دربارهٔ «کد بو» به نتایج زیر رسید:
 شواهد تجربی مبنی بر عواقب «بدهی فنی» وجود دارد ولی فقط شواهد گفتاری وجود دارد که چگونه، کِی و چرا آنها رخ می‌دهند.
 کارهای اضطراری برای نگهداری کد و فشار برای تحویل ویژگی‌ها (features) و ترجیح کاهش time-to-market بر کیفیت کد، معمولاً دلایل ایجاد کد بو هستند.

ابزارهایی مانند Checkstyle, PMD, FindBugs و SonarQube برای تشخیص خودکار بوی بد کد استفاده می‌شوند.

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

بوهای بد کد در سطح کلاس:
 کلاس حجیم: یک کلاس که بیش از اندازه رشد کرده. شیء خدا را ببینید.
 حسادت بر ویژگی‌ها: استفادهٔ بیش از حد یک کلاس از متدهای کلاسی دیگر.
 صمیمیت بی‌جا: یک کلاس که به جزئیات پیاده‌سازی کلاسی دیگر وابسته است. Object Orgy را ببینید.
 وصیت عمل‌نشده: یک کلاس، متدی از کلاس والد خود را طوری override کند که قاعدهٔ جانشانی لیسکوف نقض شود.
 کلاس تنبل: یک کلاس که کار بسیار کوچکی انجام می‌دهد.
 استفادهٔ بیش از حد از مقادیر ثابت (literal): این مقادیر باید به عنوان متغیرهای constant به کار روند، برای جلوگیری از خطای برنامه‌نویسی و بالا بردن خوانایی کد. علاوه بر اینها، مقادیر ثابت باید در فایل‌های جدا ذخیره شوند.
 پیچیدگی سایکلومتیک: شاخه‌ها یا حلقه‌های زیاد؛ این می‌تواند حاکی از وجود تابعی باشد که می‌بایست به توابعی کوچکتر شکسته شود یا اینکه نیاز به ساده‌سازی/بازسازی داشته باشد.
 Downcasting: یک تبدیل نوع که مدل انتزاع را می‌شکند. مدل انتزاع باید حذف یا بازسازی شود.
 متغیر یتیم یا کلاس ثابت: یک کلاس که مجموعه‌ای از مقادیر ثابت را در اختیار دارد که این مقادیر در کلاس‌های دیگری به کار رفته‌اند.
 توده داده: زمانی که گروهی از متغیرها به همراه هم به قسمت‌های مختلف برنامه پاس داده می‌شوند. به‌طور کلی راه حل این است که این متغیرها در قالب یک شیء تجمیع شوند و آن شیء به قسمت‌های مختلف برنامه پاس داده شود.

بوهای بد کد در سطح متد:
 تعداد زیاد پارامتر: یک لیست طولانی از پارامترها خوانایی ضعیفی دارد و فراخوانی و تست تابع را پیچیده می‌کند. این اشکال ممکن است ناشی از تعریف بد تابع باشد.
 متد طولانی: متد یا تابعی که بیش از حد رشد کرده باشد.
 نام‌های بیش از اندازه طولانی: انتخاب نام‌های بسیار طولانی برای متغیرها، توابع، نوع متغیرها و سایر موجودیت‌های برنامه.
 نام‌های بیش از اندازه کوتاه: نام هر موجودیتی در کد باید وظیفهٔ آن را بیان کند مگر اینکه وظیفهٔ مورد نظر واضح و بدیهی باشد.
 دادهٔ بیش از حد نیاز در خروجی: یک تابع نباید بیش از نیاز هر فراخواننده‌اش، داده خروجی دهد.
 کامنت طولانی: برای مثال کامنت برای متدهای setter/getter.
 اشیاء حجیم (god objects): یک کلاس که وظایف زیادی بر عهده دارد و چسبندگی ضعیفی دارد.
 خط کد طولانی: خوانایی را پایین آورده؛ همچنین فهم، دیباگ، بازسازی و امکان استفاده مجدد کد را سخت می‌کند. برای مثال:
 new XYZ(s).doSomething(buildParam1(x), buildParam2(x), buildParam3(x), a + Math.sin(x)*Math.tan(x*y + z)).doAnythingElse().build().sendRequest();

جستارهای وابسته 
 ضد الگو
 طراحی بو
 لیست ابزارها برای آنالیز کد به صورت ایستا
 پوسیدگی نرم‌افزاری
 مهندسی نرم‌افزار
 علوم رایانه

پانویس

منابع 

ضد الگو
فرهنگ مردمی برنامه‌نویسی رایانه‌ای
فرهنگ مردمی مهندسی نرم‌افزار