پادشاهِ کُدنویسا شو!
کینگتو - آموزش برنامه نویسی تخصصصی - دات نت - سی شارپ - بانک اطلاعاتی و امنیت

کد راکد یا Dormant Code چیست؟

10 بازدید 0 نظر ۱۴۰۵/۰۴/۰۴
در دنیای توسعه نرم‌افزار، افزودن ویژگی‌های جدید، بهبود عملکرد و رفع باگ‌ها از اولویت‌های همیشگی تیم‌های فنی است. اما در این مسیر پرشتاب، معمولاً بخش‌هایی از کد به فراموشی سپرده می‌شوند. این بخش‌ها که روزی ممکن است حیاتی بوده‌اند، اکنون بدون استفاده در گوشه‌ای از پروژه باقی مانده‌اند. در اصطلاح تخصصی مهندسی نرم‌افزار، به این بخش‌ها کد راکد یا خفته (Dormant Code) گفته می‌شود.

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

 

کد راکد (Dormant Code) چیست؟

کد راکد (Dormant Code) به بخش‌هایی از سورس‌کد (Source Code) یک نرم‌افزار گفته می‌شود که در حال حاضر در محیط عملیاتی (Production) اجرا نمی‌شوند، توسط هیچ بخش دیگری از برنامه فراخوانی نمی‌شوند و هیچ ارزش افزوده‌ای برای کاربران یا سیستم ایجاد نمی‌کنند، اما همچنان در مخزن کد (Repository) باقی مانده‌اند.

این کدها شامل موارد زیر می‌شوند:

  • توابع و متدهایی که دیگر فراخوانی نمی‌شوند.
  • کلاس‌ها و ماژول‌هایی که با تغییر معماری سیستم، جایگزین شده‌اند اما حذف نشده‌اند.
  • قابلیت‌هایی (Features) که به دلیل تغییر استراتژی کسب‌وکار، غیرفعال شده‌اند.
  • کدهای آزمایشی یا نسخه‌های بتایی که در گذشته برای تست یک ایده نوشته شده بودند.

تفاوت Dormant Code با Dead Code چیست؟

اگرچه در بسیاری از متون تخصصی این دو اصطلاح به جای یکدیگر استفاده می‌شوند، اما یک تفاوت ظریف اما مهم بین آن‌ها وجود دارد:

  • کد مرده (Dead Code): معمولاً به کدهایی گفته می‌شود که کامپایلر یا مفسر به دلیل ساختار منطقی برنامه (مانند شرط‌های همیشه نادرست یا کدهای بعد از دستور return) اصلاً نمی‌تواند به آن‌ها دسترسی پیدا کند (Unreachable Code). کامپایلرهای مدرن اغلب می‌توانند این کدها را تشخیص داده و در زمان بهینه‌سازی حذف کنند.
  • کد راکد (Dormant Code): ساختار منطقی این کدها لزوماً اشتباه نیست و از نظر کامپایلر قابل دسترسی هستند، اما در جریان کاری فعلی نرم‌افزار (Runtime Flow) به دلایل بیزینسی یا تغییرات معماری، فراخوانی نمی‌شوند. این کدها برای کامپایلر زنده، اما برای کسب‌وکار و سیستم مرده هستند.

 

چرا کدها راکد می‌شوند؟ (ریشه‌های ایجاد Dormant Code)

شناسایی دلایل به وجود آمدن کد راکد به تیم‌های توسعه کمک می‌کند تا از بازتولید آن در آینده جلوگیری کنند. مهم‌ترین دلایل عبارتند از:

الف) تغییرات سریع در نیازهای کسب‌وکار (Agile Pivots)

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

ب) استفاده نادرست یا رها کردن Feature Flags

  • امروزه استفاده از فچیر فلگ‌ها (Feature Toggles) برای مدیریت عرضه ویژگی‌های جدید بسیار رایج است. با این حال، اگر فرآیندی برای پاک‌سازی (Cleanup) این فلگ‌ها پس از پایدار شدن ویژگی جدید وجود نداشته باشد، کدهای قدیمیِ پشت فلگ برای همیشه به عنوان کدهای راکد در سیستم باقی می‌مانند.

ج) بازنویسی و مهاجرت‌های ساختاری (Refactoring Migration)

  • هنگام ارتقای یک سیستم قدیمی (Legacy) یا بازنویسی ماژول‌ها، توسعه‌دهندگان کدهای جدیدی می‌نویسند. به دلیل ترس از شکستن بخش‌های دیگر سیستم، کدهای قدیمی اغلب در پروژه باقی می‌مانند تا به عنوان پشتیبان عمل کنند، اما با گذشت زمان به فراموشی سپرده می‌شوند.

د) جابجایی اعضای تیم (Team Turnover)

  • وقتی توسعه‌دهندگان اصلی یک پروژه سازمان را ترک می‌کنند، دانش ضمنی (Tacit Knowledge) مرتبط با بخش‌هایی از کد از بین می‌رود. اعضای جدید تیم به دلیل عدم اگاهی از کارکرد دقیق برخی کلاس‌ها یا توابع، جرات حذف آن‌ها را ندارند و ترجیح می‌دهند به آن‌ها دست نزنند.

 

چرا باید Dormant Code را اصلاح و حذف کرد؟ (مخاطرات پنهان)

نگه داشتن کدهای راکد در پروژه یک خیرخواهی ساده‌لوحانه یا یک سستی بی‌ضرر نیست؛ بلکه یک تهدید جدی برای سلامت فنی و اقتصادی پروژه است. در ادامه دلایل فنی ضرورت اصلاح این کدها را بررسی می‌کنیم.

۱. افزایش بدهی فنی (Technical Debt) و پیچیدگی شناختی

  • هر خط کدی که در پروژه وجود دارد، هزینه‌ای به نام پیچیدگی شناختی (Cognitive Complexity) دارد. وقتی یک توسعه‌دهنده جدید وارد پروژه می‌شود یا می‌خواهد تغییری ایجاد کند، باید تمام کدهای موجود را بخواند و درک کند. وجود کدهای راکد تمرکز تیم را از بین می‌برد، زمان توسعه را طولانی‌تر می‌کند و فرآیند بازنویسی (Refactoring) را به یک کابوس تبدیل می‌سازد.

۲. تهدیدات امنیتی (Security Vulnerabilities)

  • بزرگ‌ترین خطر کدهای راکد، آسیب‌پذیری‌های امنیتی است. کدهای راکد معمولاً به‌روزرسانی نمی‌شوند، تست‌های امنیتی روی آن‌ها انجام نمی‌گیرد و پچ‌های جدید را دریافت نمی‌کنند. با این حال، این کدها همچنان بخشی از ساختار برنامه هستند. هکرها می‌توانند با یافتن مسیرهای پنهان برای فراخوانی این کدهای قدیمی و آسیب‌پذیر، به سیستم نفوذ کنند. به این پدیده در امنیت سایبری، افزایش سطح حمله (Attack Surface) می‌گویند.

۳. اختلال در تست‌های خودکار (Unit Integration Testing)

  • کدهای راکد زمان اجرای تست‌های خودکار (CICD) را طولانی می‌کنند. بدتر از آن، اگر کدهای راکد دارای تست‌های قدیمی باشند، تغییر در بخش‌های دیگر سیستم ممکن است باعث شکست خوردن (Fail) این تست‌ها شود. در این حالت، تیم توسعه مجبور است زمان ارزشمند خود را صرف اصلاح تست کدهایی کند که اصلاً در محیط واقعی اجرا نمی‌شوند!

۴. افت عملکرد سیستم و ابزارهای توسعه

  • زمان کامپایل و بیلد (Build Time): حجم بالای کدهای بلااستفاده، فرآیند کامپایل و بیلد پروژه را سنگین و طولانی می‌کند.

حجم آرتیفکت نهایی: در دنیای موبایل (اپلیکیشن‌های اندروید و iOS) یا میکروسرویس‌ها، حجم فایل نهایی (Binary Size) بسیار مهم است. کدهای راکد باعث حجیم شدن بی‌دلیل اپلیکیشن یا ایمیج‌های داکر (Docker Images) می‌شوند.

۵. تحلیل‌های نادرست ابزارهای اندازه‌گیری (Code Metrics)

  • ابزارهای سنجش کیفیت کد (مانند SonarQube) کدهای راکد را نیز پردازش می‌کنند. این امر باعث می‌شود شاخص‌هایی مانند درصد پوشش تست (Test Coverage) یا تراکم باگ‌ها به صورت غیرواقعی نمایش داده شوند و مدیران فنی نتوانند ارزیابی درستی از وضعیت واقعی پروژه داشته باشند.

 

استراتژی‌ها و ابزارهای شناسایی Dormant Code

حذف کدهای راکد بدون برنامه‌ریزی می‌تواند خطرناک باشد. برای این کار باید از یک رویکرد سیستماتیک و ابزارهای تخصصی استفاده کرد.

الف) تحلیل ایستای کد (Static Code Analysis)

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

Linterها و کامپایلرها: بسیاری از زبان‌های برنامه‌نویسی مدرن (مانند Go، Rust یا TypeScript) گزینه‌هایی برای هشدار در مورد کدهای استفاده‌نشده (مانند unused variables یا unreachable code) دارند.
ابزارهای پیشرفته: ابزارهایی مانند SonarQube، NDepend (برای دات‌نت)، ArchUnit (برای جاوا) و Scrutinizer می‌توانند کدهای راکد و بدون وابستگی را در ابعاد بزرگ شناسایی کنند.

ب) تحلیل پویای کد (Dynamic Code Analysis) و ابزارهای پروفایلینگ

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

ابزارهای Code Coverage در محیط Production: ابزارهایی مانند JaCoCo برای جاوا یا ابزارهای مانیتورینگ عملکرد (APM) مانند New Relic و Dynatrace می‌توانند رفتار برنامه را در محیط واقعی زیر نظر بگیرند و مشخص کنند کدام بخش از کدها در یک بازه زمانی طولانی (مثلاً ۳ تا ۶ ماه) حتی یک‌بار هم اجرا نشده‌اند.

ج) بررسی تاریخچه گیت (Git History Mining)

بررسی تاریخچه کامیت‌ها نشان می‌دهد که کدام فایل‌ها ماه‌ها یا سال‌هاست که دست‌نخورده باقی مانده‌اند. فایل‌هایی با قدمت بالا که هیچ تغییری نکرده‌اند و ارتباط ضعیفی با بخش‌های فعال پروژه دارند، کاندیداهای اصلی Dormant Code هستند.

 

راهنمای گام‌به‌گام اصلاح و پاک‌سازی کدهای راکد

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

  • ۱ شناسایی و مستندسازی با استفاده از ابزارهای تحلیل ایستا و پویا، لیستی از کدهای مشکوک به راکد بودن تهیه کنید. 
  • ۲ بررسی تاریخچه (Git) بررسی کنید که این کد توسط چه کسی و با چه هدفی نوشته شده است. 
  • ۳ جداسازی تدریجی (Deprecation) کد را بلافاصله حذف نکنید. ابتدا آن را به عنوان Deprecated علامت‌گذاری کنید تا در صورت وجود وابستگی پنهان، هشدارهای لازم صادر شود. 
  • ۴ خاموش‌سازی منطقی اگر کد پشتیبان یک ویژگی است، آن را از طریق Feature Flag به طور کامل غیرفعال کنید و مدتی منتظر بمانید. 
  • ۵ حذف کامل و کامیت مستقل کد را پاک کنید. تغییرات مربوط به حذف کد را در یک کامیت یا Pull Request (PR) جداگانه انجام دهید تا در صورت نیاز به بازگشت (Rollback)، کار به سادگی انجام شود. 

یک اصل طلایی برای توسعه‌دهندگان: سیستم کنترل نسخه (Git) برای همین ساخته شده است! از حذف کد نترسید. اگر دو سال بعد به این کد نیاز پیدا کردید، به راحتی می‌توانید آن را از تاریخچه گیت بازیابی کنید. نیازی نیست مخزن زنده پروژه را تبدیل به موزه کدهای قدیمی کنید.

 

روش‌های پیشگیری: چگونه پایگاه کد را تمیز نگه داریم؟

بهترین راه برای مقابله با کدهای راکد، جلوگیری از شکل‌گیری آن‌هاست. برای این منظور، راهکارهای زیر توصیه می‌شود:

  1. فرهنگ پسر پیشاهنگ (Boy Scout Rule): همیشه پایگاه کد را تمیزتر از آنچه تحویل گرفته‌اید، ترک کنید. اگر در حین کار به تابعی برخورد کردید که دیگر استفاده نمی‌شود، همان لحظه آن را حذف کنید.
  2. تعیین تاریخ انقضا برای Feature Flags: برای هر فچیر فلگ، یک بلیت (Ticket) در سیستم مدیریت پروژه (مانند جیرا) برای حذف آن پس از موفقیت‌آمیز بودن عرضه ویژگی جدید ایجاد کنید.
  3. بازبینی دقیق کد (Code Review): در جلسات کد ریویو، به بررسی این نکته بپردازید که آیا کدهای قدیمی مربوط به یک ویژگی بازنویسی‌شده، به طور کامل حذف شده‌اند یا خیر.

 

 

کد راکد (Dormant Code) یک بیماری خاموش در مهندسی نرم‌افزار است. اگرچه در کوتاه‌مدت ممکن است مشکلی ایجاد نکند، اما در بلندمدت با افزایش بدهی فنی، ایجاد روزنه‌های امنیتی، کند کردن سرعت توسعه و سنگین کردن فرآیندهای تست، هزینه‌های سنگینی را به تیم‌ها و سازمان‌ها تحمیل می‌کند.

اصلاح و حذف مداوم کدهای راکد، سرمایه‌گذاری روی آینده پروژه است. پایگاه کدی که عاری از کدهای زائد باشد، چابک‌تر، امن‌تر و برای توسعه‌دهندگان بسیار لذت‌بخش‌تر خواهد بود. با استفاده از ابزارهای مدرن و ایجاد فرآیندهای منظم، پاک‌سازی این کدهای خفته را به بخشی از فرهنگ توسعه خود تبدیل کنید.

 
لینک استاندارد شده: JTN

0 نظر

    هنوز نظری برای این مقاله ثبت نشده است.
جستجوی مقاله و آموزش
دوره‌ها با تخفیفات ویژه