البرمجة مقابل الواجهات:هل تكتب واجهات لجميع فئات المجال الخاص بك؟

StackOverflow https://stackoverflow.com/questions/152077

  •  02-07-2019
  •  | 
  •  

سؤال

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

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

هل كانت مفيدة؟

المحلول

واجهات الكتابة "لمجرد" تبدو لي مضيعة للوقت والطاقة، ناهيك عن انتهاك مبدأ KISS.

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

نصائح أخرى

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

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

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

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

أنصحك بالبقاء رشيقًا ورشيقًا - لا تفعل أي شيء حتى تحتاج إلى القيام به، ثم دع IDE الخاص بك يقوم بإعادة البناء نيابةً عنك عندما تحتاج إليه.

من التافه جدًا في IDEA/Eclipse تحويل فئة ملموسة إلى واجهة عندما تقرر أنك بحاجة إلى واحدة.

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

في الواقع، هذا السؤال هو مثال على سوء الفهم الشائع حول "البرمجة ضد الواجهات".

انت ترى هذا يكون مبدأ جيد جدًا، لكنه كذلك لا يعني ما يعتقد الكثير من الناس أنه يعني!

"برنامج لواجهة، وليس تنفيذ" (من كتاب GoF) يعني ذلك فقط، وليس أنه يجب عليك بذل قصارى جهدك لتحقيق يخلق واجهات منفصلة لكل شيء.إذا كان لديك ArrayList الكائن، ثم أعلن أن نوع المتغير/الحقل/المعلمة/الإرجاع هو من النوع List.سيتعامل رمز العميل بعد ذلك مع نوع الواجهة فقط.

وفي كتاب "الجافا الفعالة" لجوشوا بلوخ، تم التعبير عن المبدأ بشكل أوضح، في "البند 52:الرجوع إلى الكائنات من خلال واجهاتها".حتى أنه يقول بالخط العريض:

من المناسب تمامًا الرجوع إلى كائن بواسطة فئة بدلاً من واجهة في حالة عدم وجود واجهة مناسبة.

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

لذا فالجواب بالنسبة لي هو:استخدم دائمًا الواجهات الموجودة بالفعل، ولكن تجنب إنشاء واجهات جديدة إذا لم يكن هناك سبب وجيه للقيام بذلك (و قابلية الاختبار, ، في حد ذاته، لا ينبغي أن يكون واحدا).

تعد كتابة الواجهة قبل الحاجة إليها (سواء للاختبار أو للهندسة المعمارية) أمرًا مبالغًا فيه.

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

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

نكتب في الغالب تطبيقات الويب باستخدام Wicket وSpring وHbernate ونستخدم واجهات لـ Spring Beans، على سبيل المثال.الخدمات و DAOs.بالنسبة لهذه الفئات، تكون الواجهات منطقية تمامًا.لكننا نستخدم أيضًا واجهات لكل فئة مجال على حدة، وأعتقد أن هذا مجرد مبالغة.

حتى لو كنت متأكدًا تمامًا من أنه سيكون هناك نوع واحد ملموس فقط من كائن النموذج، فإن استخدام الواجهات يجعل الاستهزاء والاختبار أسهل إلى حد ما (ولكن في هذه الأيام توجد أطر عمل يمكنها مساعدتك في إنشاء فئات وهمية تلقائيًا، حتى بالنسبة لفئات Java الملموسة- موكيتو، JTestR، الربيع، رائع...)

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

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

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

أعتقد أن السبب الرئيسي للبرمجة ضد الواجهات هو قابلية الاختبار.ومن ثم، بالنسبة لكائنات المجال - ما عليك سوى التمسك بـ POJOs أو POC#Os :) وما إلى ذلك، أي فقط امنع فئاتك من إضافة أي إطار عمل محدد لمنعهم من تبعيات البناء ووقت التشغيل المختلفة وهذا كل شيء.يعد إنشاء واجهات لـ DAOs فكرة جيدة.

نحن نستخرج الواجهات من كل شيء لمجرد أنها تساعد في الاختبار (السخرية) ولأشياء مثل AOP.يمكن لـ Eclipse القيام بذلك تلقائيًا:Refactor->استخراج الواجهة.

وإذا كنت بحاجة إلى تعديل الفصل لاحقًا، فيمكنك استخدام Refactor->Pull Up...لسحب الطرق التي تحتاجها إلى الواجهة.

*أفعل ذلك لأنني أحتاجه لإنشاء وكلاء لكائنات المجال الخاص بي.

هذا شيء آخر يجب أن نأخذه في الاعتبار والذي واجهته، خاصة مع المجال الذي تم إنشاؤه وكائنات DAO.الكثير من الواجهات محددة للغاية.لنفترض أن العديد من كائنات المجال لها معرف وحقل حالة، فلماذا لا تتشارك في واجهة مشتركة؟لقد سبب لي هذا الإحباط، وهو نموذج مجال مسطح (من حيث الميراث) غير ضروري.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top