предпочтительный способ реализации шаблона посетителя на динамических языках?

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);
    }

Переходя на ruby (или python, или что-то еще), я больше не получаю отправку от компилятора на основе типа.Должен ли я выполнить отправку в самом посетителе?

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

Или есть другая предпочтительная идиома, которая используется в динамических языках?

Это было полезно?

Решение

Моя рекомендация состоит в том, чтобы использовать первый подход.У каждого подхода есть свои плюсы и минусы.Первое сложнее поддерживать по мере роста числа типов номеров;последнее сложнее по мере роста числа Более чистых типов.

В Ruby вы могли бы попробовать

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

PS:не все языки с динамической типизацией не могут выполнять отправку на основе типа;некоторые могут определить тип, или, в противном случае, могут использовать принудительное приведение, чтобы выбрать правильный метод среди перегруженных опций.

Другие советы

Я бы предпочел вторую версию.Первый из них выглядит как проблема с запахом кода, которую должен решить посетитель:длинные операторы if-else-if или switch-case.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top