تنويع البط

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

مثال 
هذا مثال بسيط في بايثون 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'

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

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

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

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

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

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

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

المراجع 

برمجة كائنية التوجه
نظرية النمط