سؤال

لقد جئت من جافا، والآن أعمل أكثر مع روبي.

إحدى ميزات اللغة التي لست على دراية بها هي module.أنا أتساءل ما هو بالضبط module ومتى تستخدم واحدة، ولماذا تستخدم أ module أكثر من class?

هل كانت مفيدة؟

المحلول

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

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

يمكنك أيضًا استخدام وحدة نمطية عندما تكون لديك طرق مشتركة عبر تطبيقات متعددة (مرة أخرى، نموذج المكتبة جيد هنا).

نصائح أخرى

╔═══════════════╦═══════════════════════════╦═════════════════════════════════╗
║               ║ class                     ║ module                          ║
╠═══════════════╬═══════════════════════════╬═════════════════════════════════╣
║ instantiation ║ can be instantiated       ║ can *not* be instantiated       ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ usage         ║ object creation           ║ mixin facility. provide         ║
║               ║                           ║   a namespace.                  ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ superclass    ║ module                    ║ object                          ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ methods       ║ class methods and         ║ module methods and              ║
║               ║   instance methods        ║   instance methods              ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ inheritance   ║ inherits behaviour and can║ No inheritance                  ║
║               ║   be base for inheritance ║                                 ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ inclusion     ║ cannot be included        ║ can be included in classes and  ║
║               ║                           ║   modules by using the include  ║
║               ║                           ║   command (includes all         ║
║               ║                           ║   instance methods as instance  ║
║               ║                           ║   methods in a class/module)    ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ extension     ║ can not extend with       ║ module can extend instance by   ║
║               ║   extend command          ║   using extend command (extends ║
║               ║   (only with inheritance) ║   given instance with singleton ║
║               ║                           ║   methods from module)          ║
╚═══════════════╩═══════════════════════════╩═════════════════════════════════╝

أنا مندهش أن أحدا لم يقل هذا بعد.

نظرًا لأن السائل جاء من خلفية Java (وأنا أيضًا)، فإليك تشبيهًا يساعد.

الفصول تشبه ببساطة فئات Java.

الوحدات تشبه فئات Java الثابتة.فكر في ذلك Math فئة في جافا.لا يمكنك إنشاء مثيل لها، ويمكنك إعادة استخدام الأساليب الموجودة في الفئة الثابتة (على سبيل المثال. Math.random()).

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

يمكن تضمين الوحدة النمطية بواسطة فئات متعددة.لا يمكن وراثة الوحدات، لكن نموذج "mixin" هذا يوفر نوعًا مفيدًا من "الوراثة المتعددة".سوف يختلف أنصار OO مع هذا البيان، لكن لا تدع النقاء يعيق إنجاز المهمة.


(هذه الإجابة مرتبطة في الأصل بـ http://www.rubycentral.com/pickaxe/classes.html, ، ولكن هذا الرابط ومجاله لم يعدا نشطين.)

Module في روبي، إلى حد ما، يتوافق مع جافا فئة مجردة - لديه طرق مثيل، يمكن للفئات أن ترث منه (عبر include, ، يسميها شباب روبي "mixin")، ولكن ليس لها مثيلات.هناك اختلافات طفيفة أخرى، ولكن هذا القدر من المعلومات يكفي للبدء.

مساحة الاسم: الوحدات هي مساحات الأسماء...التي لا وجود لها في جافا ;)

لقد قمت أيضًا بالتبديل من Java و python إلى Ruby، وأتذكر أنه كان لدي نفس السؤال بالضبط ...

لذا فإن أبسط إجابة هي أن الوحدة هي مساحة اسم، وهي غير موجودة في Java.في جافا أقرب عقلية لمساحة الاسم هي طَرد.

لذا فإن الوحدة النمطية في روبي تشبه ما هو موجود في جافا:
فصل؟ لا
واجهه المستخدم؟ لا
فئة مجردة؟ لا
طَرد؟ نعم ممكن)

الأساليب الثابتة داخل الفئات في جافا:نفس الأساليب داخل الوحدات في روبي

في جافا الحد الأدنى للوحدة هو فئة، لا يمكن أن يكون لديك وظيفة خارج فئة.لكن هذا ممكن في روبي (مثل الثعبان).

إذن ما الذي يدخل في الوحدة النمطية؟
الطبقات والأساليب والثوابت.الوحدة تحميهم ضمن مساحة الاسم تلك.

لا مثيل: لا يمكن استخدام الوحدات لإنشاء مثيلات

الوظائف المختلطة: في بعض الأحيان لا تكون نماذج الوراثة جيدة للفئات، ولكن من حيث الوظيفة تريد تجميع مجموعة من الفئات/الطرق/الثوابت معًا

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

مثال بسيط للوحدة:

module MySampleModule
  CONST1 = "some constant"

  def self.method_one(arg1)
    arg1 + 2
  end
end

كيفية استخدام الأساليب داخل الوحدة النمطية:

puts MySampleModule.method_one(1) # prints: 3

كيفية استخدام ثوابت الوحدة النمطية:

puts MySampleModule::CONST1 # prints: some constant

بعض الاتفاقيات الأخرى حول الوحدات:
استخدم وحدة نمطية واحدة في ملف (مثل فئات روبي، فئة واحدة لكل ملف روبي)

الحد الأدنى:الوحدة عبارة عن تقاطع بين فئة ثابتة/أداة مساعدة وmixin.

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

فصل

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

وحدة

  • الوحدات هي طريقة لتجميع الأساليب والفئات والثوابت.

  • تمنحك الوحدات فائدتين رئيسيتين:

    => توفر الوحدات مساحة اسم وتمنع تضارب الأسماء.تساعد مساحة الاسم على تجنب التعارضات مع الوظائف والفئات التي تحمل نفس الاسم والتي كتبها شخص آخر.

    => تنفذ الوحدات منشأة mixin.

(بما في ذلك الوحدة النمطية في Klazz يعطي مثيلات من Klazz الوصول إلى طرق الوحدة النمطية.)

(قم بتوسيع Klazz باستخدام Mod مما يمنح الفصل Klazz إمكانية الوصول إلى أساليب Mods.)

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

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

لا يمكن إنشاء مثيل للوحدات النمطية، ولا تنشئ كائنات، ولا تدعم الوراثة.لذا تذكر أن إحدى الوحدات لا ترث من وحدة أخرى!

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

module Apple
  def a
    puts 'a'
  end
end

module Apple 
  def b
    puts 'b'
  end
end

class Fruit
  include Apple
end

 > f = Fruit.new
 => #<Fruit:0x007fe90c527c98> 
 > f.a
 => a
 > f.b
 => b

ولكن لا يوجد وراثة بين الوحدات:

module Apple
  module Green
    def green
      puts 'green'
    end
  end
end

class Fruit
  include Apple
end

> f = Fruit.new
 => #<Fruit:0x007fe90c462420> 
> f.green
NoMethodError: undefined method `green' for #<Fruit:0x007fe90c462420>

لم ترث وحدة Apple أي أساليب من الوحدة الخضراء وعندما قمنا بتضمين Apple في فئة Fruit، تمت إضافة أساليب وحدة Apple إلى السلسلة الأصلية لمثيلات Apple، ولكن ليس أساليب الوحدة الخضراء، على الرغم من أن الوحدة الخضراء تم تعريف الوحدة النمطية في وحدة Apple.

فكيف يمكننا الوصول إلى الطريقة الخضراء؟يجب عليك تضمينه بشكل صريح في صفك:

class Fruit
  include Apple::Green
end
 => Fruit 
 > f.green
=> green

لكن روبي لديها استخدام مهم آخر للوحدات.هذه هي منشأة Mixin، التي أصفها في إجابة أخرى على SO.لكن لتلخيص ذلك، تتيح لك mixins تحديد الأساليب في سلسلة وراثة الكائنات.من خلال mixins، يمكنك إضافة أساليب إلى سلسلة وراثة مثيلات الكائن (تشمل) أو فئة_مفردة من الذات (تمديد).

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top