جانک (junk code) — کد و وابستگیهایی است که برای پروژه سودی ندارند، اما حجم، زمان ساخت و بار شناختی تیم را افزایش میدهند. برخلاف کد مرده که هرگز اجرا نمیشود، جانک ممکن است کار کند، اما این کار را ناکارآمد یا اضافی انجام میدهد: کتابخانههای تکراری، importهای استفاده نشده، بلوکهای کامنت شده، polyfillهای قدیمی و انتزاعات تزئینی. طبق گزارش CodeScene Code Health Report (2025)، به طور متوسط ۱۵ درصد وابستگیها در پروژههای موبایل مستقیماً استفاده نمیشوند و فقط بستههای ترانزیتی را میکشند. کد آشغال «وزن اضافی» پروژه است: کدبیس را ضخیمتر میکند، اما قویتر نمیکند. حسابرسی منظم وابستگیها و حذف انتزاعات اضافی مستقیماً سرعت ساخت و کیفیت کد را بهبود میبخشد.
نکات کلیدی
جانک (junk code) — اصطلاحی جمعی برای کد، پیکربندیها و وابستگیهایی است که در پروژه وجود دارند اما ارزش عملکردی ندارند. جانک لزوماً خراب یا استفادهنشده نیست — مشکل این است که وجود آن معیارهای پروژه را بدون توجیه مناسب بدتر میکند.
جانک به چهار دسته تقسیم میشود. اول — وابستگیهای اضافی: کتابخانههایی که برای یک تابع که با ابزارهای استاندارد قابل پیادهسازی است متصل شدهاند. دوم — بار مرده: بلوکهای کامنت شده، TODO بدون تیکت، متدهای خالی و کلاسهای placeholder. سوم — راهحلهای تکراری: دو کتابخانه که کار یکسان انجام میدهند (مثلاً Gson و Kotlin Serialization در یک پروژه). چهارم — مهندسی بیش از حد: لایههای معماری که استفاده نمیشوند اما «برای آینده» نگهداری میشوند.
طبق تحقیق Stripe Engineering Productivity (2025)، حذف ۱۰ درصد جانک از یک پروژه معمولی زمان ساخت کامل را به طور متوسط ۲۲ درصد کاهش میدهد. دلیل: هر وابستگی اضافی گراف ساخت را افزایش میدهد، هر انتزاع خالی نیاز به زمان برای درک دارد، هر بلوک کامنت شده توجه را منحرف میکند.
مشکل اصلی در مبارزه با جانک عدم وجود پیامدهای فوری است. پروژه با کد آشغال کامپایل و کار میکند. مشکلات به تدریج انباشته میشوند: ساخت کند میشود، تعداد وابستگیهای ترانزیتی افزایش مییابد و پس از یک سال اضافه کردن یک ویژگی جدید دو برابر بیشتر از آنچه باید طول میکشد.
وابستگیهای junk — کتابخانهها و بستههایی هستند که به پروژه متصل شدهاند اما مستقیماً در کد استفاده نمیشوند، یا فقط در یک تابع که با APIهای استاندارد سادهتر پیادهسازی میشود استفاده میگردند.
مثالهای معمول: کتابخانه برای کار با JSON وقتی پروژه قبلاً از Kotlin Serialization استفاده میکند (دو parser — این جانک است)؛ کتابخانه Apache Commons Lang برای یک متد StringUtils.isEmpty که با extension isNullOrBlank در Kotlin جایگزین میشود؛ کتابخانه DI که در یک ماژول از ده ماژول استفاده میشود و بقیه وابستگیها را دستی از طریق سازنده دریافت میکنند.
هر وابستگی اضافی نه تنها کد اضافی در باینری است. این افزایش سطح حمله برای آسیبپذیریهاست: طبق GitHub Advisory Database (2025)، ۴۰ درصد CVEهای بحرانی در پروژههای موبایل به وابستگیهای ترانزیتی که توسعهدهندگان کنترل نمیکنند مربوط میشود. هرچه وابستگیها کمتر باشند — سطح حمله کوچکتر است.
// مشاهده درخت وابستگی Gradle
./gradlew app:dependencies --configuration releaseRuntimeClasspath
// یافتن وابستگیهای استفاده نشده (پلاگین Gradle)
plugins {
id "com.autonomousapps.dependency-analysis" version "2.0.0"
}
// ایجاد گزارش کتابخانههای استفاده نشده
./gradlew buildHealth
برای iOS از دستور swift package show-dependencies استفاده کنید که درخت کامل وابستگیها را نمایش میدهد. ابزار Xcode Build Timeline نشان میدهد هر کتابخانه چقدر زمان به ساخت اضافه میکند. اگر کتابخانه ۳۰ درصد زمان کامپایل را میگیرد اما در یک صفحه استفاده میشود — این کاندیدای حذف یا جایگزینی است.
برای Node.js (React Native) از depcheck — ابزاری که وابستگیهای استفاده نشده را در package.json پیدا میکند و npm-check که نسخههای قدیمی را نیز نشان میدهد استفاده کنید. قاعدهای اعمال کنید: هر وابستگی جدید باید با توجیه «چرا با ابزارهای استاندارد ممکن نیست» از code review عبور کند.
importهای مرده — رایجترین نوع جانک. آنها بر زمان اجرا تأثیر نمیگذارند اما زمان کامپایل را افزایش میدهند: کامپایلر هر import را حتی اگر استفاده نشود پردازش میکند. در پروژههای بزرگ حذف importهای استفاده نشده زمان ساخت را ۵–۱۰ درصد کاهش میدهد.
IDEهای مدرن به طور خودکار importهای استفاده نشده را با رنگ خاکستری مشخص میکنند. پاکسازی خودکار را هنگام ذخیره فایل تنظیم کنید: در IntelliJ IDEA — Optimize Imports on the fly، در Xcode — Editor > Remove Unused Imports. در CI بررسی اضافه کنید: linter باید commitهای دارای importهای استفاده نشده را مسدود کند.
کد کامنت شده — نوع دیگری از جانک. توسعهدهندگان بلوکها را کامنت میکنند تا هنگام بازآرایی عملکرد را از دست ندهند. اما git تاریخچه کامل تغییرات را نگه میدارد: هر کد حذف شده را میتوان با یک دستور git revert یا git log -S
قاعده: در مخزن کد کامنت شده وجود ندارد. اگر کد لازم نیست — آن را برای همیشه حذف کنید. اگر کد لازم است اما موقتاً غیرفعال شده — از feature toggle با تیکت و مهلت استفاده کنید. کامنتهای // TODO: remove after migration — بدون مهلت نگذارید. تاریخ بگذارید و در تقویم یادآوری تنظیم کنید.
مهندسی بیش از حد — ایجاد لایههای معماری که مشکلات فعلی را حل نمیکنند اما نیاز به نگهداری دارند. این یکی از سختترین انواع جانک است زیرا به طور رسمی کد «درست» است: از SOLID پیروی میکند، با تست پوشش داده شده و با معماری مطابقت دارد. مشکل این است که به آن نیازی نیست.
مثال کلاسیک — کلاس انتزاعی UseCase با یک متد invoke که فقط مخزن را فراخوانی میکند. اگر UseCase منطق اضافه نمیکند (کش کردن، retry، تبدیل)، فقط فراخوانی را منتقل میکند — این موجودیت اضافی است. پیمایش در پروژه را افزایش میدهد: توسعهدهنده UseCase را باز میکند، میبیند invoke → repository — و میبندد. زمان تلف شده، سود صفر.
مثال دیگر — پارامترسازی بیش از حد. اینترفیس generic با شش پارامتر نوع که در یک مکان استفاده میشود. هر پارامتر نوع یک بار شناختی است: هنگام خواندن کد باید شش نوع را در ذهن نگه داشت در حالی که فقط دو نوع واقعاً استفاده میشود. اگر انتزاع استفاده مجدد نمیشود — اضافی است.
معیار قطع: اگر انتزاع در سه زمینه مختلف استفاده مجدد نمیشود — آن را حذف کنید. انتزاع وقتی توجیه دارد که واقعاً مشکل تکراری بودن را حل کند، نه اینکه سناریوهای فرضی آینده را پیشبینی کند. YAGNI (You Ain't Gonna Need It) — بهترین اصل پیشگیری از مهندسی بیش از حد است.
حسابرسی جانک به ترکیبی از تحلیل ایستا، تحلیل وابستگیها و بررسی دستی نیاز دارد. نمیتوان جستجوی انتزاعات اضافی را کاملاً خودکار کرد، اما جانک فنی (importهای مرده، کتابخانههای استفاده نشده، کد کامنت شده) با ابزارها پیدا میشود.
| دسته | ابزار | چه چیزی را بررسی میکند |
|---|---|---|
| وابستگیهای استفاده نشده | dependency-analysis (Gradle) | کتابخانههایی که در کد استفاده نمیشوند |
| وابستگیهای استفاده نشده | depcheck (Node.js) | بستههای package.json بدون import |
| وابستگیهای استفاده نشده | swift package --show-dependencies | درخت وابستگی SwiftPM |
| importهای مرده | IDE (Optimize Imports) | عبارتهای import استفاده نشده |
| کد کامنت شده | grep -r "//" / rg "^\s*//" | بلوکهای کامنت با کد |
| متدها/کلاسهای خالی | SonarQube / CodeClimate | متدهای بدون بدنه یا با بدنه خالی |
| کتابخانههای تکراری | Gradle lint (duplicate classes) | تعارض کلاسها از کتابخانههای مختلف |
برای حسابرسی کامل هر اسپرینت buildHealth (Android) یا depcheck (Node.js) را اجرا کنید. در CI داشبوردی ایجاد کنید که پویایی تعداد وابستگیها را در طول اسپرینتها نشان دهد. اگر تعداد افزایش مییابد اما کارایی متناسب افزایش نمییابد — تیم در حال انباشتن جانک است.
به duplicate classes توجه کنید — خطایی که دو کتابخانه حاوی یک کلاس هستند. این نه تنها جانک است، بلکه منبع مستقیم تعارضات ساخت است. در Gradle چنین تعارضاتی از طریق force یا exclude حل میشوند، اما هر چنین راهحلی نشانهای است که یکی از کتابخانهها اضافی است.
تمیز کردن جانک یک اقدام یکباره نیست، بلکه یک فرآیند منظم است. بدون مقررات، جانک در عرض دو تا سه اسپرینت برمیگردد. بهترین روش — اختصاص ۱۰–۱۵ درصد ظرفیت هر اسپرینت به تمیزکاری فنی، از جمله حسابرسی جانک است.
فرآیند از چهار مرحله تشکیل شده است. اول — تشخیص: اجرای ابزارها، دریافت گزارش، اولویتبندی. اولویت بالا — وابستگیهای دارای CVE شناخته شده و کتابخانههای تکراری. متوسط — importهای مرده و کد کامنت شده. پایین — انتزاعات اضافی (نیازمند تحلیل دستی).
دوم — تمیز کردن: حذف وابستگیهای مرده، جایگزینی کتابخانههای تکراری با یکی، حذف کد کامنت شده. هر تغییر با یک commit جداگانه با پیام قابل فهم: «remove unused dependency: gson (replaced by kotlinx.serialization)»، «delete commented code in LoginViewModel».
سوم — تأیید: ساخت پروژه، اجرای تستها، بررسی UI. اگر پس از حذف وابستگی تستها عبور کنند — وابستگی واقعاً غیرضروری بود. اگر تستها شکست بخورند — یعنی جایی یک مرجع پنهان باقی مانده که تحلیلگر ایستا کشف نکرده است.
چهارم — پیشگیری: بهروزرسانی چکلیست code review، اضافه کردن قانون «هیچ وابستگی جدید بدون توجیه» به Definition of Done، تنظیم بررسی خودکار در CI. پیشگیری تنها راه جلوگیری از انباشت مجدد جانک است.
سوالات متداول
بدهی فنی یک تصمیم مصالحهای آگاهانه (سریع اما بیکیفیت) است که برنامهریزی برای رفع آن وجود دارد. جانک یک تصمیم آگاهانه نیست، بلکه زبالههای انباشته شده است: وابستگیهای اضافی، کد کامنت شده، انتزاعات خالی که هیچکس برنامهریزی نکرده و نمیخواهد از آنها نگهداری کند.
ریتم بهینه — هر اسپرینت ۱۰ درصد زمان را به تمیزکاری فنی اختصاص دهید. این امکان را میدهد جانک را بدون انباشتن جرم بحرانی تحت کنترل نگه دارید. اگر جانک در پروژه زیاد است — با یک اسپرینت بزرگ تمیزکاری شروع کنید و سپس به ریتم منظم بروید.
اعداد را اندازه بگیرید و نشان دهید: زمان ساخت را قبل و بعد از حذف ۳–۵ وابستگی اضافی اندازه بگیرید. صرفهجویی ۱۵–۳۰ ثانیهای در هر ساخت ضرب در تعداد ساختهای روزانه ساعتها زمان صرفهجویی شده تیم را به دست میدهد. اعداد بهتر از درخواستهای انتزاعی برای پاکیزگی متقاعد میکنند.
بله، به خصوص اگر وابستگی CVE داشته باشد. حتی اگر پروژه پایدار باشد، آسیبپذیری در وابستگی ترانزیتی یک ریسک امنیتی است. علاوه بر این، هنگام بهروزرسانی SDK یا زبان، وابستگی قدیمی ممکن است ناسازگار شود و حذف آن قبل از ارتقاء ساعتها زمان مهاجرت را صرفهجویی میکند.
هر TODO بدون تیکت جانک است. قاعدهای تعیین کنید: TODO فقط در قالب // TODO(PROJECT-1234): fix با پیوند به وظیفه در ردیاب نوشته میشود. مرتباً TODOها را بررسی کرده و آنهایی که اهمیت خود را از دست دادهاند ببندید. TODOهای منقضی شده را حذف کنید — اگر مشکل در شش ماه ظاهر نشده، بحرانی نیست.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.