كائنات مقابل هياكل البيانات

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


ما هو الفصل؟

الفئة هي مواصفات للعديد من الكائنات المشابهة.


ما هو الكائن؟

الكائن عبارة عن مجموعة من الوظائف التي تقوم بتنفيذ إجراءات باستخدام بيانات مغلفة.


أم أنه من الأفضل أن نقول إن الكائن عبارة عن مجموعة من الوظائف التي تؤدي أعمالًا مع بيانات يكون وجودها ضمنيًا

بمعنى "ضمني"؟


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

ليست البيانات في الكائن؟


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

حسنا ، دعنا نقول.


حسنا ، ما هو هيكل البيانات؟

بنية البيانات هي مجموعة من العناصر ذات الصلة.


أو بمعنى آخر ، بنية البيانات عبارة عن مجموعة من العناصر التي تعمل بها الدالات ، ويكون وجودها ضمنيًا.

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


هذا صحيح. وماذا عن هذين التعريفين؟

بمعنى من المعاني ، فهي نقيض بعضها البعض.


في الواقع. أنها تكمل بعضها البعض. مثل اليد والقفازات.
  • الكائن هو مجموعة من الوظائف التي تعمل مع عناصر البيانات التي يكون وجودها ضمنيًا ضمنيًا.
  • بنية البيانات هي مجموعة من عناصر البيانات التي تعمل بها الوظائف ، ويكون وجودها ضمنيًا.

نجاح باهر! لذلك اتضح أن الكائنات وهياكل البيانات ليست هي الشيء نفسه!


الحق. هياكل البيانات هي DTOs.

والجداول في قواعد البيانات ليست كائنات سواء ، أليس كذلك؟


صحيح مرة أخرى. تحتوي قواعد البيانات على هياكل البيانات ، وليس الكائنات.

انتظر لحظة لا ORM تعيين الجداول من قاعدة البيانات إلى الكائنات؟


بالطبع لا. لا يمكنك تعيين جداول قاعدة البيانات إلى كائنات. الجداول في قاعدة البيانات هي هياكل البيانات ، وليس الكائنات.

ثم ماذا تفعل ORM؟


يقومون بنقل البيانات من بنية إلى أخرى.

لذلك لا علاقة لهم بالكائنات؟


لا شيء على الاطلاق. بالمعنى الدقيق للكلمة ، لا يوجد شيء مثل ORM بالمعنى التكنولوجي الذي يعين البيانات العلائقية إلى كائنات ، لأنه لا يمكن تعيين الجداول من قاعدة بيانات إلى كائنات.

لكنهم أخبروني أن ORMs تجمع أشياء تجارية.


لا ، يقوم ORM باسترداد البيانات من قاعدة بيانات تعمل معها كائنات الأعمال

ولكن لا تندرج هذه الهياكل البيانات في كائنات الأعمال؟


ربما يحصلون ، أو ربما لا. ORM لا يعرف أي شيء عن هذا.

لكن الفرق هو الدلالي بحت.


لا ، لا. هناك عواقب بعيدة المدى.

على سبيل المثال؟


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

èëèé. هذا غير مفهوم.


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

هذا مفهوم.


حسنا. الآن فكر في كل تطبيق. يصف نموذج الكائن الخاص بكل تطبيق كيفية تنظيم سلوك التطبيق. سيكون لكل تطبيق نموذج كائن خاص به لمطابقة سلوك التطبيق بشكل أفضل.

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


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

شيء أتذكره. ولكن يبدو أن عدم التوافق قد تم تصحيحه فقط باستخدام ORM.


والآن أنت تعرف أن هذا ليس كذلك. عدم تطابق المعاوقة بين الكائنات وهياكل البيانات متكامل ، وليس متماثل.

ماذا؟


هم الأضداد ، وليس شيء مماثل.

الأضداد؟


نعم ، بمعنى مثير جدا للاهتمام. ترى ، الكائنات وهياكل البيانات يعني هياكل التحكم تعارض تماما.

ماذا؟


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

ما مدى اشكال الاشكال البرمجية مع الكائنات في جميع الأمثلة؟


لنلقِ نظرة على نوعين مختلفين من الأشكال: المربعات والدوائر. من الواضح أن وظائف حساب مساحة ومحيط هذه الفئات تستخدم هياكل بيانات مختلفة. من المفهوم أيضًا أن هذه العمليات يتم التذرع بها باستخدام تعدد الأشكال الديناميكي.

إبطاء من فضلك ، لا يوجد شيء واضح.


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

حسنا. بالطبع كائن يعرف كيف يتم تنفيذ أساليبها. بشكل طبيعي.


الآن دعونا نحول هذه الكائنات إلى بنيات بيانات. نحن نستخدم الاتحادات التمييزية.

تميزت ماذا؟


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

سوف يكون الحقل مع رمز التعداد؟


حسنا نعم. وسيكون للساحة النقطة العليا اليسرى وطول الجانب. وأيضا التعداد للإشارة إلى النوع.

حسنا. سيكون هناك اثنين من الهياكل مع رمز النوع.


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

حسنا. بالطبع ، لفئتين. فرع للساحة والدائرة. وللمحيط ، تحتاج أيضًا إلى مفتاح مماثل.


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

حسنا ، أنا أفهم ما كنت تقود إلى. في سيناريو بهياكل البيانات ، يكون كل من تنفيذ دالة للمنطقة في نفس الوظيفة ؛ فهم لا "ينتمون" (مهما كانت هذه الكلمة) إلى النوع.


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

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


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

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


حسنا. اتضح أن إضافة وظائف جديدة أمر صعب ، لأن عليك إجراء تغييرات في كل فصل.

ولكن مع هياكل البيانات ، كل شيء مختلف. لإضافة مثلث ، يجب عليك تغيير كل وظيفة لإضافة فروع لمعالجة المثلث في كل مفتاح.


هذا صحيح. من الصعب إضافة أنواع ؛ يجب عليك تحرير كل وظيفة.

ولكن لإضافة وظيفة للمركز ، لا يجب تغيير أي شيء.


نعم ، إضافة ميزات سهلة.

نجاح باهر. اتضح أن هذين النهجين معاكسان بشكل مباشر.


بالتأكيد نعم. لتلخيص

  • من الصعب إضافة وظائف جديدة إلى الفصول الدراسية ، وعليك إجراء تغييرات في كل فصل
  • تعد إضافة وظائف جديدة إلى هياكل البيانات أمرًا بسيطًا ، تحتاج فقط إلى إضافة وظيفة ، ولا يجب تغيير أي شيء آخر
  • إضافة أنواع جديدة إلى الفصول بسيطة ، تحتاج فقط إلى إضافة فصل جديد
  • من الصعب إضافة أنواع جديدة للهياكل ؛ تحتاج إلى إصلاح كل وظيفة

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


ملاحظة جيدة! ولكن اليوم نحن بحاجة إلى التفكير في شيء آخر. هناك نقطة أخرى تكون فيها هياكل البيانات والفئات متناقضة. الاعتماد.

الإدمان؟


نعم ، اتجاه التبعيات في الكود المصدري.

حسنا ، سأطلب. ما هو الفرق؟


دعونا ننظر في حالة الهياكل. تحتوي كل وظيفة على مفتاح يحدد التنفيذ المطلوب بناءً على كود الكتابة في الاتحاد.

نعم هو كذلك. ماذا بعد؟


دعونا نلقي نظرة على وظيفة استدعاء للمنطقة. يعتمد رمز الاتصال على وظيفة المنطقة وتعتمد وظيفة المنطقة على كل تطبيق محدد.

وماذا تقصد عندما تقول "يعتمد"؟


تخيل أن كل تطبيق لوظيفة في منطقة ما يتم تخصيصه لوظيفة منفصلة. بمعنى ، ستكون هناك وظائف circleArea و squareArea و triangleArea.

حسنًا ، اتضح أنه في فروع التبديل سيكون هناك ببساطة مكالمات إلى هذه الوظائف.


تخيل أن هذه الوظائف موجودة في ملفات مختلفة.

ثم في الملف مع التبديل سيتم استيراد أو استخدام أو تضمين للملفات مع وظائف.


بالضبط. هذا هو التبعية على مستوى شفرة المصدر. مصدر واحد يعتمد على مصدر آخر. كيف يتم توجيه هذا الاعتماد؟

يعتمد رمز المصدر مع رمز التبديل على التعليمات البرمجية المصدر التي توجد فيها التطبيقات.


ماذا عن رمز استدعاء وظيفة للمنطقة؟

يعتمد رمز الاتصال على رمز التبديل ، والذي يعتمد على جميع التطبيقات.


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

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


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

وهذه هي عموما جميع الأنظمة مع الكتابة الساكنة ، أليس كذلك؟


نعم ، وبعض الأنظمة الأخرى بدونها

هذا يجب إعادة بنائه كثيرًا.


والكثير لإعادة.

حسنًا ، لكن في حالة الفصول الدراسية ، هل هو العكس؟


نعم ، لأن الكود الذي يستدعي وظيفة المنطقة يعتمد على الواجهة ، والتطبيق يعتمد أيضًا على هذه الواجهة.

انا ارى سيقوم رمز الفئة Square باستيراد أو استخدام أو تضمين ملف مع واجهة الشكل.


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

نعم حسنا. هذا هو ، إذا قمت بإجراء تغييرات على أحد التطبيقات ...


من الضروري فقط إعادة إنشاء الرمز وإعادة تثبيته بهذه التغييرات.

وذلك لأن تبعيات يتم توجيهها عكس اتجاه المكالمات.


نعم ، نحن نسميها انعكاس التبعية.

حسنًا ، دعنا نلخص كل شيء. وتعارض الطبقات وهياكل البيانات لبعضها البعض في ثلاثة حواس.


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

نعم هذا صحيح. وينبغي أن يؤخذ ذلك في الاعتبار من قبل كل مصمم ومهندس برمجيات.

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


All Articles