بازسازی کد: Encapsulate collection - ساده و خیلی مهم
اندازه‌ی قلم متن
تخمین مدت زمان مطالعه‌ی مطلب: یک دقیقه

زمانیکه متدی یک لیست (collection) را بر می‌گرداند، بهتر است این لیست، نسخه‌ای فقط خواندنی باشد. برای توضیح بیشتر این موضوع می‌توان به کلاس زیر و نحوه‌ی بازسازی آن رجوع کرد. 
در کلاس Person فرضی، متدی مسئولیت دریافت لیست درس‌های آن شخص را بر عهده دارد. متد دیگری نیز مسئولیت ثبت کردن آنها را بر عهده دارد. توجه کنید متد دریافت لیست درس ها، لیستی قابل ویرایش (افزودن یا حذف کردن) را بر می‌گرداند. 

در پیاده سازی ابتدایی، متدهای getter و setter عادی را مشاهده می‌کنیم که خیلی معمول هستند (با پیاده سازی‌های مختلف در نگارش‌های مختلف #C) .

اما چرا بهتر است لیستی فقط خواندنی را از طریق متد GetCourses برگردانیم؟  

  • زیرا برگرداندن لیست قابل ویرایش، به استفاده کننده کلاس، امکان ویرایش لیست را بدون اطلاع کلاس مالک می‌دهد. 
  • زیرا اطلاعات بیش از حدی در مورد نحوه‌ی ذخیره سازی اطلاعات در کلاس مالک را به استفاده کننده می‌دهد.
با برگرداندن نسخه‌ای فقط خواندنی از لیست خود می‌توانیم اشکالات مطرح شده را تا حدی کاهش دهیم. این بازسازی کد را می‌توان با حذف setter برای کل لیست و افزودن دو متد برای افزودن و حذف تکی آیتم‌های آن کامل کرد. با این تغییر می‌توان از عدم تغییرات خارج از اطلاع و کنترل کلاس مالک، به طور کامل اطمینان حاصل کرد. 
به طور مثال اگر در #C از کلاس List استفاده می‌کنید، می‌توان به صورت زیر این کار را انجام داد؛ نسخه عمومی‌تری مانند IReadOnlyCollection نیز وجود دارد. همچنین نسخه‌ای از دیکشنری فقط خواندنی نیز در دسترس است (IReadOnlyDictionary):
public class Refactoring 
{ 
    private List<object> objects; 
    public Refactoring() 
    { 
        objects = new List<object>(); 
    } 
    public IReadOnlyList<object> Objects { get { return objects.AsReadOnly(); } } 
}
  • #
    ‫۵ سال و ۹ ماه قبل، یکشنبه ۱۱ آذر ۱۳۹۷، ساعت ۲۱:۲۰
    این نوع طراحی در الگوی Domain-driven design متداول می‌باشد و یکی از مواردی که در بازگشت لیست فقط خواندنی باید توجه داشت و در برخی از سایتها با آن برخورد می‌کنیم استفاده از
     public IReadOnlyList<object> Objects { get { return objects.ToList(); } }
    به جای
     public IReadOnlyList<object> Objects { get { return objects.AsReadOnly(); } }
    می‌باشد به طوری که در مثال اول کلیه اطلاعات داخل objects درون لیست جدید کپی می‌شود ولی در مثال دوم فقط ارجاعی به آدرسی که اطلاعات اصلی در آن قرار دارد شکل می‌گیرد و سربار کمتری دارد.