تنويع البط (بالإنجليزية: Duck typing)‏ في برمجة الحاسوب هي تطبيق لاختبار البط — «إذا كانت تمشي مثل البطة وتبطبط مثل البطة، فيجب أن تكون بطة» — لتحديد إمكانية استخدام كائن لغرض معين. بالتنويع العادي، يتم تحديد الملاءمة حسب نوع الكائن. في تنويع البط، يتم تحديد ملاءمة الكائن من خلال وجود طرق وخصائص معينة، بدلاً من نوع الكائن نفسه.[1]

مثال

عدل

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

class Duck:
  def fly(self):
    print("Duck flying")
 
class Sparrow:
  def fly(self):
    print("Sparrow flying")

class Whale:
  def swim(self):
    print("Whale swimming")

for animal in Duck(), Sparrow(), Whale():
  animal.fly()

Output:

Duck flying
Sparrow flying
AttributeError: 'Whale' object has no attribute 'fly'

في اللغات المكتوبة بشكل ثابت

عدل

تحتوي بعض اللغات ذات التنويع الثابت في الغالب مثل سي شارب و بوو على ميزات[2][3] ترشد المجمّع لترتيب التحقق من نوع الأصناف في وقت التشغيل بدلاً من وقت التجميع، وتضمين كود التحقق من النوع في وقت التشغيل وذلك في الناتج المجمّع. يمكننا أيضًا تنفيذ تويع البط في جافا باستخدام أدوات معالجة الطرق البرمجية MethodHandle API.[4]

مقارنة مع أنظمة الأنواع الأخرى

عدل

أنظمة النوع الهيكلي

عدل

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

تدعم لغات تايب سكريب[5] و لغة كامل الكائنية و سكالا و غو و Elm[6] و Gosu و PureScript التنويع الهيكلي بدرجات متفاوتة.

البروتوكولات والواجهات

عدل

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

قوالب أو أنواع عامة

عدل

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

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

المراجع

عدل
  1. ^ "Glossary — Python 3.7.1 documentation". docs.python.org. مؤرشف من الأصل في 2020-06-25. اطلع عليه بتاريخ 2018-11-08.
  2. ^ Boo: Duck Typingنسخة محفوظة October 6, 2008, على موقع واي باك مشين.
  3. ^ "Anders Hejlsberg Introduces C# 4.0 at PDC 2008". مؤرشف من الأصل في 2009-12-16. اطلع عليه بتاريخ 2017-01-30.
  4. ^ "StackOverflow: Implement duck typing using java MethodHandles". مؤرشف من الأصل في 2020-07-01. اطلع عليه بتاريخ 2020-06-13.
  5. ^ "SE Radio Episode 384: Boris Cherny on TypeScript". se-radio.net. مؤرشف من الأصل في 2019-10-26. اطلع عليه بتاريخ 2019-10-25.
  6. ^ Czaplicki، Evan. "Core Language · An Introduction to Elm". مؤرشف من الأصل في 2020-04-27. اطلع عليه بتاريخ 2017-01-30.