2013-04-26 2 views
6

나는 약간의 작업을 수행하는 util 클래스를 가지고 있습니다. 분명히 확장을 위해 닫히고 모든 메소드는 정적입니다. 간단하게하기 위해서, 클래스는 다음과 같습니다정적 클래스의 템플릿 메서드 패턴

public final class Util { 
    private Util() { } 

    public static void doWork() { 
     // some work 
     int variable = help(); 
     // some work uses variable 
    } 

    private static int help() { 
     // some helper functionality 
    } 
} 

클래스는 계산을 많이 수행하는 방법 doWork 있습니다. 그런데 메소드는 도우미 메소드 help을 호출하여 일부 결과를 얻고 나머지 코드는 help 메소드가 리턴 한 결과를 사용합니다.

이제 클라이언트 코드에서 doWork 메서드의 기능을 다시 사용하고 싶지만 help을 호출하는 대신 help2 메서드를 호출하고 싶습니다. 가장 간단한 해결책은 helphelp2으로 바꾸고 방법 doWork2을 만드는 것입니다.

doWork의 모든 변경 사항을 doWork2에 복제해야하므로 매우 나쁜 접근 방법입니다. 이것은 Template Method 패턴과 매우 유사하지만 여기에 확장 기능이 없기 때문에 적용 할 수 없습니다.

나는이 방법에 매개 변수를 추가 할 수 있지만 doWork의 모든 기존 사용자를 유지하기 위해 함께했다

최선의 해결책 :

더 나은 디자인 솔루션이 문제를 해결하기 위해 적용 할 수있는 무엇
public static void doWork() { 
    doWorkWithParameter(true); 
} 

public static void doWorkWithParameter(boolean helpOrHelp2) { 
    // some work 
    int variable = helpOrHelp2 ? help() : help2(); 
    // some work uses variable 
} 

? Template Pattern과 같은 유연성을 얻을 수있는 방법이 있지만 util 클래스에 적용 할 수 있습니다.

미리 감사드립니다.

+0

당신이 솔루션에 메서드 오버로드를 사용하지 않는 이유가 있나요? 'public static void doWork() {...}' 'public static void doWork (boolean param) {...}' – Crazenezz

+0

아니면 여전히'public static void doWork (int variable)'입니다. 비록 내가 실제적인 대답은 혼란이 통계학에 기인하고 그 물체가 더 추상적 인 예를 가지고 말하기가 더 깔끔한 답을 제공한다는 것입니다. –

+0

당신이 찾고있는 것은 전략 패턴입니다. Arnaldo의 대답을 확인하십시오. –

답변

5

나의 제안은 백분율 클래스는 호출자 각 doWork - 도움말 쌍입니다 Command Pattern에서 영감 작업자 인터페이스를 사용하여 캡슐화 : 또는 당신은 할 수 있습니다.

public class ConcreteWorker implements Worker{ 

    @Override 
    public void doWork() { 
     // TODO Auto-generated method stub 
      int variable = help(); 

    } 

    @Override 
    public int help() { 
     // TODO Auto-generated method stub 
     return 0; 
    } 

} 

또 다른 노동자

작업자 inteface을이 백분율 클래스

public final class Util { 
    private Util() { } 

    public static void toWork(Worker worker){ 
     worker.doWork(); 
    } 

} 

콘크리트 노동자

public interface Worker { 
    public void doWork(); 
    public int help(); 
} 

같은 몇 가지 수 (도움과 doWork의 구현)

그리고 실행

Util.toWork(new ConcreteWorker()); 
Util.toWork(new ConcreteWorker2()); 
+0

Worker 인터페이스 대신 doWork() 메소드로 추상 클래스로 만드는 것이 더 좋습니다. 이것은 실제로 내가 제안한 것과 동일하지만 더 많은 코드를 가지고 있습니다. 하나가 아닌 네 개의 클래스가 있습니다. 열거 형 (enum)은 정적 메서드를 더 효과적으로 대체한다고 가정합니다. – Mikhail

+1

좋아요! 그것은 전략 패턴'Collections.sort (lst, Comparator)'처럼 보입니다. 나는 그것을 어떻게 놓칠 수 있습니까? – mishadoff

1

당신은 도움() 메소드가 2 정적 객체 Help 인터페이스 느릅 나무를 구현 Help1 & Help2를 생성하고이처럼 doWorkWithParameter 방법을 변경할 수 있습니다 : 그것은 밀접하게 현재 솔루션에 관련이

public static void doWorkWithParameter(Help h) { 
    int variable = h.help(); 
} 

. 하지만 좀 더 "객체 지향"이라고 생각합니다.

1

그리 오래 전에 나는이 만든 :

public static enum Helper{ 
    OLD(){ 
     public int help(){ 
      return 0; 
     } 
    }, 

    NEW(){ 
     public int help(){ 
      return 1; 
     } 
    }; 

    public abstract int help(); 

    public void doWork() { 
     int variable = help(); 
    } 
} 

public static Helper HELPER = Helper.NEW; 

은 우리가 호출 할 수

Constants.HELPER.doWork() 

도우미 상수 값을 전환하여 나는 동작을 변경할 수 있습니다.

Helper.OLD.doWork(); 
Helper.NEW.doWork(); 
+0

고마워, 좋은 속임수. – mishadoff

+0

이것은 Effective Java book에서 발췌 한 것입니다 - "Item 34 : 인터페이스로 확장 가능한 에뮬레이션 에뮬레이션" – Mikhail

관련 문제