حادث قطار وهمي
في علوم الحاسوب ، يشير مصطلح "النموذج الوهمي المعقد" [ 1 ] إلى صعوبة محاكاة بنية نموذجية متداخلة بعمق. المحاكاة هي إنشاء كائنات وهمية تُستخدم لتقليد سلوك الكائنات الحقيقية، غالبًا لصعوبة اختبارها باستخدام الكائنات الحقيقية. [ 2 ] يُمثل النموذج الوهمي المعقد سلسلة من استدعاءات الدوال (تُسمى سلسلة)، تُعيد كل منها كائنات يمكن استدعاء دوال جديدة عليها. [ 3 ] تتعارض النماذج المتداخلة بعمق مع قانون ديميتر، إذ يجب الوصول إلى خاصية معينة. يُعرف قانون ديميتر أيضًا بمبدأ أقل معرفة ، وهو دليل تصميمي يُشجع على تقليل الترابط بين هياكل البيانات غير المترابطة بشكل وثيق، والتي يُفضل عدم ربطها معًا. إضافةً إلى ذلك، يُمكن اعتبار هذا المستوى من الترابط مؤشرًا على وجود مشكلة في الكود .
ينبغي تجنب استخدام نماذج الحوادث الوهمية قدر الإمكان. وذلك لأنها لا تُصعّب اختبار الكود الذي يستخدمها فحسب، بل تُصعّب التعامل معها أيضاً من منظور التصميم. إضافةً إلى ذلك، فإنها تزيد من كمية المعلومات التي يمكن للكائن الوصول إليها، نظراً لارتباطه الوثيق بمعاملات أخرى لا علاقة لها بوظيفته الأساسية. [ 1 ] [ 4 ]
مثال على كارثة قطار
إذا أراد شخص ما كتابة اختبار للبحث عن مكتبة تتلقى تمويلًا عامًا، أو عن طريق أمين المكتبة الرئيسي فيها، فقد يستخدم رمزًا مثل ما يلي:
جافا
assertEqual ( l.getHeadLibrarian () . getName ( ) . split ( " " ) [ 1 ] , "Smith" ) assertEqual ( l.getFunding ( ) . getType ( ) , "public" )روبي
l.headLibrarian.name.split ( / + / ) . last.should == " Smith " l.funding.type.should == " public "لإنشاء نموذج أولي لكائن يطابق نتيجة البحث، سيتعين عليهم استخدام رمز محاكاة مثل ما يلي:
جافا
HeadLibrarian h = mock ( HeadLibrarian.class ) ; when ( h.getName ( ) ). thenReturn ( "Jane Smith" ) ;Funding f = mock ( Funding . class ); when ( f . getType ()). thenReturn ( "public" );Library l = mock ( Library.class ); when ( l.getHeadLibrarian ( )). thenReturn ( h ) ; when ( l.getFunding ( ) ) . thenReturn ( f ) ;روبي
h = mock ( 'HeadLibrarian' , :name => 'Jane Smith' ) f = mock ( 'Funding' , :type => 'public' ) l = mock ( 'Library' , :HeadLibrarian => h , :Funding => f )هذا مثال على حادث قطار وهمي، لأنه نموذج لجسمين غير مرتبطين، ولكنه يعتمد على فئة، المكتبة، للإشارة إليهما معًا. [ 5 ]
طرق لتجنب الكارثة
يمكن تجنب حدوث خلل برمجي مُحاكي بإجراء تعديلات عامة على الكود، أو بتعديلات أكثر تحديدًا باستخدام حقن التبعية والمكتبات. تسمح التعديلات العامة على الكود بتبسيط النموذج المتداخل، وذلك بشكل أساسي من خلال إنشاء مُقيِّم للوصول إلى الخاصية الفرعية. يمنع هذا التداخل العميق الذي يُسبب الخلل البرمجي المُحاكي، كما يُمكن محاكاة هذا المُقيِّم بسهولة.
حقن التبعية
يمكن استخدام حقن التبعية (DI)، وهي عملية تمرير التبعية إلى العميل الذي سيستخدمها، لتخفيف حدة المشاكل المحتملة. إحدى طرق حقن التبعية سهلة الاستخدام هي كائن الموقع لتقليل تعقيد إنشاء الكائن الوهمي. فيما يلي مثال مُعاد صياغته باستخدام دالة build_mock لحقن التبعية للمساعدة في تعيين قيم وهمية للكائنات التابعة. على الرغم من أن هذا لا يبدو مفيدًا كثيرًا في هذا المثال البسيط، إلا أنه في سيناريو أكثر تعقيدًا، يمكن أن يقلل من تعقيد تعيين القيم يدويًا. [ 6 ]
دالة بناء_النموذج ( الاسم ، الخريطة ، المحدد ، المراجع ) الكائن = نموذج ( الاسم ، الخريطة ) المراجع.كل do | مرجع | الكائن.إرسال ( " # { مرجع } = " , المحدد [ مرجع.إلى_الرمز ] ) نهاية الكائن نهايةlocator = {} locator [ :HeadLibrarian ] = mock ( 'HeadLibrarian' , :name => 'Jane Smith' ) locator [ :Funding ] = mock ( 'Funding' , :type => 'public' ) locator [ :Library ] = build_mock ( 'Library' , {}, locator , [ 'HeadLibrarian' , 'Funding' ] )المكتبات
موكيتو
يمكن أن يُسهّل استخدام مكتبة اختبار بلغات برمجة مختلفة التعامل مع فوضى النماذج الوهمية باستخدام أدوات مساعدة. ومن الأمثلة على ذلك مكتبة Mockito التي توفر تعليقات توضيحية للمساعدة في حقن النماذج الوهمية في الكائنات. باستخدام التعليق التوضيحي @InjectMocks والتعليق التوضيحي @Mock، عندما تُهيئ Mockito جميع النماذج الوهمية، فإنها ستحقن المكتبة بهذه النماذج الوهمية لأغراض التمويل ومسؤول المكتبة الرئيسي. [ 7 ]
public class LibraryTester { @Mock HeadLibrarian h ; @Mock Funding f ; @InjectMocks Library l ; @Before public void initMocks () { MockitoAnnotations . initMocks ( this ); } @Test public void testLibrary () { when ( l . getHeadLibrarian (). getName ()). thenReturn ( "Jane Smith" ); when ( l . getFunding (). getType ()). thenReturn ( "public" ); // الاختبارات هنا } }ديميتر
يمكن أيضًا استخدام المكتبات لمعالجة مشكلة "الخطأ البرمجي" (mock trainwreck). إحدى هذه المكتبات هي " ديميتر" (demeter )، والتي تُستخدم لتوفير مُقيِّمات "قانون ديميتر" (Law of Demeter) التي تُنشئ تلقائيًا مُقيِّمات للنماذج المتداخلة أحادية المستوى. باستخدام هذه المكتبة، يُمكن للمستخدم محاكاة المُقيِّمات التي يستخدمها الكود الخاص به للدالة الفرعية، كما هو موضح في المثال أدناه. [ 8 ]
يتطلب "ديمتر"فئة المكتبة تمتد من ديمترديميتر : رئيسة أمناء المكتبة، ديميتر : التمويلdef initialize @HeadLibrarian = HeadLibrarian.new @Funding = Funding.new end endl = mock ( 'Library' , :HeadLibrarian_name => 'Jane Smith' , : Funding.type = > ' public' ) l.HeadLibrarian_name #Jane Smithمراجع
- 1 2 فوكس، أرماندو. "علوم الحاسوب 169، 001 - ربيع 2015" . يوتيوب . جامعة كاليفورنيا، بيركلي . تم الاطلاع عليه في 4 فبراير 2017 .
- ↑ ستيوارت، سيمون. "مناهج السخرية - أورايلي ميديا" . www.onjava.com . تاريخ الاسترجاع: 20 فبراير 2017 .
- ↑ مارك إيفرز؛ روب ويستجيست. "التصميم القائم على المسؤولية باستخدام الكائنات الوهمية" . الأساليب والأدوات . تم الاطلاع عليه بتاريخ 4 فبراير 2017 .
- ↑ "كود اختبار الوحدة مكتوب بأسلوب "أخبر، لا تسأل"" . steveliles.github.io . تم الاطلاع عليه بتاريخ 20 فبراير 2017 .
- ↑ فريمان، ستيف؛ برايس، نات؛ ماكينون، تيم؛ والنيس، جو. "أدوار وهمية، وليست أشياء" (ملف PDF) . jMock . تم الاطلاع عليه بتاريخ 7 فبراير 2017 .
- ↑ تكنولوجيا المعلومات، تيتانيوم. "جيمس شور: تبسيط مفهوم حقن التبعية" . www.jamesshore.com . تاريخ الاسترجاع: 20 فبراير 2017 .
- ↑ GmbH، لارس فوغل، © 2012، 2016 vogella. "اختبارات الوحدة باستخدام Mockito - برنامج تعليمي" . www.vogella.com . تاريخ الاسترجاع: 20 فبراير 2017 .
{{cite web}}: صيانة CS1: أسماء متعددة: قائمة المؤلفين ( رابط ) صيانة CS1: أسماء رقمية: قائمة المؤلفين ( رابط ) - ↑ "GitHub - emerleite/demeter: طريقة بسيطة لتطبيق قانون ديميتر على كائنات روبي الخاصة بك" . github.com . تم الاطلاع عليه بتاريخ 20 فبراير 2017 .
- اختبار الوحدة
- الأنماط المضادة
- استعارات تشير إلى النقل
