
مقدمه: چرا در #C نوشتن کد به صورت تمیز اهمیت بالایی دارد؟
در دنیای توسعه نرمافزار، نوشتن کدی تمیز، مقیاسپذیر و بهینه در زبان #C و فریمورک NET Core. از اهمیت بالایی برخوردار است.
این مقاله به بررسی ۱۵ بهترین شیوه کدنویسی در #C و NET Core. میپردازد که به توسعهدهندگان کمک میکند نرمافزارهایی با کیفیت بالا و قابل نگهداری ایجاد کنند.
اگر می خواهید با زبان #C و اصول کدنویسی آن آشنا بشید پیشنهاد می شود نوشته زیر را مطالعه کنید:
در این نوشته شما می خوانید
رعایت اصول SOLID
اصول SOLID پنج اصل اساسی در طراحی شیءگرا هستند که به توسعهدهندگان کمک میکنند کدی قابل نگهداری و توسعهپذیر بنویسند:
- Single Responsibility Principle (SRP): هر کلاس یا ماژول باید تنها یک وظیفه مشخص داشته باشد.
- Open/Closed Principle (OCP): کد باید برای توسعه باز و برای تغییر بسته باشد.
- Liskov Substitution Principle (LSP): هر کلاس فرزند باید بتواند بهجای کلاس والد استفاده شود.
- Interface Segregation Principle (ISP): از اینترفیسهای کوچک و تخصصی بهجای اینترفیسهای بزرگ و عمومی استفاده کنید.
- Dependency Inversion Principle (DIP): وابستگیها را به انتزاعها (Interfaces یا Abstract Classes) متصل کنید، نه به پیادهسازیها.
استفاده از تزریق وابستگی (Dependency Injection)
تزریق وابستگی یکی از الگوهای طراحی است که به بهبود تستپذیری و نگهداری کد کمک میکند.
در NET Core. ، میتوانید از سرویس داخلی Microsoft.Extensions.DependencyInjection یا دیگر IoC Containerها مانند Autofac استفاده کنید.
مثال:
public interface IMessageService
{
void SendMessage(string message);
}
public class EmailService : IMessageService
{
public void SendMessage(string message)
{
// Send Mail
}
}
public class NotificationController
{
private readonly IMessageService _messageService;
public NotificationController(IMessageService messageService)
{
_messageService = messageService;
}
public void Notify(string message)
{
_messageService.SendMessage(message);
}
}
نامگذاری واضح و معنادار
استفاده از نامهای توصیفی برای متدها، متغیرها و کلاسها به خوانایی کد کمک میکند.
برای اینترفیسها از پیشوند I
استفاده کنید (مثلاً IRepository
).
مثال:
public class CustomerRepository : ICustomerRepository
{
// Piade Sazi Method
}
نوشتن کلاسها و متدهای کوتاه و خوانا
هر کلاس نباید بیش از ۳۰۰ خط کد و هر متد بیش از ۳۰-۴۰ خط داشته باشد.
متدهای طولانی را به متدهای کوچکتر با مسئولیتهای مشخص تقسیم کنید.
مثال:
public class OrderService
{
public void ProcessOrder(Order order)
{
if (!ValidateOrder(order))
throw new InvalidOperationException("Invalid order.");
CalculateTotal(order);
SaveOrder(order);
SendConfirmation(order);
}
private bool ValidateOrder(Order order)
{
// Etebar Sanji Order
}
private void CalculateTotal(Order order)
{
// Mohasebe Total
}
private void SaveOrder(Order order)
{
// Save Order
}
private void SendConfirmation(Order order)
{
// Send Verification
}
}
استفاده از async/await برای عملیات ناهمزمان
در عملیات I/O مانند فراخوانی API، دسترسی به دیتابیس و خواندن فایلها از async/await استفاده کنید تا عملکرد برنامه بهبود یابد.
متدهای async باید به Async
ختم شوند (مثلاً GetUsersAsync
).
مثال:
public async Task> GetUsersAsync()
{
return await _dbContext.Users.ToListAsync();
}
مدیریت استثناها (Exception Handling)
استفاده از بلاکهای try-catch
در مکانهای مناسب به جلوگیری از کرشهای ناگهانی برنامه کمک میکند.
همچنین، تعریف Middleware برای مدیریت استثناها در سطح برنامههای ASP.NET Core توصیه میشود.
مثال:
public async Task GetUser(int id)
{
try
{
var user = await _userService.GetUserByIdAsync(id);
if (user == null)
return NotFound();
return Ok(user);
}
catch (Exception ex)
{
// Log giri Error
return StatusCode(500, "Internal server error");
}
}
پرهیز از کدهای تکراری (DRY - Don't Repeat Yourself)
کدهای مشترک را به متدها و کلاسهای مجزا منتقل کنید.
استفاده از Extension Methods برای گسترش قابلیتهای کلاسها نیز مفید است.
مثال:
public static class StringExtensions
{
public static bool IsNullOrEmpty(this string value)
{
return string.IsNullOrEmpty(value);
}
}
نظارت و لاگگیری مؤثر
استفاده از ابزارهایی مانند Serilog یا NLog برای لاگگیری به شما کمک میکند تا مشکلات را سریعتر شناسایی و رفع کنید.
لاگگیری در لایههای مختلف اپلیکیشن و پیادهسازی Correlation ID نیز توصیه میشود.
مثال:
public class HomeController : Controller
{
private readonly ILogger _logger;
public HomeController(ILogger logger)
{
_logger = logger;
}
public IActionResult Index()
{
_logger.LogInformation("Index page accessed.");
return View();
}
}
نوشتن تستهای واحد و یکپارچه
استفاده از ابزارهای تست مانند xUnit, NUnit یا MSTest به تکمیل مقاله با ارائه شیوههای کدنویسی بهینه در #C و NET Core. میپردازیم تا نرمافزارهایی تمیز، مقیاسپذیر و بهینه ایجاد کنید.
public class OrderServiceTests
{
private readonly Mock _orderRepositoryMock;
private readonly OrderService _orderService;
public OrderServiceTests()
{
_orderRepositoryMock = new Mock();
_orderService = new OrderService(_orderRepositoryMock.Object);
}
[Fact]
public void ProcessOrder_ShouldCallSaveOrder_WhenOrderIsValid()
{
var order = new Order { Id = 1, Amount = 100 };
_orderService.ProcessOrder(order);
_orderRepositoryMock.Verify(repo => repo.SaveOrder(It.IsAny()), Times.Once);
}
}
استفاده بهینه از Entity Framework Core یا Dapper
استفاده از AsNoTracking
برای بهبود عملکرد:
هنگام بازیابی دادههایی که نیازی به ردیابی تغییرات ندارند، از متد AsNoTracking
استفاده کنید تا عملکرد بهتری داشته باشید.
مثال:
public async Task> GetUsersAsync()
{
return await _dbContext.Users
.AsNoTracking()
.ToListAsync();
}
پیادهسازی الگوهای Repository و Unit of Work:
این الگوها به جداسازی منطق دسترسی به دادهها از منطق تجاری کمک میکنند و کد را قابل نگهداریتر میسازند.
استفاده از Projection برای کاهش دادههای دریافتی:
با انتخاب فقط فیلدهای مورد نیاز در کوئریها، میتوانید حجم دادههای منتقلشده را کاهش داده و عملکرد را بهبود بخشید.
مثال:
public async Task> GetUserDtosAsync()
{
return await _dbContext.Users
.Select(u => new UserDto { Id = u.Id, Name = u.Name })
.ToListAsync();
}
استفاده از آنالیز کد و رعایت سبک کدنویسی
استفاده از ابزارهای آنالیز کد: ابزارهایی مانند SonarQube میتوانند به شناسایی مشکلات پنهان در کد کمک کنند و کیفیت کد را بهبود بخشند.
پیکربندی EditorConfig برای حفظ یکپارچگی سبک کدنویسی در تیم، از فایلهای EditorConfig استفاده کنید تا تنظیمات قالببندی و سبک کد را تعریف کنید.
استفاده بهینه از LINQ
پرهیز از استفاده غیرضروری از
ToList()
: از تبدیل زودهنگام کوئریها به لیست با استفاده ازToList()
خودداری کنید تا از بار اضافی بر حافظه جلوگیری شود.استفاده از متدهای مناسب: از متدهایی مانند
Select
،Where
وFirstOrDefault
بهصورت بهینه و متناسب با نیاز استفاده کنید.مثال:
var activeUserNames = users
.Where(u => u.IsActive)
.Select(u => u.Name);
مدیریت مناسب حافظه
پیادهسازی الگوی Dispose: برای کلاسهایی که منابع غیرمدیریتی را مدیریت میکنند، الگوی
IDisposable
را پیادهسازی کنید و ازusing
برای آزادسازی منابع استفاده کنید.مثال:
public class FileManager : IDisposable
{
private FileStream _fileStream;
public FileManager(string filePath)
{
_fileStream = new FileStream(filePath, FileMode.Open);
}
public void Dispose()
{
_fileStream?.Dispose();
}
}
توسعه ماژولار و قابل گسترش
شکستن اپلیکیشن به ماژولهای کوچکتر: با تقسیم برنامه به ماژولهای مستقل، نگهداری و توسعه آن را سادهتر کنید.
استفاده از معماری میکروسرویس: در پروژههای بزرگ، معماری میکروسرویس میتواند به بهبود مقیاسپذیری و مدیریت بهتر کمک کند.
بهینهسازی عملکرد
پیادهسازی Caching: از مکانیزمهای کش مانند MemoryCache یا Redis برای ذخیره دادههای پرکاربرد استفاده کنید تا بار روی دیتابیس کاهش یابد.
بهینهسازی کوئریهای دیتابیس: از ایجاد کوئریهای ناکارآمد و N+1 جلوگیری کنید و کوئریها را بهینهسازی کنید.
استفاده از ابزارهای پروفایلینگ: ابزارهایی مانند MiniProfiler میتوانند به شناسایی گلوگاههای عملکردی کمک کنند.
سوالات متداول درباره بهترین شیوه های کدنویسی در #C و NET Core.
رعایت اصول SOLID در کدنویسی #C باعث میشود کدهای شما تمیز، قابل نگهداری و توسعهپذیر باشند.
این اصول به شما کمک میکنند وابستگیها را کاهش داده، تغییرات را سادهتر اعمال کنید و پروژههای بزرگ را بهصورت مقیاسپذیر مدیریت کنید.
در .NET Core، تزریق وابستگی با استفاده از سرویس Microsoft.Extensions.DependencyInjection انجام میشود.
کافی است سرویسها را در کلاس Startup در متد ConfigureServices
ثبت کرده و از طریق Constructor به کلاسها تزریق کنید تا تستپذیری و نگهداری کد بهبود یابد.
در #C، استفاده از نامهای توصیفی و معنادار که هدف متغیر یا متد را بیان کند، بهترین روش است.
برای اینترفیسها از پیشوند I
استفاده کنید و برای متدهای async پسوند Async
را اضافه کنید تا خوانایی و فهم کد افزایش یابد.
ابزارهایی مانند Serilog و NLog برای لاگگیری در ASP.NET Core بسیار محبوب هستند.
این ابزارها به شما کمک میکنند تا لاگهای ساختاریافته، زمانبندیشده و سطحبندیشده ایجاد کرده و مشکلات برنامه را سریعتر شناسایی و رفع کنید.
برای نوشتن تستهای واحد در #C، از ابزارهایی مانند xUnit یا NUnit استفاده کنید.
رعایت اصول Arrange-Act-Assert در نوشتن تستها و استفاده از ابزارهای Mocking مانند Moq برای شبیهسازی وابستگیها، تستهای شما را دقیقتر و کارآمدتر میکند.
برای مدیریت حافظه در .NET Core، از IDisposable
و کلمه کلیدی using
برای آزادسازی منابع استفاده کنید.
همچنین از Garbage Collector بهره ببرید و از ایجاد اشیاء بزرگ و بیاستفاده پرهیز کنید تا عملکرد و کارایی برنامه بهینه شود.
نتیجهگیری
با رعایت این ۱۵ بهترین شیوه کدنویسی در #C و .NET Core، میتوانید نرمافزارهایی با عملکرد بالا، قابل نگهداری و توسعهپذیر ایجاد کنید.
همچنین، با استفاده از ابزارهای مناسب و پیادهسازی اصول طراحی، توسعه نرمافزارهای مقیاسپذیر و بهینه برای شما سادهتر خواهد شد.
📢 اگر شما هم تجربه ای در کد نویسی به صورت تمیز را دارید در بخش کامنتها آن را به اشتراک بگذارید! 🚀
دیدگاهتان را بنویسید