طبقة الوصول إلى البيانات: قائمة Exposing <>: فكرة سيئة؟

أقوم حاليًا بتشفير طبقة بسيطة لبيانات الوصول ، وكنت أتساءل عن النوع الذي ينبغي أن أعرضه للطبقات الأخرى.

I am going to internally implement the Data as a List<>, but I remember reading something about not exposing the List type to the consumers if not needed.

public List GetAllUsers()//non C# users: that means List of User :)

هل تعلم لماذا (جوجل لم يساعد)؟ ماذا عادة ما تعرض لهذا النوع من الاشياء؟ الأول قائمة؟ IEnumerable؟

3

3 إجابة

Usually it's best to expose the least powerful interface that the user can still meaningfully work with. If the user just needs some enumerable data, return IEnumerable. If that's not enough because the user needs to be able to modify the list (attention! shouldn't often be the case), return an IList.

/تصحيح:

يسأل جويل سؤالًا صالحًا في تعليقه: لماذا تعرض الواجهة الأقل قوة بدلاً من منح المستخدم القدرة القصوى؟ (اقتبس)

تكمن الفكرة وراء هذا في أن طريقة إرجاع البيانات قد لا تتوقع من المستخدم تعديل محتواه: قد لا تزال هناك طريقة أخرى للفئة قد لا تكون فارغة بعد الرجوع إليها. تخيل أن المستخدم يزيل جميع البيانات من القائمة. أما الطريقة الأخرى ، فيجب عليها الآن أن تقوم بفحص إضافي لأن ذلك قد يكون غير ضروري.

الأهم من ذلك ، يعرض هذا أجزاء من التنفيذ الداخلي من خلال نوع الإرجاع. إذا كنت بحاجة إلى تغيير التنفيذ في المستقبل بحيث لم يعد يستخدم حاوية IList ، فلدي مشكلة: إما أن أحتاج إلى تغيير طريقة العقد ، وإدخال تغيير فاصل. أو أحتاج إلى نسخ البيانات إلى حاوية قائمة.

على سبيل المثال ، تخيل أن التنفيذ الفعال يستخدم قاموسًا ويعيد فقط مجموعة القيم التي لا تنفذ IList .

6
وأضاف
أيضاً ، لديك خيار إرجاع ReadOnlyCollection عندما تريد التحكم في ذلك على الجانب المستدعي.
وأضاف المؤلف CVertex, مصدر
لم أشتر في فكرة "الأقل قوة" بعد ؛ ماذا عن جعل كل كتلة من الكود مفيدة قدر الإمكان؟
وأضاف المؤلف Joel Coehoorn, مصدر

بالتأكيد هو شيء. سيؤدي استخدام الواجهة إلى تقليل عملية الاقتران وتسهيل تغيير تفاصيل تنفيذ طبقة البيانات على الطريق. أي واجهة تعتمد على الظروف. IList جيد ، لكن في بعض الأحيان قد تحتاج إلى وظيفة ICollection أو تريد تحديد قيم للقراءة فقط.

3
وأضاف

يجب عليك التفكير بعناية قبل العودة IEnumerable. إذا كانت الشفرة الأساسية تستخدم "العائد" لإنشاء IEnumerable ، أو تستخدم LINQ ، فحينئذٍ ستنتهي إلى فتح أي موارد مستخدمة.

يجب نسخ IEnumerable إلى IEnumerable آخر قبل إرجاعها. باستخدام IList ، يمكنك جعل هذا مطلبًا ، حتى لا يتمكن أحد من إرجاع IEnumerable عن غير قصد.

من ناحية أخرى ، فإن إرجاع أيليست يشير إلى المتصل إلى أنه يمكنهم تغيير القائمة التي تم إرجاعها.

2
وأضاف
نقطة جيدة. ربما يمكنك إضافة مثال يوضح مثل هذه الحالة من أجل اكتمالها.
وأضاف المؤلف Konrad Rudolph, مصدر