ما الخطأ في التحقق من صحة البيانات وما علاقة مبدأ استبدال Liskov به؟



إذا كنت تسأل نفسك في بعض الأحيان السؤال: "هل كل شيء جيد بالنسبة لي في هذه الطريقة؟" واختر بين "ماذا لو كانت تهب" و "من الأفضل أن تتحقق فقط في حالة" ، ثم مرحبًا بك في ...

تصحيح: كما لاحظ lorc و 0xd34df00d ، ما تمت مناقشته أدناه يسمى الأنواع التابعة. يمكنك أن تقرأ عنها هنا . حسنا ، أدناه هو النص المصدر مع أفكاري في هذا الشأن.

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

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

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

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

class Parent { ... } class Child : Parent { ... } ... void processValidObject(Parent parent) { if (parent is Child) { // process } else { // error } } 

توافق على أن المشكلة الآن أكثر وضوحًا. أمامنا هو انتهاك قانوني لمبدأ استبدال Liskov. اقرأ لماذا يعد انتهاك مبدأ الاستبدال أمرًا سيئًا ، على سبيل المثال ، هنا .

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

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

يمكن توسيع هذه الفكرة إلى DLD المعرفة من قبل المستخدم. سيؤدي توفير كائنات مع بيانات التعريف التي تحتوي على DLD المخزنة في النوع إلى التخلص من المشكلات الموضحة أعلاه. سيكون من الرائع الحصول على دعم لمثل هذه الأداة بلغة ما ، ولكن يتم تنفيذ هذا السلوك أيضًا بلغات OO "العادية" ، مثل Java أو C # ، باستخدام الوراثة والمصنع.

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

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

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

Source: https://habr.com/ru/post/ar476220/


All Articles