إرشادات استخدام واجهة Java - هي Jetters و Setters في واجهة سيئة؟

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

سؤال

ماذا يفكر الناس في أفضل إرشادات لاستخدامها في واجهة؟ ماذا ينبغي ويجب أن أذهب إلى واجهة؟

لقد سمعت أن الناس يقولون ذلك، كقاعدة عامة، يجب أن تحدد الواجهة السلوك وليس فقط. هل هذا يعني أن واجهة لا ينبغي أن تحتوي على getters و setters؟

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

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

المحلول

أعتقد أن هناك نوعان من الواجهات المعلنة بشكل عام:

  1. أ وصف الخدمة. وبعد هذا قد يكون شيء مثل CalculationService. وبعد لا أعتقد أن الطرق getX يجب أن يكون في هذا النوع من الواجهة، و من المؤكد ليس setX. وبعد إنهم يضطلعون بوضوح بوضوح تفاصيل التنفيذ، وهي ليست مهمة هذا النوع من الواجهة.
  2. أ نموذج البيانات - موجود فقط نبذل مجردة تنفيذ كائنات البيانات في النظام. قد يتم استخدامها للمساعدة في الاختبار أو لمجرد أن بعض الأشخاص الذين تبلغ منهم قديمة قد تذكر الأيام التي يتذكرون فيها (على سبيل المثال) باستخدام إطار الثبات تعادلك إلى وجود فائض معين (أي سوف تختار تنفيذ واجهة في حال تحولت طبقة الثبات الخاصة بك). أعتقد أن وجود طرق Javabean في هذا النوع من الواجهة معقولة تماما.

ملاحظة: ربما تكون فئات المجموعات مناسبة لكتابة رقم 2

نصائح أخرى

لا أرى لماذا لا يمكن أن تحدد الواجهة Getters و Setters. على سبيل المثال، List.size() هو بفعالية مجرد getter. يجب أن تحدد الواجهة السلوك بدلا من التنفيذ رغم ذلك - لا يمكن أن يقول كيف حالك مقبض الحالة، ولكن يمكن أن تصر على أنه يمكنك الحصول عليه وتعيينه.

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

تحرير: تشير التعليقات إلى أن Getters و Setters تعني حقل بسيط يستخدم في دعم التخزين. أنا لا أوافق بشدة مع هذا التضمين. في رأيي، هناك تأثير على أنه "رخيص بشكل معقول" للحصول على / تعيين القيمة، ولكن ليس مخزنا كحقل مع تطبيق تافهة.


تحرير: كما لوحظ في التعليقات، يتم ذلك صريحا في مواصفات javabeans. القسم 7.1:

وبالتالي حتى عند أنواع كاتب البرنامج النصي في شيء مثل b.Label = fooلا تزال هناك طريقة استدعاء الأسلوب في الكائن الهدف لتعيين الخاصية، والكائن الهدف لديه عنصر تحكم برمجي كامل.

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


إذا كانت الآثار المفترضة كانوا صحيح، قد نفتح خصائص جيدة مثل الحقول مباشرة. لحسن الحظ أن التضمين لا عقد: Getters و Setters هي تماما ضمن حقوقهم لحساب الأشياء.

على سبيل المثال، النظر في مكون مع

getWidth()
getHeight()
getSize()

هل تعتقد أن هناك ضمنا أن هناك ثلاثة متغيرات هناك؟ لن يكون من المعقول إما:

private int width;
private int height;

public int getWidth() {
    return width;
}

public int getHeight() {
    return height;
}

public Size getSize() {
    return new Size(width, height); // Assuming an immutable Size type
}

أو (IMO المفضل):

private Size size;

public int getWidth() {
    return size.getWidth();
}

public int getHeight() {
    return size.getHeight();
}

public Size getSize() {
    return size;
}

هنا إما أن تكون الممتلكات الحجم أو خصائص الطول / العرض للراحة فقط - لكنني لا أرى ذلك يجعلها غير صالحة بأي طريقة.

لا يوجد شيء بشر بطبيعته حول getters / setters. لكن:

  1. أميل إلى جعل كائناتي غير ثابتة (في المقام الأول) فيما يتعلق بالحقول التي تحتوي عليها. لماذا ا ؟ أنا مثيل لأن معظم الأشياء خلال مرحلة البناء. إذا أردت تغيير شيء ما في وقت لاحق، فأنا أحيي هذه القيود. لذلك سوف تميل واجهاتي إلى احتواء Getters، ولكن لا يقومون (هناك فوائد أخرى - خاصة الخيوط).
  2. أريد أن أفعل الأشياء الخاصة بي أشياء بالنسبة لي, ، ليس العكس. لذلك عندما تستحوذ أحد كائناتي على عدد من Getters، أبدأ في طرح ما إذا كان يجب أن يحتوي هذا الكائن على وظائف أكثر، بدلا من تعريض جميع بياناته لشيء آخر للعمل معه. يرى هذه الإجابة لمزيد من التفاصيل.

هذه هي جميع الإرشادات، لاحظ.

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

لن أقول أنه لا يجب أن يكون لديك getters في واجهة، رغم ذلك. من المنطقي أن يكون لديك واجهة مقروءة

لقد سمعت أن الناس يقولون ذلك، كقاعدة عامة، يجب أن تحدد الواجهة السلوك وليس فقط. هل هذا يعني أن الواجهة لا ينبغي أن تحتوي على getters و setters؟

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

ثانيا، إذا تم تعريف Getters و Setters في واجهة، فهو لا يحددون حقا السلوك الكامل (الآخر أن واحد للقراءة وواحد هو للكتابة WRT خاصية.) هل يمكن أن يكون لديك سلوك معقد وراء setters and getters، ولكن يمكنهم يتم تنفيذها فقط في الفصول الفعلية. لا يوجد شيء في لغة Java التي يمكن أن تسمح لنا بتحديد السلوك بحرية في واجهات إلا لأكثر الحالات تقييدا.

مع ذلك في الاعتبار، لا يوجد شيء خاطئ - بلتاجيا وذوي - مع وجود setters و getters في واجهات.

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

الآن، إذا نظرنا إلى Getters ويشرعون من وجهة نظر الفصول المنفذة المتوافقة مع المواصفات JavaBeans، فأنت لا تحتاج إلى تحديد واجهات لهم.

ولكن إذا كان لديك أشياء تتطلب setters and getters، مثل قد تكون قد تكون قد تكون قد توصلت أيضا إلى نوع الفاصوليا (وليس في وقت التشغيل مثل الفول)، والذي قد توجد تطبيقات متعددة، ثم نعم ، سيدعو هذا إلى واجهة تحدد getters و setters.

آمل أن يساعد.

هذه اللمسات على Getter / Setter بأكملها هي موضوع شرير يتم تناوله عدة مرات على هذا الموقع وفي أي مكان آخر.

أميل إلى تأييد عدم وجود مسافرين في الواجهة، ولكن لإضافة المتعاونين الذين يستخدمون وسيطات المنشئين إلى التنفيذ.

إن حقيقة أن التنفيذ المباشر لشيء ما هو أنه لا ينبغي أن يمنعه Getter إنه في واجهة إذا كان يحتاج إلى أن يكون.

لمزيد من القراءة: اعترافات تصميم API العملي لمهندس معماري Java Framework (Jaroslav Tulach، 2008، Acress).

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

في الأساس إذا كانت الإجابة على "هل أحتاج إلى معرفة قيمة [الدولة، الممتلكات، أيا كانت الأمثل] من أجل العمل مع مثيل ذلك؟" ثم نعم ... ينتمي الملحقات إلى الواجهة.

List.Size () من John أعلاه هو مثال مثالي ل Getter يحتاج إلى تعريفه في واجهة

يتم استخدام Getters للاستعلام عن حالة كائن - والتي يمكنك تجنبها حقا عند تصميم واجهةك. اقرأ http://www.pragprog.com/articles/tell-dont-ask.

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