JAVA/Effective Java

클래스와 인터페이스 - 규칙 21 전략을 표현하고 싶을 때는 함수 객체를 사용하라.

반응형

호출 대상에 대해 어떠한 작업을 수행하는 것을

전략 패턴이라고 한다.



1
2
3
4
5
class StringCompare {
 public int compare (String s1, String s2) {
   return s1.length() - s2.length();
 }
}
cs



 두 개의 문자열을 받아서 비교하는 클래스를 사용할 수 있는 전략 패턴이다.
비교가 필요할 경우 매번 StringCompare 클래스를 생성하지 말고, 싱글톤 패턴을 정의하여 가져다가 사용하면 더욱 편리하다.

하지만 이 StringCompare 클래스의 경우 객체를 메서드에 전달하기 위해서는 인자의 자료형이 String이어야 한다. 

따라서 Compareator 인터페이스를 정의 하여 이를 StringComapre 클래스가 구현하도록 해야 한다.



1
2
3
4
5
6
7
8
9
10
11
// 인터페이스
public interface Comparator<T> {
  public int compare(T t1, T t2);
}
 
class StringCompare implements Comparator<String> {
  @Override 
  public int compare (String s1, String s2) {
   return s1.length() - s2.length();
  }
}
cs




정리하면,
 함수 객체의 주된 용도는 전략 패턴이다. 전략 패턴을 사용하기 위해서는 인터페이스 (위에서는 Comparator<String>)를 선언하고, 실행가능 전략 클래스 생성 시 저 위에 인터페이스를 구현하도록 해야 한다.

단, 전략 패턴이 한번만 사용할 경우 익명 클래스로 사용할 수 있다.



1
2
3
4
5
6
Arrays.sort(StringArray, new Comparator<String>() {
  @Overide
  public int compare (String s1, String s2) {
    return s1.length() - s2.length();
  }
});
cs



만약 자주 사용 되는 경우에는,
public static final 지시자를 사용하여 외부에 공개 할 수 있다.



1
2
3
4
5
6
7
8
9
10
11
class Host {
  private static Class StringCompare implements Comparator<String>, Serializable {
   public int comapare(String s1, String s2) {
    return s1.length() - s2.length();
   }
  }
 
  // Compare<String>를 구현한 클래스로, 다형성을 이용하여 StringCompare를 받을 수 있다.
  // 외부에서는 Host.STRING_LENGTH_COMPARATOR.compare("dd", "ff"); 방식으로 사용할 수 있다.
  public static final Comparator<String> STRING_LENGTH_COMPARATOR = new StringCompare();
}
cs



출처 : 조슈아 블로크, 『 Effective Java 2/E』, 이병준 옮김, 인사이트(2014.9.1), 규칙21 인용.



반응형