2009-04-03 11 views
4

상당히 큰 Ruby 응용 프로그램에서 우리는 주어진 객체가 이름과 ID의 두 가지로 식별되는 상황을 말합니다. 이 값 유형은 각각 다른 용도로 사용되기 때문에 정확히 동일하지는 않습니다 (다른 장소에서 ID와 이름을 유지). 그래서 우리는 응용 프로그램 (ID, 이름 및 객체) 주위로 전달되는 다양한 값으로 마무리합니다. 이 상황은 적어도 어느 정도는 문제로 보입니다. 왜냐하면 우리는 이미 어떤 함수가 어떤 함수에 전달되어야하는지 명확하지 않은 버그에 이미 물 렸기 때문입니다. 저는 실제로 몇 년 동안 여러 가지 응용 프로그램에서 유사한 문제 코드를 보았습니다. 그러나 다시 특정 이름을 지정하지는 않았습니다."messy-polymorphism"anti-pattern

루비는 타입없는 언어로서, 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 

우리의 코드베이스 (뿐만 아니라 초기화) 나는 "지저분한 - 다형성"이라고 부르는 결과 약이 코드의 확산. 종종 효과가 있지만 때로는 매우 혼란스러운 상황을 만듭니다.

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

  • 정식 이름이 안티 패턴입니까? "지저분한 인터페이스?", "지저분한 다형성?" 또는 다른 것?
  • 사람들이 얼마나 나쁠 것이라고 생각하십니까?
  • 리팩토링하는 체계적인 방법이 있습니까? 우리가 작성한 많은 테스트가 일반 리팩터링과 함께하는 도전은이 루스 타이핑을 사용하므로 테스트와 구현을 동시에 변경해야하고 일반 테스트의 스캐 폴드 효과가 없으므로 기반의 리팩토링. 나는이 느슨한 다형성을 실제로 강화시킬 수 있다고 생각한다. 즉, 을 추상화하고 코드를 함수로 추출한다. 하지만 이 좋은 아이디어일까요?
+0

레일스 애플리케이션입니까? –

답변

7

id가 스스로를 반환하도록 객체의 ID를 반환하고 ID를 얻기 위해 필요한 모든 작업을 수행 할 수 있도록 get_id 메소드를 정의 할 수 있습니까? 그럼 당신은 항상 당신이 알고있는 3 가지 중 하나가 될 수있는 모든 것을 표준화 할 수 있습니다. get_name 및 get_object 메소드가 필요한 경우 마찬가지로 get_name 및 get_object 메소드와 유사합니다.

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

내가 뭔가를 놓치지 않는 한이 반 패턴 "추상화를 만들 기회를 놓친다"라고 말하고 싶습니다.

4

거의 언제든지 개체의 클래스를 전환하는 것을 발견하면 개체 자체의 메서드로 동작해야한다는 것을 알 수 있습니다. 메시지 발신 은 수신기를 기반으로하는 다형성 인입니다.

def initialize starting_value 
    @starting_id = starting_value.id 
end 

할하는 데 사용에 상관없이 다양한 get_id_from_* 방법을 수행하는 id 정의 :이 경우, 그것은 무언가 같이해야합니다. 불법 유형 케이스는 NoMethodError가 발생하기 때문에 이미 발생합니다.

내가 무엇을 부르는지에 관해서는, 나는 "OO 언어로 절차 적 프로그래밍"이라고 부릅니다."