لا يمر في المعلمات التي ينبغي أن تكون معروفة في الانتهاكات الضمنية؟

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

سؤال

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

يستخدم عشوائي وترتيب خوارزمية خلط ورق اللعب جيدة؟

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

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

المحلول

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

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

public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source)

الذي يخلق أ Random باستخدام وقت النظام الحالي لأن بذورها ستعتني بأكثر حالات الاستخدام العادي لهذه الطريقة. الطريقة الأصلية

public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source, Random rng)

يمكن استخدامها لاختبار (تمر في Random كائن مع بذور معروفة) وأيضا في تلك الحالات النادرة حيث يقرر المستخدم أنهم يحتاجون إلى RNG آمنة تشفير. يجب أن يسمي تطبيق المعلمة الواحد هذه الطريقة.

نصائح أخرى

لا أعتقد أنه يكسر التغليف. الحالة الوحيدة في الصفيف هي البيانات نفسها - و "مصدر العشوائي" هو في الأساس خدمة. لماذا يجب أن يكون هناك مجموعة بشكل طبيعي مصدر عشوائي مرتبط؟ لماذا يجب أن يكون هذا singleton؟ ماذا عن المواقف المختلفة التي لديها متطلبات مختلفة - مثل السرعة مقابل العشوائية آمنة تشفير؟ هناك سبب لماذا java.util.Random لديه أ SecureRandom Subclass :) ربما لا يهم ما إذا كانت نتائج خلط ورق اللعب يمكن التنبؤ بها مع الكثير من الجهد والمراقبة - أو ربما يفعل ذلك. هذا يعتمد على السياق، وهذا هو المعلومات التي يجب أن تهتم خوارزمية خلط ورق اللعب بها.

بمجرد البدء في التفكير في الأمر كخدمة، فمن المنطقي أن يتم تمريره كإعالة.

نعم انت استطاع احصل عليه من Singleton المحلي للخيط (وبالفعل سأذهب بلوق حول ذلك بالضبط في الأيام القليلة المقبلة) لكنني سأكون عموما رمز ذلك بحيث المتصل يحصل لاتخاذ هذا القرار.

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

بالطبع، هناك دائما خيار صنع Random اختياري - استخدم Singleton Local Local كإعداد افتراضي إذا لم يوفر المتصل نفسه.

لا أعتقد أن هذا ينتهك التغليف.

مثالك

أود أن أقول أن القدرة على توفير RNG هو ميزة للفئة. من الواضح أنني لن أقدم طريقة لا تتطلب ذلك، لكن يمكنني رؤية المرات التي قد تكون مفيدا لتتمكن من تكرار العشوائية.

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

الحالة العامة

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

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