предпочтительный способ реализации шаблона посетителя в динамических языках? - PullRequest
3 голосов
/ 04 сентября 2008

В качестве упражнения для себя я переводил пример программы на разные языки. Начиная с 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

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

Ответы [ 2 ]

3 голосов
/ 05 сентября 2008

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

3 голосов
/ 04 сентября 2008

Я рекомендую использовать первый подход. Есть плюсы и минусы для каждого подхода. Первый сложнее поддерживать по мере роста числа типов комнат; последний становится все труднее по мере роста числа чистых типов.

В Ruby вы можете попробовать

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...