문제

나 자신을 위한 연습으로 샘플 프로그램을 다양한 언어로 번역하고 있었습니다.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

아니면 동적 언어에서 사용되는 또 다른 선호 관용구가 있습니까?

도움이 되었습니까?

해결책

내 추천은 이전 접근 방식을 사용하는 것입니다.각 접근 방식에는 장점과 단점이 있습니다.전자는 객실 유형의 수가 증가함에 따라 유지 관리가 더 어렵습니다.후자는 Cleaner 유형의 수가 증가함에 따라 더 어려워집니다.

Ruby에서는 시도해 볼 수 있습니다.

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

추신:모든 동적 유형 언어가 유형 기반 디스패치를 ​​수행할 수 없는 것은 아닙니다.일부는 유형을 추론할 수 있지만 실패하면 강제 캐스팅을 사용하여 오버로드된 옵션 중에서 적절한 방법을 선택할 수 있습니다.

다른 팁

나는 두 번째 버전으로 갈 것입니다.첫 번째는 Visitor가 해결해야 하는 일종의 코드 냄새처럼 보입니다.긴 if-else-if 또는 switch-case 문.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top