الطريقة المفضلة لتنفيذ نمط الزائر باللغات الديناميكية؟

StackOverflow https://stackoverflow.com/questions/44337

سؤال

وكتمرين لنفسي، كنت أقوم بترجمة نموذج لبرنامج إلى لغات مختلفة.بدءًا من لغة C#، كانت لدي واجهة بنمط الزائر كما يلي:

interface Visitor
    {
        void Accept(Bedroom x);
        void Accept(Bathroom x);
        void Accept(Kitchen x);
        void Accept(LivingRoom x);
    }

بالانتقال إلى روبي (أو بايثون، أو أي شيء آخر)، لم أعد أتلقى إرسالًا من المترجم بناءً على النوع.هل يجب أن أقوم بالإرسال في الزائر نفسه؟

class Cleaner

  def accept(x)
    acceptBedroom(x) if Bedroom === x
    acceptBathroom(x) if Bathroom === x
    acceptKitchen(x) if Kitchen===x
    acceptLivingRoom(x) if LivingRoom===x
  end

  ...

أم يجب أن أقوم بالإرسال في تخصصات الغرفة المختلفة:

class Bathroom<Room
  def initialize(name)
    super(name)
  end
  def accept(visitor)
    visitor.acceptBathroom(self)
  end
end

أم أن هناك لغة مفضلة أخرى تستخدم في اللغات الديناميكية؟

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

المحلول

توصيتي هي استخدام النهج السابق.هناك إيجابيات وسلبيات لكل نهج.يصعب الحفاظ على النوع الأول مع تزايد عدد أنواع الغرف؛الأخير أصعب مع تزايد عدد أنواع المنظف.

في روبي، يمكنك أن تجرب

def accept(x)
  send "accept#{x.class}".to_sym, x
end

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

نصائح أخرى

سأذهب مع الإصدار الثاني.الأول يشبه نوع رائحة الكود الذي من المفترض أن يحله الزائر:عبارات if-else-if الطويلة أو حالة التبديل.

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