سؤال

على مقالة ويكيبيديا عن القانون ديميتر يقول:

القانون يمكن القول ببساطة بأنه "استخدام فقط نقطة واحدة".

ومع ذلك مثال بسيط من يجيد واجهة قد تبدو مثل هذا:

static void Main(string[] args)
{
   new ZRLabs.Yael.Pipeline("cat.jpg")
        .Rotate(90)
        .Watermark("Monkey")
        .RoundCorners(100, Color.Bisque)
        .Save("test.png");
}

حتى لا يذهب هذا معا ؟

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

المحلول

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

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

نصائح أخرى

ليس بالضرورة."فقط استخدام نقطة واحدة" هو غير دقيق موجز القانون ديميتر.

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

  • أول نقطة هي طريقة تسمى من ObjectA ، والعودة كائن من نوع ObjectB
  • بجوار نقطة هي الطريقة الوحيدة المتاحة في ObjectB ، والعودة كائن من نوع ObjectC
  • نقطة المقبلة هي خاصية متوفرة فقط في ObjectC
  • بلا نهاية

ومع ذلك, على الأقل في رأيي ، القانون ديميتر لا تنتهك إن عودة وجوه من كل نقطة لا يزال نفس النوع الأصلي المتصل:

var List<SomeObj> list = new List<SomeObj>();
//initialize data here
return list.FindAll( i => i == someValue ).Sort( i1, i2 => i2 > i1).ToArray();

في المثال أعلاه ، سواء FindAll() و النوع() بإرجاع نفس نوع الكائن القائمة الأصلية.القانون ديميتر لا تنتهك:قائمة فقط تحدثت فورا الأصدقاء.

أن يقال ليس كل يجيد واجهات تنتهك القانون ديميتر طالما عودتهم نفس نوع المتصل بهم.

نعم, على الرغم من أن لديك لتطبيق بعض الواقعية إلى الحالة.أنا دائما تأخذ القانون ديميتر كدليل بدلا من القاعدة.

بالتأكيد كنت قد ترغب في تجنب ما يلي:

CurrentCustomer.Orders[0].Manufacturer.Address.Email(text);

وربما استبدال مع:

CurrentCustomer.Orders[0].EmailManufacturer(text);

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

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

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

1) لا تنتهك في كل شيء.

الرمز هو ما يعادل

var a = new ZRLabs.Yael.Pipeline("cat.jpg");
a = a.Rotate(90);
a = a.Watermark("Monkey");
a = a.RoundCorners(100, Color.Bisque);
a = a.Save("test.png");

2) حسن رأ' فيل Haack يقول : القانون ديميتر ليست نقطة العد ممارسة

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

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