문제

상당히 큰 Ruby 애플리케이션에서는 주어진 객체가 다음 두 가지로 식별되는 상황이 있습니다.이름이랑 아이디 말야.이러한 각 값 유형은 다소 다른 목적으로 사용되므로 정확하게 동일하지는 않습니다(id와 이름은 다른 위치에 유지됩니다).따라서 우리는 애플리케이션 주위에 다양한 값(ID, 이름 및 객체)이 전달되는 것으로 마무리합니다.이 상황은 주어진 함수에 어떤 유형을 전달해야 하는지 명확하지 않은 버그에 이미 물렸기 때문에 적어도 어느 정도 문제가 있는 것처럼 보입니다.실제로 수년에 걸쳐 여러 응용 프로그램에서 유사한 문제 코드를 본 기억이 나지만 다시 특정 이름을 지정하지는 않았습니다.

유형이 없는 언어인 Ruby는 C++와 같은 고전적인 유형 기반 다형성 함수를 허용하지 않습니다.해결 방법으로 동료는 종종 다음과 같은 종류의 코드를 사용했습니다.

  def initialize starting_value
    if starting_post.kindof? Foo
      @starting_id = get_id_from_foo starting_value
    elsif starting_post.kindof? Bar
      @starting_id = get_id_from_bar starting_value
    else
      raise "illegal type"
    end
  end

초기화 프로그램뿐만 아니라 코드 기반 주변에 이 코드가 확산되면 "지저분한 다형성"이 발생합니다.그것은 종종 효과가 있지만 때로는 매우 혼란스러운 상황을 만듭니다.

이에 대해 세 가지 질문이 있습니다.

  • 이에 대한 공식적인 이름이 반 패턴으로 표시됩니까?"지저분한 인터페이스?", "지저분한 다형성?" 또는 다른 것?
  • 사람들이 이것을 얼마나 나쁘게 생각합니까?
  • 이것을 리팩터링하는 체계적인 방법이 있습니까?우리가 만든 많은 테스트 가이 느슨한 유형을 사용한다는 일반적인 리팩토링으로 우리가 가지고있는 과제는 테스트와 구현을 동시에 변경해야하므로 일반 테스트 기반 리팩토링의 비계 효과가 없습니다.나는이 느슨한 다형성을 실제로 "강화"할 수 있다고 생각하며, 즉각적인 찢어지지 않고 코드를 함수로 추상화 할 수 있다고 생각합니다.그러나 이것이 좋은 생각일까요?
도움이 되었습니까?

해결책

ID가 자신을 반환하고 객체가 ID를 반환하며 이름이 ID를 얻기 위해 수행해야 하는 모든 작업을 수행하도록 일종의 get_id 메서드를 정의할 수 없습니까?그러면 당신은 항상 세 가지 중 하나가 될 것으로 알고 있는 모든 것을 정규화할 수 있습니다.필요한 경우 get_name 및 get_object 메소드도 마찬가지입니다.

즉, 암시적 ThingWhatHasAnID 인터페이스를 정의하고 이를 함수 매개변수의 duck 유형으로 만들었습니다.

내가 뭔가를 놓치고 있는 것이 아니라면, 나는 이 안티패턴을 "추상화를 만들 기회를 놓친 것"이라고 부르고 싶습니다.

다른 팁

거의마다 자신이 객체의 클래스를 켜는 것을 발견 할 때마다, 동작이 객체 자체의 방법이어야한다는 단서입니다. 메시지 파견 ~이다 수신기를 기반으로 한 다형성. 이 경우와 같은 것이어야합니다.

def initialize starting_value
  @starting_id = starting_value.id
end

정의하다 id 다양한 것을하기 위해 get_id_from_* 사용 된 방법. 불법 유형 케이스는 이미 명명법을 얻을 수 있기 때문에 이미 증가합니다.

이것을 무엇이라고 부를 것인지, 나는 그것을 "OO 언어로의 절차 프로그래밍"이라고 부릅니다.

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