وباستخدام واحد الى واحد واجهات مع الكيانات نطاق ممارسة جيدة أو سيئة؟ لماذا ا؟

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

سؤال

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

وعلى سبيل المثال:

وحساب كائن المجال:

public class Account : IAccount
{
     public string Name {get;set;}
     //...some more fields that are also in IAccount
     public decimal Balance {get;set;}
}

وانها مطابقة واجهة

public interface IAccount
{
   string Name {get;set;}
   //... all the fields in Account
   decimal Balance {get;set;}
}

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

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

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

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

وهكذا أنا الغريب:

وماذا لديك واحد الى واحد واجهات للكيانات نطاقك؟

لماذا لا؟

وماذا هو ممارسة جيدة أو سيئة؟

وشكرا لقراءة!

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

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

المحلول

وانها عادة سيئة كما هو موضح، ولكن ...

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

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

نصائح أخرى

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

ولكن ماذا لو كان لديك، على سبيل المثال:

public class Account : IAccount { ... }       // Usual account, persistent
public class MockAccount : IAccount { ... }   // Test mock object
public class TransAccount : IAccount { ... }  // Account, not persistent
public class SimAccount : IAccount { ... }    // Account in a performance sim

ووهلم جرا؟

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

في عام، إذا دروسي لن تكون جزءا من نمط تصميم مثل استراتيجية أو الزوار أنا لا إضافة الواجهات.

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

interface SomeStrategy {
   void doSomething(StrategyData data);
}

interface StrategyData {
   String getProperty1();

   String getProperty2();
} 

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

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

واحد مقابل واحد واجهات على كيانات تشكل نموذج مضاد

ووضع جيمس غريغوري أنه أفضل مني <لأ href = "http://www.lostechies.com/blogs/jagregory/archive/2009/05/09/entity-interface-anti-pattern.aspx" يختلط = " نوفولو noreferrer "> هنا .

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

لماذا هذا واحد أخفق بها؟

وأجد وجود واجهة لكائن المجال، كما قال تشارلي مارتن، يتيح لي الفرصة لاختيار تنفيذ بلدي.

وثمة مثال أساسي هو المعرف (object.Id) لكائن، وهذا سيكون مختلفا تبعا للمكان الذي قمت بتخزين هذا الكائن والمسؤولية عن خلق هذه المشكلة قد تكون أو لا راحة في تنفيذ البيانات لاحقا. في SQL Server الذي قد يذهب لترقيم تلقائي، ولكن في الجدول تخزين أزور قد تذهب لارشد، ولكنك لا تريد أن يكون لتغيير منطق الأعمال منكم التطبيق لأنك تغيير حيث يمكنك تخزين البيانات الخاصة بك.

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

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

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

وهناك مكان لمعظم أنماط حتى المفترى سينغلتون، وهو ما يعني ليست على "نموذج مضاد"، على الأقل بقدر ما يوحي المصطلح.

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