طراحی کلاس های تمیز با SRP و Encapsulation

طراحی کلاس های تمیز با SRP و Encapsulation

نویسنده: مرضیه تقدسی | تاریخ انتشار: 19 خرداد 1405 | تعداد بازدید: 534

در ادامه‌ی سری مقالات «اصول کدنویسی تمیز»، به یکی از بنیادین‌ترین ستون‌های طراحی نرم‌افزار می‌رسیم: اصل مسئولیت واحد (Single Responsibility Principle). این اصل از اصول پایه‌ای SOLID است و می‌گوید یک کلاس باید فقط یک دلیل برای تغییر داشته باشد. کنار SRP، مفهوم Encapsulation یا کپسوله‌سازی هم قرار می‌گیرد که وظیفه محافظت از داده و رفتار داخلی یک کلاس را بر عهده دارد.

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

 


بخش اول: اصل مسئولیت واحد (SRP)

SRP می‌گوید یک کلاس نباید چندین کار مختلف انجام دهد. هرچه مسئولیت‌های بیشتری به یک کلاس اضافه شود، کلاس پیچیده‌تر و حساس‌تر می‌شود.

مثال از یک کلاس با چند مسئولیت:




public class ReportService

{

public void GenerateReport()

{

// تولید گزارش

}

public void SaveToFile()

{

// ذخیره در فایل

}

public void SendEmail()

{

// ارسال گزارش به ایمیل

}

}

در این مثال، کلاس سه مسئولیت مختلف دارد: تولید گزارش، ذخیره‌سازی و ارسال. این ساختار به شدت شکننده است؛ کوچک‌ترین تغییر در یکی از این بخش‌ها ممکن است کل کلاس را تحت تأثیر قرار دهد.

 

بازنویسی کلاس طبق SRP

چند کلاس کوچک‌تر ایجاد می‌کنیم که هرکدام فقط یک مسئولیت دارند:




public class ReportGenerator

{

public void Generate() { }

}

public class FileStorage

{

public void Save() { }

}

public class EmailSender

{

public void Send() { }

}

حالا اگر بخواهید سیستم را گسترش دهید، تغییرات فقط در همان کلاس مربوطه انجام می‌شود و سایر بخش‌ها تحت تأثیر قرار نمی‌گیرند. این یعنی کد پایدارتر، تست‌پذیرتر و قابل نگهداری‌تر.

 


بخش دوم: Encapsulation؛ محافظت از داده‌ها و رفتار داخلی

کپسوله‌سازی یعنی هرکلاس باید از داده‌ها و منطق داخلی خود محافظت کند. این حفاظت معمولاً با تعیین سطوح دسترسی مثل private، protected و public انجام می‌شود.

مزایای Encapsulation:

  • جلوگیری از سوءاستفاده یا تغییر اشتباه داده‌ها
  • حفظ یکپارچگی وضعیت داخلی کلاس
  • سادگی بیشتر در توسعه و تست
  • امکان کنترل دقیق روی تغییرات و رفتارها



public class Order

{

private decimal _totalAmount;

public void AddItem(decimal price)

{

_totalAmount += price;

}

public decimal GetTotalAmount()

{

return _totalAmount;

}

}

در این مثال، مقدار _totalAmount به صورت مستقیم از بیرون قابل تغییر نیست و فقط از طریق متدهای کنترل‌شده دسترسی دارد. این همان اصل محافظت از داده‌هاست.

 


بخش سوم: چرا SRP و Encapsulation همیشه با هم استفاده می‌شوند؟

این دو اصل به شدت مکمل یکدیگرند. SRP مسئولیت کلاس را محدود می‌کند و Encapsulation از داده‌ها و منطق داخلی محافظت می‌کند. ترکیب این دو منجر به ساخت کلاس‌هایی می‌شود که:

  • کوچک، واضح و قابل فهم‌اند
  • کمترین وابستگی را دارند
  • آماده افزودن قابلیت‌های جدید بدون تخریب ساختار موجودند
  • به راحتی تست می‌شوند

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

 


نتیجه‌گیری بخش سوم

اگر فقط یک اصل از Clean Code را رعایت کنید، آن اصل باید SRP باشد؛ و اگر فقط یک اصل از شی‌گرایی را جدی بگیرید، آن اصل باید Encapsulation باشد.

در مقاله بعدی، وارد دنیای ارتباطات بین اشیا می‌شویم: ترکیب‌گرایی (Composition) و اصل دمتر (Law of Demeter). این بخش، یکی از مهم‌ترین پایه‌های معماری ماژولار است.