فصل دوازدهم: استفاده از ابزارها برای بهبود کیفیت کد 🛠️

به عنوان یک برنامه‌نویس، ارتقای کیفیت کد یکی از مهم‌ترین دغدغه‌های شماست. بهبود کیفیت کد نیازمند استفاده از ابزارهای مختلف است. ابزارهایی که برای بهبود کد و همچنین سرعت بخشیدن به توسعه طراحی شده‌اند، شامل code metrics، quick actions، پروفایلر JetBrains dotTrace، JetBrains ReSharper و Telerik JustDecompile هستند.

در این فصل، ما عمدتاً روی موارد زیر تمرکز خواهیم کرد:

در پایان این فصل، شما مهارت‌های زیر را کسب خواهید کرد:


نیازمندی‌های فنی 💻


تعریف کد با کیفیت بالا ✅

کیفیت بالای کد یک ویژگی اساسی نرم‌افزار است. کد با کیفیت پایین می‌تواند منجر به ضرر مالی، اتلاف وقت و تلاش، و حتی خطرات جانی شود. کد با استاندارد بالا باید ویژگی‌های زیر را داشته باشد: Performance, Availability, Security, Scalability, Maintainability, Accessibility, Deployability, Extensibility (PASSMADE)

از ویژگی‌های PASSMADE می‌توان مشکلات احتمالی ناشی از عدم رعایت این استانداردها را پیش‌بینی کرد:


Code Metrics به کمک می‌آید 📏

Code metrics به توسعه‌دهندگان امکان می‌دهد پیچیدگی و نگهداری‌پذیری کد را اندازه‌گیری کنند و کدهایی که نیاز به Refactoring دارند را شناسایی کنند.

در ادامه، به بررسی دقیق‌تر ابزارها خواهیم پرداخت، ابتدا با Code Metrics شروع می‌کنیم. ✅

انجام پاک‌سازی کد و محاسبه Code Metrics 🧹📏

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


معیارهای کد که Visual Studio 2019 محاسبه می‌کند، شامل موارد زیر است

۱. Maintainability Index (شاخص نگهداری‌پذیری)
نگهداری کد یک بخش ضروری از Application Lifecycle Management (ALM) است. تا زمانی که نرم‌افزار به پایان عمر خود نرسد، باید نگهداری شود. هر چه نگهداری کد دشوارتر باشد، طول عمر کد منبع قبل از نیاز به جایگزینی کامل کوتاه‌تر است.

نوشتن نرم‌افزار جدید برای جایگزینی یک سیستم مشکل و هزینه‌بر، بسیار بیشتر از نگهداری یک سیستم موجود است. شاخصی که برای اندازه‌گیری نگهداری‌پذیری کد استفاده می‌شود، Maintainability Index نام دارد. این مقدار یک عدد صحیح بین ۰ تا ۱۰۰ است.

رده‌بندی Maintainability Index، رنگ‌ها و معانی آن‌ها:


۲. Cyclomatic Complexity (پیچیدگی سیکلوما‌تیک)
پیچیدگی کد، که به آن Cyclomatic Complexity نیز گفته می‌شود، به تعداد مسیرهای مختلف کد در نرم‌افزار اشاره دارد. هر چه مسیرها بیشتر باشند، نرم‌افزار پیچیده‌تر است. هر چه نرم‌افزار پیچیده‌تر باشد، تست و نگهداری آن دشوارتر می‌شود.

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


۳. Depth of Inheritance (عمق ارث‌بری)
معیار Depth of Inheritance و Class Coupling تحت تأثیر Object-Oriented Programming (OOP) قرار دارند. در OOP، کلاس‌ها می‌توانند از کلاس‌های دیگر ارث‌بری کنند.

عمق ارث‌بری، تعداد کلاس‌هایی است که از یکدیگر ارث می‌برند. هر چه عمق ارث‌بری بیشتر باشد، احتمال خطا در کلاس‌های مشتق‌شده هنگام تغییر در کلاس‌های پایه بیشتر است. عمق ارث‌بری ایده‌آل = ۱


۴. Class Coupling (وابستگی کلاس‌ها)
OOP امکان Coupling کلاس‌ها را فراهم می‌کند. وابستگی کلاس زمانی رخ می‌دهد که یک کلاس مستقیماً توسط پارامتر، متغیر محلی، نوع بازگشتی، فراخوانی متد، نمونه‌سازی Generic یا Template، کلاس‌های پایه، پیاده‌سازی Interface، فیلدهای تعریف‌شده روی نوع‌های اضافی و Attribute Decoration ارجاع داده شود.

معیار Class Coupling سطح وابستگی بین کلاس‌ها را تعیین می‌کند. برای نگهداری و توسعه آسان‌تر کد، Class Coupling باید حداقل باشد.
در OOP، یک راه برای دستیابی به این هدف استفاده از Interface-based Programming است. این روش امکان تعویض کلاس‌ها را فراهم می‌کند، به شرطی که همان Interface را پیاده‌سازی کنند.

نکته: نرم‌افزار باید Cohesion بالا و Coupling پایین داشته باشد، چون تست، نگهداری و توسعه آن را آسان‌تر می‌کند.


۵. Lines of Source Code (تعداد خطوط کد منبع)
تعداد کل خطوط کد منبع شما، شامل خطوط خالی، با این معیار اندازه‌گیری می‌شود.

۶. Lines of Executable Code (تعداد خطوط کد اجرایی)
تعداد عملیات در کد اجرایی با این معیار سنجیده می‌شود.


شروع استفاده از Code Metrics در Visual Studio 2019 🖥️

حالا که با Code Metrics و معیارهای موجود در Visual Studio 2019 نسخه 16.4 به بعد آشنا شدید، وقت آن است که آنها را عملی ببینیم:

1️⃣ هر پروژه‌ای که می‌خواهید در Visual Studio باز کنید
2️⃣ روی پروژه راست‌کلیک کنید
3️⃣ گزینه Analyze and Code Cleanup | Run Code Cleanup (Profile 1) را انتخاب کنید، همان‌طور که در تصویر زیر نشان داده شده است

Conventions-UsedThis-Book

4️⃣ اکنون گزینه Calculate Code Metrics را انتخاب کنید.

5️⃣ باید پنجره Code Metrics Results ظاهر شود، همان‌طور که در تصویر زیر نشان داده شده است. ✅

Conventions-UsedThis-Book

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

خب، حالا که با Code Metrics آشنا شدیم، طبیعتاً به سراغ Code Analysis می‌رویم. 🔍


انجام تحلیل کد (Performing Code Analysis) 🛠️

برای کمک به توسعه‌دهندگان در شناسایی مشکلات بالقوه در کد منبع، شرکت Microsoft ابزار Code Analysis را به عنوان بخشی از Visual Studio ارائه کرده است.

Code Analysis یک تحلیل Static روی کد منبع انجام می‌دهد و می‌تواند موارد زیر را شناسایی کند:


برای استفاده از این ابزار:

1️⃣ راه‌حل کتاب را باز کنید و پروژه CH11_AddressingCrossCuttingConcerns را انتخاب کنید
2️⃣ از منوی Project مسیر زیر را انتخاب کنید:
Project | CH11_AddressingCrossCuttingConcerns | Properties
3️⃣ در صفحه Properties پروژه، گزینه Code Analysis را انتخاب کنید، همان‌طور که در تصویر زیر نشان داده شده است ✅

Conventions-UsedThis-Book

همان‌طور که در تصویر قبلی مشاهده می‌کنید، اگر ببینید که پکیج Analyzer پیشنهادی نصب نشده است، روی Install کلیک کنید تا نصب شود.

پس از نصب، شماره نسخه در Installed Version Box نمایش داده می‌شود. برای من، نسخه 2.9.6 است.

به طور پیش‌فرض، Active Rules روی Microsoft Managed Recommended Rules تنظیم شده است.
محل این Ruleset، همان‌طور که در توضیحات نشان داده شده، به صورت زیر است:

C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\Team Tools\Static Analysis Tools\Rule Sets\MinimumRecommendedRules.ruleset

فایل را باز کنید. این فایل به صورت یک پنجره ابزار در Visual Studio باز خواهد شد، همان‌طور که در تصویر زیر مشاهده می‌کنید. ✅

Conventions-UsedThis-Book

همان‌طور که در تصویر قبلی مشاهده می‌کنید، می‌توانید قوانین (Rules) را انتخاب یا لغو انتخاب کنید. وقتی پنجره را بستید، از شما خواسته می‌شود تغییرات را ذخیره کنید.

برای اجرای Code Analysis، مسیر زیر را دنبال کنید:
Analyze and Code Cleanup | Code Analysis

برای مشاهده نتایج، باید پنجره Error List باز باشد. می‌توانید آن را از منوی View باز کنید.

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

نمونه‌ای از این نتایج را می‌توان در تصویر زیر مشاهده کرد ✅

Conventions-UsedThis-Book

همان‌طور که در تصویر قبلی مشاهده می‌کنید، پروژه CH10_AddressingCrossCuttingConcerns دارای ۳۲ هشدار و ۱۳ پیام است. اگر روی این هشدارها و پیام‌ها کار کنیم، می‌توانیم تعداد آن‌ها را به ۰ هشدار و ۰ پیام کاهش دهیم.

حالا که دیدید چگونه با استفاده از Code Metrics می‌توان میزان نگهداری‌پذیری نرم‌افزار را سنجید و با تحلیل کد، نقاط قابل بهبود را پیدا کرد، وقت آن است که به Quick Actions نگاهی بیندازیم. ⚡


استفاده از Quick Actions 🛠️💡

یکی دیگر از ابزارهای مفیدی که من دوست دارم استفاده کنم، ابزار Quick Action است. این ابزار معمولاً به صورت پیچ‌گوشتی 🪛، لامپ 💡 یا لامپ خطا 💡⚠️ در کنار یک خط کد ظاهر می‌شود.

با Quick Actions می‌توانید با یک دستور:

از آنجا که پروژه CH10_AddressingCrossCuttingConcerns دارای ۳۲ هشدار و ۱۳ پیام بود، می‌توانیم از این پروژه برای مشاهده عملکرد Quick Actions استفاده کنیم.

به تصویر زیر نگاه کنید تا عملکرد Quick Actions را ببینید ✅

Conventions-UsedThis-Book

با نگاه به تصویر قبلی، می‌بینیم لامپ 💡 روی خط ۱۰ ظاهر شده است.

اگر روی لامپ کلیک کنیم، منوی زیر ظاهر می‌شود ✅

Conventions-UsedThis-Book

اگر روی گزینه Add readonly modifier کلیک کنیم، Access Modifier مربوط به readonly بعد از private قرار می‌گیرد.

خودتان با استفاده از Quick Actions کد را تغییر دهید. وقتی با آن کار کنید، روند کار نسبتاً ساده است. پس از تمرین با Quick Actions، به سراغ ابزار JetBrains dotTrace Profiler می‌رویم. ⚡


استفاده از پروفایلر JetBrains dotTrace 🖥️📊

پروفایلر JetBrains dotTrace بخشی از JetBrains ReSharper Ultimate است. از آنجا که در این فصل به هر دو ابزار نگاه می‌کنیم، توصیه می‌کنم قبل از ادامه، JetBrains ReSharper Ultimate را دانلود و نصب کنید.

JetBrains نسخه Trial هم ارائه می‌دهد، در صورتی که نسخه اصلی را ندارید. نسخه‌هایی برای Windows، macOS و Linux موجود است.

پروفایلر dotTrace با Mono، .NET Framework و .NET Core کار می‌کند. تمام انواع برنامه‌ها توسط این پروفایلر پشتیبانی می‌شوند و می‌توانید از آن برای تحلیل و یافتن مشکلات Performance در کد استفاده کنید. این ابزار به شما کمک می‌کند مشکلاتی مانند:

بسیاری از برنامه‌ها درخواست‌های HTTP ارسال می‌کنند. پروفایلر تحلیل می‌کند که چگونه برنامه این درخواست‌ها را پردازش می‌کند، و همین کار را برای SQL Queries روی پایگاه داده نیز انجام می‌دهد. همچنین می‌توانید Static Methods و Unit Tests را پروفایل کنید و نتایج را داخل Visual Studio مشاهده کنید. نسخه‌ای Standalone نیز موجود است.


چهار گزینه اصلی پروفایلینگ 📈

  1. Sampling: اندازه‌گیری دقیق زمان فراخوانی متدها، مناسب برای شروع
  2. Tracing: جزئیات بیشتر پروفایلینگ، با overhead بالاتر (CPU و حافظه)
  3. Line-by-Line: تحلیل دقیق خط به خط، با overhead بیشتر
  4. Timeline: مشابه Sampling، اما Events برنامه را در طول زمان جمع‌آوری می‌کند

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

گزینه‌های پیشرفته پروفایلینگ شامل:


پروفایل کردن برنامه‌ها

پروفایلر می‌تواند به برنامه‌ها و پردازه‌های در حال اجرای .NET Framework 4.0 یا بالاتر و .NET Core 3.0 یا بالاتر متصل شود، برنامه‌های محلی و راه دور را پروفایل کند.
این شامل موارد زیر است:


دسترسی به پروفایلر در Visual Studio 2019

از منوی Extensions | ReSharper | Profile | Show Performance Profiler استفاده کنید.

در تصویر زیر می‌بینید که هنوز هیچ پروفایلی اجرا نشده است. پروژه انتخاب‌شده Basic CH3 است و نوع پروفایلینگ روی Timeline تنظیم شده است.

برای پروفایل کردن پروژه CH3 با Sampling، Timeline Dropdown را باز کرده و Sampling را انتخاب کنید، همان‌طور که در تصویر بعدی نشان داده شده است ✅

Conventions-UsedThis-Book

اگر بخواهید پروژه دیگری را پروفایل کنید، کافی است Drop-down لیست Project را باز کرده و پروژه موردنظر خود را انتخاب کنید.

پروژه ساخته (Build) می‌شود و پروفایلر شروع به کار می‌کند. سپس پروژه شما اجرا شده و خاموش می‌شود.

نتایج در dotTrace Profiling Application نمایش داده می‌شوند، همان‌طور که در تصویر زیر مشاهده می‌کنید ✅

Conventions-UsedThis-Book

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

موارد منوی All Calls در سمت چپ شامل موارد زیر است:

در حال حاضر، گزینه Thread Tree انتخاب شده است.
حال نگاهی به Call Tree گسترش یافته در تصویر بعدی می‌اندازیم ✅

Conventions-UsedThis-Book

پروفایلر Call Tree کامل کد شما را نشان می‌دهد، که شامل کد سیستم و کد خودتان است.
شما می‌توانید درصد زمان صرف‌شده برای هر فراخوانی را مشاهده کنید. این امکان به شما می‌دهد تا متدهای طولانی را شناسایی کرده و آن‌ها را بهبود دهید.

حال، به Plain List نگاه می‌کنیم. همان‌طور که در تصویر بعدی مشاهده می‌کنید، در Plain List View می‌توانیم داده‌ها را بر اساس معیارهای زیر گروه‌بندی کنیم:

معیارهای فوق را می‌توانید در تصویر زیر مشاهده کنید ✅

Conventions-UsedThis-Book

وقتی روی یک مورد در لیست کلیک می‌کنید، می‌توانید کد منبع کلاسی که متد در آن قرار دارد را مشاهده کنید.

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

آخرین صفحه پروفایلینگ با Sampling که بررسی می‌کنیم، Hot Spots View است، همان‌طور که در تصویر زیر نشان داده شده است ✅

Conventions-UsedThis-Book

پروفایلر نشان می‌دهد که Main Thread، که نقطه شروع کد ما است، تنها ۴.۵۹٪ از زمان پردازش را به خود اختصاص می‌دهد.

اگر روی Root کلیک کنید، مشاهده می‌کنید که ۱۸٪ کد مربوط به کد کاربر است و ۷۲٪ کد مربوط به کد سیستم می‌باشد، همان‌طور که در تصویر زیر نشان داده شده است ✅

Conventions-UsedThis-Book

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

برای اطلاعات بیشتر درباره نحوه استفاده از JetBrains dotTrace، می‌توانید به منابع آموزشی آنلاین آن‌ها مراجعه کنید:
JetBrains dotTrace Documentation 📚


استفاده از JetBrains ReSharper 🛠️✨

در این بخش، می‌بینیم که چگونه JetBrains ReSharper می‌تواند به بهبود کد شما کمک کند.

ReSharper یک ابزار گسترده است و همانند پروفایلر که بخشی از نسخه Ultimate آن است، ما تنها به بررسی ابتدایی امکانات آن می‌پردازیم. هدف این است که با قابلیت‌های ابزار آشنا شوید و بدانید چگونه می‌تواند تجربه کدنویسی شما در Visual Studio را بهبود دهد.


چند مزیت استفاده از ReSharper


برای دسترسی به منوی ReSharper، از منوی Extensions در Visual Studio 2019 استفاده کنید.
وقتی در Code Editor هستید، با راست‌کلیک روی کد، منوی Context باز می‌شود و آیتم‌های مرتبط نمایش داده می‌شوند.
آیتم منوی ReSharper در Context Menu، Refactor This… است، همان‌طور که در تصویر زیر نشان داده شده ✅

Conventions-UsedThis-Book

حالا، از منوی Visual Studio 2019 مسیر زیر را اجرا کنید:
Extensions | ReSharper | Inspect | Code Issues in Solution

ReSharper پروژه را پردازش کرده و سپس پنجره Inspection Results را نمایش می‌دهد، همان‌طور که در تصویر زیر مشاهده می‌کنید ✅

Conventions-UsedThis-Book

همان‌طور که در تصویر قبلی مشاهده می‌کنید، ReSharper تعداد ۵۲۷ مشکل را در کد ما پیدا کرده است، که ۴۳۶ مورد از آن‌ها نمایش داده شده‌اند. این مشکلات شامل موارد زیر می‌شوند:


اگر بخش Compiler Warnings را باز کنیم، سه مشکل مشاهده می‌کنیم:

  1. فیلد _name هیچ‌گاه مقداردهی نمی‌شود.
  2. متغیر محلی nre هرگز استفاده نمی‌شود.
  3. این متد async فاقد await است و به صورت هم‌زمان (Synchronous) اجرا می‌شود. از await برای فراخوانی‌های غیرمسدودکننده API یا await TaskEx.Run(...) برای کارهای CPU-bound در Thread پس‌زمینه استفاده کنید.

این مشکلات شامل اعلان متغیرهایی است که مقداردهی یا استفاده نمی‌شوند و همچنین متد async که فاقد await است و به صورت هم‌زمان اجرا می‌شود.


اگر روی اولین هشدار کلیک کنید، به خط کدی می‌روید که مقداردهی نشده است. با نگاه به کلاس، می‌بینیم که رشته (string) اعلان شده و استفاده می‌شود، اما هرگز مقداردهی نشده است. از آنجا که بررسی می‌کنیم آیا رشته string.Empty است، می‌توانیم آن را مقداردهی کنیم:

private string _name = string.Empty;

چون متغیر _name هنوز هایلایت است، می‌توانیم ماوس را روی آن ببریم و ببینیم مشکل چیست. Quick Action به ما می‌گوید که می‌توان _name را readonly کرد. پس آن را اضافه می‌کنیم:

private readonly string _name = string.Empty;

اگر روی دکمه Refresh کلیک کنیم، می‌بینیم که تعداد مشکلات یافت‌شده اکنون ۵۲۶ است. اما ما دو مشکل را رفع کردیم. پس چرا تعداد ۵۲۵ نیست؟ دلیل این است که دومین مشکلی که رفع شد، توسط ReSharper شناسایی نشده بود، بلکه یک بهبود بود که توسط Visual Studio Quick Actions پیشنهاد شد. بنابراین ReSharper تعداد صحیح مشکلات شناسایی‌شده را نشان می‌دهد. ✅


حالا به مسئله احتمالی کیفیت کد (Potential Code Quality Issue) برای کلاس LooseCouplingB نگاه می‌کنیم. ReSharper گزارش می‌دهد که امکان بروز System.NullReferenceException در این متد وجود دارد:

public LooseCouplingB()
{
    LooseCouplingA lca = new LooseCouplingA();
    lca = null;
    Debug.WriteLine($"Name is {lca.Name}");
}

همان‌طور که می‌بینیم، System.NullReferenceException در کد قابل مشاهده است.

برای بررسی کلاس LooseCouplingA و تعیین اینکه کدام اعضا باید مقداردهی شوند، می‌بینیم عضو _name باید مقداردهی شود:

public string Name
{
    get => _name.Equals(string.Empty) ? StringIsEmpty : _name;
    set
    {
        if (value.Equals(string.Empty))
            Debug.WriteLine("Exception: String length must be greater than zero.");
    }
}

با توجه به اینکه _name برای خالی بودن بررسی می‌شود، در واقع باید _name به string.Empty مقداردهی شود. پس کانستراکتور اصلاح‌شده LooseCouplingB به صورت زیر می‌شود:

public LooseCouplingB()
{
    var lca = new LooseCouplingA
    {
        Name = string.Empty
    };
    Debug.WriteLine($"Name is {lca.Name}");
}

اگر پنجره Inspection Results را Refresh کنیم، می‌بینیم تعداد مشکلات ۵ کاهش یافته است، زیرا علاوه بر مقداردهی صحیح Property، از فرصت استفاده از زبان برای ساده‌سازی Instantiation و Initialization نیز استفاده کردیم که توسط ReSharper شناسایی شد.


ReSharper همچنین می‌تواند Dependency Diagram تولید کند. برای تولید نمودار وابستگی پروژه، مسیر زیر را انتخاب کنید:
Extensions | ReSharper | Architecture | Show Project Dependency Diagram

این نمودار وابستگی پروژه را نمایش می‌دهد.

همان‌طور که در تصویر زیر نشان داده شده است ✅

Conventions-UsedThis-Book

همان‌طور که در Project Dependency Diagram مربوط به Namespace CH06 مشاهده می‌کنید، یک وابستگی پروژه بین CH06_SpecFlow و CH06_SpecFlow.Implementation وجود دارد.

به همین ترتیب، می‌توانید با استفاده از ReSharper، Type Dependency Diagrams نیز تولید کنید. مسیر زیر را انتخاب کنید:
Extensions | ReSharper | Architecture | Type Dependencies Diagram

اگر نمودار را برای ConcreteClass در پروژه CH10_AddressingCrossCuttingConcerns تولید کنیم، نمودار ساخته می‌شود، اما در ابتدا تنها کلاس ConcreteComponent نمایش داده خواهد شد.

روی کادر ConcreteComponent در نمودار راست‌کلیک کرده و Add All Referenced Types را انتخاب کنید.
با این کار، کلاس ExceptionAttribute و اینترفیس IComponent اضافه می‌شوند.

سپس روی کلاس ExceptionAttribute راست‌کلیک کرده و دوباره Add All Referenced Types را انتخاب کنید تا به نتیجه نهایی برسید، همان‌طور که در تصویر زیر نشان داده شده است ✅

Conventions-UsedThis-Book

نکته‌ی واقعاً فوق‌العاده در مورد این ابزار این است که می‌توانید عناصر نمودار را بر اساس Namespace مرتب کنید.

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

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

در تصویر زیر، نمونه‌ای از Typed Dependencies Diagram را می‌بینید که بر اساس Namespace‌ها سازماندهی شده است

Conventions-UsedThis-Book

بارها برای من پیش آمده که واقعاً به چنین نموداری در کار روزمره نیاز داشتم.

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

این اطلاعات به توسعه‌دهندگان دانش درست می‌دهد تا بدانند هنگام توسعه، کلاس‌ها، Enum‌ها و Interface‌های جدید را کجا قرار دهند، و همچنین بدانند هنگام نگهداری کد، اشیاء را از کجا پیدا کنند.

این نمودار همچنین برای یافتن Namespace‌ها، Interface‌ها و نام‌های اشیاء تکراری نیز مفید است. ✅


نگاهی به Coverage 🔍

مراحل زیر را دنبال کنید:

  1. از منوی Extensions | ReSharper | Cover | Cover Application استفاده کنید.
  2. Dialog Configuration Coverage نمایش داده می‌شود و گزینه پیش‌فرض Standalone انتخاب شده است.
  3. فایل اجرایی (Executable) خود را انتخاب کنید.
  4. می‌توانید یک برنامه .NET از پوشه bin انتخاب کنید.
  5. تصویر زیر Coverage Configuration Dialog را نشان می‌دهد ✅

Conventions-UsedThis-Book

۶. روی دکمه Run کلیک کنید تا برنامه اجرا شود و داده‌های پروفایلینگ جمع‌آوری شوند.
پس از آن، ReSharper دیالوگ زیر را نمایش خواهد داد:

Conventions-UsedThis-Book

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

Conventions-UsedThis-Book

۷. روی پنجره کنسول کلیک کنید و سپس هر کلیدی را فشار دهید تا از برنامه خارج شوید.
پنجره پوشش (Coverage) بسته خواهد شد و فرآیند ذخیره‌سازی داده‌ها آغاز می‌شود.
در نهایت، پنجره Coverage Results Browser نمایش داده خواهد شد، همان‌طور که در این تصویر می‌بینید:

Conventions-UsedThis-Book

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

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

برای رفتن به آیتم موردنظر کافی است دو بار روی آن کلیک کنید تا مستقیماً به همان قطعه کد منتقل شوید.

در مثال ما، کلاس Program تنها 33٪ پوشش کد داشته است. با دوبار کلیک روی Program، خروجی زیر را مشاهده می‌کنیم:

static void Main(string[] args)
{
    LoggingServices.DefaultBackend = new ConsoleLoggingBackend();
    AuditServices.RecordPublished += AuditServices_RecordPublished;
    DecoratorPatternExample();
    //ProxyPatternExample();
    //SecurityExample();
    //ExceptionHandlingAttributeExample();
    //SuccessfulMethod();
    //FailedMethod();
    Console.ReadKey();
}

همان‌طور که می‌بینید، دلیل پوشش پایین این است که چندین فراخوانی کد برای تست موقتاً کامنت شده‌اند. در این حالت می‌توانیم:


حال که با ReSharper و ابزارهای کمک‌کننده برای نوشتن کدهای تمیز و باکیفیت در #C آشنا شدید، نوبت به ابزار بعدی می‌رسد: Telerik JustDecompile.

من بارها از این ابزار استفاده کرده‌ام، برای مثال:

این ابزار را به شدت توصیه می‌کنم، چون در طول سال‌ها ارزش خود را بارها ثابت کرده است.

موتور Decompile این ابزار متن‌باز است و می‌توانید سورس‌کد آن را از این آدرس دریافت کنید:
https://github.com/telerik/justdecompileengine

همچنین نصب‌کننده ویندوز را می‌توانید از وب‌سایت Telerik دریافت کنید:
https://www.telerik.com/products/decompiler.aspx

این ابزار هم به صورت برنامه مستقل و هم به صورت افزونه Visual Studio موجود است.
با آن می‌توانید:


مراحل نصب و اجرا:

  1. Telerik JustDecompile را دانلود و نصب کنید.
  2. در حین نصب ممکن است ابزارهای اضافی پیشنهاد شوند، که در صورت تمایل می‌توانید آنها را غیرفعال کنید.
  3. برنامه مستقل JustDecompile را اجرا کنید.
  4. یک اسمبلی .NET پیدا کرده و آن را به پنل سمت چپ برنامه بکشید.
  5. برنامه کد را Decompile کرده و ساختار درختی کد را در سمت چپ نمایش می‌دهد.
  6. با انتخاب هر آیتم در سمت چپ، کد آن در سمت راست نمایش داده می‌شود، همان‌طور که در تصویر زیر می‌بینید:

Conventions-UsedThis-Book

حالا، همان‌طور که می‌بینید، فرآیند دیکامپایل (decompilation) سریع است و در بیشتر موارد، نتیجه‌ی خوبی برای دیکامپایل اسمبلی ما ارائه می‌دهد. البته این فرآیند بی‌نقص نیست، اما معمولاً کار راه می‌اندازد. مراحل زیر را انجام دهید:

  1. در منوی کشویی سمت راست گزینه‌ی Plugins، گزینه‌ی C# را انتخاب کنید.
  2. سپس روی Tools | Create Project کلیک کنید.
  3. گاهی از شما خواسته می‌شود نسخه‌ی .NET هدف را انتخاب کنید؛ اما همیشه این درخواست نمایش داده نمی‌شود.
  4. بعد از آن، از شما پرسیده می‌شود پروژه را کجا ذخیره کنید.
  5. پروژه در همان مسیر ذخیره خواهد شد.

بعد از این کار، شما می‌توانید پروژه را در Visual Studio باز کرده و روی آن کار کنید. اگر با مشکلی مواجه شدید، Telerik خطاهای موجود در کد را ثبت کرده و یک ایمیل در اختیارتان می‌گذارد. شما می‌توانید هر مشکلی را که با آن روبه‌رو شدید از طریق ایمیل برای آن‌ها ارسال کنید. تیم پشتیبانی آن‌ها معمولاً در پاسخ‌دهی و رفع مشکلات خوب عمل می‌کند.

خب، حالا مرور این فصل به پایان رسید. بیایید به طور خلاصه مرور کنیم که چه آموختیم:

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

سوالات

  1. Code Metrics چیست و چرا باید از آن استفاده کنیم؟
  2. شش مورد از شاخص‌های اندازه‌گیری Code Metrics را نام ببرید.
  3. تحلیل کد (Code Analysis) چیست و چرا مفید است؟
  4. Quick Actions چیستند؟
  5. ابزار JetBrains dotTrace برای چه استفاده می‌شود؟
  6. ابزار JetBrains ReSharper برای چه استفاده می‌شود؟
  7. چرا از Telerik JustDecompile برای دیکامپایل اسمبلی‌ها استفاده کنیم؟

مطالعه بیشتر