Pergunta

Como exercício para mim mesmo, estava traduzindo um programa de exemplo para vários idiomas.Começando em C#, eu tinha uma interface de padrão de visitante assim:

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

Mudando para Ruby (ou python, ou qualquer outro), não recebo mais despacho do compilador com base no tipo.Devo fazer o envio no próprio visitante?

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

  ...

Ou devo fazer o envio nas diferentes especializações da sala:

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

Ou existe outro idioma preferido usado em linguagens dinâmicas?

Foi útil?

Solução

Minha recomendação é usar a abordagem anterior.Existem vantagens e desvantagens para cada abordagem.O primeiro é mais difícil de manter à medida que o número de tipos de quartos aumenta;o último é mais difícil à medida que o número de tipos de Cleaner aumenta.

Em Ruby, você poderia tentar

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

PS:nem todas as linguagens digitadas dinamicamente são incapazes de despachar com base no tipo;alguns podem inferir o tipo ou, na falta disso, podem usar a conversão forçada para escolher o método adequado entre as opções sobrecarregadas.

Outras dicas

Eu iria com a segunda versão.O primeiro parece o tipo de cheiro de código que o Visitante deve resolver:instruções longas if-else-if ou switch-case.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top