لماذا يجب تفضيل الواجهة الخاصة بفئة Java؟




مشاريع الفيجوال بيسك جاهزة (8)

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

سيبلغ PMD عن انتهاك لـ:

ArrayList<Object> list = new ArrayList<Object>();

كان الانتهاك "تجنب استخدام أنواع التنفيذ مثل" ArrayList "؛ استخدم الواجهة بدلاً من ذلك".

سيصحح السطر التالي الانتهاك:

List<Object> list = new ArrayList<Object>();

لماذا يجب استخدام الأخير مع List بدلاً من ArrayList ؟


ArrayList و LinkedList هما تطبيقان لقائمة ، وهي مجموعة مرتبة من العناصر. من المنطقي أنه لا يهم إذا كنت تستخدم ArrayList أو LinkedList ، لذلك لا ينبغي تقييد نوع ذلك.

هذا يتناقض مع القول ، جمع و قائمة ، والتي هي أشياء مختلفة (قائمة يعني فرز ، لا جمع).


يعد استخدام الواجهات على الأنواع الخرسانية هو المفتاح للتغليف الجيد ولتقريب الشفرة.

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

هنا مقالة جيدة حول هذا الموضوع.

آمل أن يساعد!


بشكل عام ، أوافق على أن فك الارتباط من التطبيق أمر جيد وسيسهل عليك الحفاظ على التعليمات البرمجية الخاصة بك.

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

لاهتمام ركضت تجربة التي ولدت عشرة مليارات وصول متسلسل إلى 1 مليون طول ArrayList. على بلدي 2.4 غيغاهرتز ماك بوك ، استغرق الوصول إلى واجهة ArrayList من خلال قائمة 2.10 ثانية في المتوسط ​​، عندما تعلن أنها من نوع ArrayList استغرق الأمر في متوسط ​​1.67 ثانية.

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


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


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

class Counter {
    static int sizeOf(List<?> items) {
        return items.size();
    }
}

في هذه الحالة هو استخدام الواجهة المطلوبة. لأنني أريد أن أحسب حجم كل عملية تنفيذ ممكنة بما في ذلك العرف الخاص بي. class MyList extends AbstractList<String>...


لماذا يجب استخدام الأخير مع List بدلاً من ArrayList؟

إنها ممارسة جيدة: برنامج للواجهة بدلاً من التنفيذ

من خلال استبدال ArrayList ، يمكنك تغيير تطبيق List في المستقبل على النحو التالي وفقًا لحالة استخدام عملك.

List<Object> list = new  LinkedList<Object>(); 
/* Doubly-linked list implementation of the List and Deque interfaces. 
 Implements all optional list operations, and permits all elements (including null).*/

أو

List<Object> list = new  CopyOnWriteArrayList<Object>(); 
/* A thread-safe variant of ArrayList in which all mutative operations
 (add, set, and so on) are implemented by making a fresh copy of the underlying array.*/

أو

List<Object> list = new  Stack<Object>(); 

/* The Stack class represents a last-in-first-out (LIFO) stack of objects.*/

أو

بعض التنفيذ المحدد List أخرى.

واجهة List يحدد العقد ويمكن تغيير تنفيذ محددة من List . وبهذه الطريقة ، يتم اقتران الواجهة والتنفيذ بشكل فضفاض.

ذات صلة SE السؤال:

ماذا يعني أن "البرنامج إلى واجهة"؟


يجب أن يتم كشف خصائص الطبقات / واجهات العمل الخاصة بك من خلال واجهات لأنه يعطي الطبقات الخاصة بك تعاقد استخدام السلوك ، بغض النظر عن التنفيذ.

ومع ذلك...

في الإعلانات المتغيرة المحلية ، من غير المنطقي القيام بذلك:

public void someMethod() {
List theList = new ArrayList();
//do stuff with the list
}

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





interface