2012-08-29 4 views
3

URL을 만드는 데 사용되는 제네릭 유형을 입력으로 사용하는 인터페이스 지정 메소드가 있습니다.Void를 선택적 인수로 사용하는 것이 더 나은 대안

interface UrlGenerator<T> { 

    String prepareUrl(T input); 

} 

매개 변수가 필요없는 구현이 하나 있습니다. 그것은 제네릭 형식 T.에 대한 무효 사용

class StaticUrlGenerator implements UrlGenerator<Void> { 

    private final String url; 

    public StaticUrlGenerator(String url) { 
     this.url = url; 
    } 

    @Override 
    public String prepareUrl(Void nothing) { 
     return url; 
    } 

} 

prepareUrl 방법에 대한 인수에 null를 요구대로 StaticUrlGenerator는 사용하기 불편하다.

은 내가 input 매개 변수를 잃을 수 :

interface UrlGenerator<T> { 

    String prepareUrl(T input); 

} 

가 지금은 (생성자) 다른 방법으로 구현하는 클래스에 필요한 입력을 통과해야합니다. 이 방법으로 클래스의 무국적 속성을 잃어 버렸습니다. 입력을 변경할 때마다 다른 생성자 인수로 다시 작성해야합니다.

class SchedulePageUrlGenerator implements UrlGenerator { 

    public static final String QUERY_STRING_BASE = "?from="; 

    private final String showingBaseUrl; 
    private final LocalDate date; 

    public SchedulePageUrlGenerator(String showingBaseUrl, LocalDate date) { 
     this.showingBaseUrl = showingBaseUrl; 
     this.date = date; 
    } 

    @Override 
    public String prepareUrl() { 
     DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyy-MM-dd"); 
     String dateStr = fmt.print(date); 
     return showingBaseUrl + QUERY_STRING_BASE + dateStr; 
    } 

} 

내 설계에는 근본적으로 잘못된 것이 있어야한다고 생각합니다.

+0

:'문자열 prepareUrl (T. .. input); ' –

+2

Twitter API 클라이언트처럼 보입니다 :-) 어쨌든 ... OO에서 작업은 이름으로 정의되는 것이 아니라 무엇을 할 지 정의됩니다. 시나리오에서 prepareUrl은 다른 클래스에서 다른 작업을 수행합니다. 해결책은 두 개의 메소드에 서로 다른 이름을 부여하여 조작을 구별하는 것입니다. –

답변

5

내 설계에는 근본적으로 잘못된 것이 있어야한다고 생각합니다.

유일하게 잘못된 것은 하나의 인수 메소드와 0 인수 메소드를 결합하려고 시도한다는 것입니다. 다른 문제에 대한 문호를 열지 않고서도 자바로 할 수는 없습니다.현재의 접근 방식

  • 스틱 명시 적으로 공허 경우 null을 통과 :

    은 기본적으로 세 가지 선택을 가지고있다.

  • Void 케이스를 처리하기 위해 두 번째 (인수 없음) 메소드를 인터페이스에 추가하고 null을 사용하여 하나의 인수 메소드를 호출하게합니다. 이 Void이 아닐 때 코드가 null을 처리해야하지만 어쨌든 않았습니다.

  • 인터페이스를 리팩터링하여 String prepareUrl()String prepareUrl(T)의 두 인터페이스를 구별하고 특수 사례 클래스로 구현하십시오.

개인적으로 옵션 2는 옵션 1보다 약간 좋지만 세 번째 옵션은 아마도 다른 문제로 이어질 것입니다. 예 : 두 가지 변형을 가진 특정 메서드는 T 형식의 전체 공간에서 다형 메서드 호출을 방해합니다.

(즉, 아마 당신의 문제에 대한 의미가 여러 인수에 대한 문을 열기 때문에 가변 인자가, 나쁜 생각입니다.) 당신은 처음부터 가변 인자 서명을 사용할 수

1

구현에 따라 다른 개수의 인수를 사용하려는 것처럼 보입니다.

이 얻을 수있는 가장 가까운

SchedulePageUrlGenerator 정말 UrlGenerator 경우 문제는 가변 인자

interface UrlGenerator<T> { 
    String prepareUrl(T... input); 
} 


// can use 
System.out.println(new StaticUrlGenerator("url").prepareUrl()); 

//or 
System.out.println(new StaticUrlGenerator("url").prepareUrl(null)); 
2

을 사용하는 것입니다. 다른 주장이 있다면 나는 그것이 아니라고 주장 할 것입니다. 인터페이스에 대한 선택적 인수가 있다면 호출 코드에서 다음과 같이해야합니다.

// this is not a good pattern 
if (urlGenerator instanceof SchedulePageUrlGenerator) { 
    (SchedulePageUrlGenerator)urlGenerator.prepareUrl(); 
} else { 
    urlGenerator.prepareUrl(...); 
} 

이것은 해킹 인 것 같습니다. 당신이 당신의 인터페이스에 많은 방법을 가지고 만 prepareUrl(...) 그때 내가 prepareUrl(...)Void 인수로 null 전달에 아무런 문제가 다른 볼 경우

이 모든

말했다. 인수 프레임 워크를 통해 인수를 생성하는 방법과 왜 null 인수가 그러한 문제인지 이해해야합니다. 하는 지원되는 그런 다음에 따라 UnsupportedOperationException을 던질 수

String prepareUrl(T input); 
String prepareUrlNoInput(); 

: 당신이 당신의 인터페이스에 더 많은 방법이있는 경우

또 다른 대안은, 다시, 준비 방법과 및 인수없이 모두을하는 것입니다 이행. 그러나 위와 같은 문구를 instanceofif과 같이해야한다면, null 인수가 더 좋습니다.

관련 문제