IT/Programming / / 2023. 4. 27. 09:31

<Effective Java> RULE 21 전략을 표현하고 싶을 때는 함수 객체를 사용하라

반응형

 

특정 함수를 호출할 수 있는 능력을 저장하고 전달할 수 있도록하는 함수포인터, 대리자, 람다표현식같은 것 들이 있다.

이런 기능은 보통 함수의 인자로 함수를 전달하기 위해 사용되며 호출된 함수의 기능을 변경하는 구실도 한다.

 

자바는 함수 포인터를 지원하지 않는다. 하지만 객체 참조를 통해 비슷한 효과를 달성할 수 있다.

 

객체의 메서드는 보통 호출 대상 객체에 뭔가를 한다.

하지만 다른 객체에 작용하는 메서드, 인자로 전달된 객체에 뭔가를 하는 메서드를 정의하는 것도 가능하다.

이런 객체를 함수 객체라고 한다.

class StringLengthComparator{
    public int compare(String s1, String s2){
        return s1.length() - s2.length();
    }
}
 

실행 가능 전략 : 이 메서드는 문자열을 알파벳 순서가 아닌 길이 순서대로 정렬한다. 이 기능을 통해 임의의 문자열 두개를 서로 비교할 수 있다.

 

무상태 클래스 : 필드가 없는 클래스.

 

위와 같은 클래스는 무상태 클래스며 싱글톤 패턴을 따르면 쓸데없는 객체 생성은 피할 수 있다.

class StringLengthComparator{
    private StringLengthComparator() {}
    public static final StringLengthComparator INSTANCE = new StringLengthComparator();
    public int compare(String s1, String s2){
        return s1.length() - s2.length();
    }
}
 

위의 클래스는 객체를 메서드에 전달하기 위해서는 인자의 자료형이 맞아야 하며 다른 전략을 전달할 수 없다.

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

class StringLengthComparator implements Comparator<String>{
    private StringLengthComparator() {}
    public static final StringLengthComparator INSTANCE = new StringLengthComparator();
    public int compare(String s1, String s2){
        return s1.length() - s2.length();
    }
}
 

요약

- 함수 객체의 주된 용도는 전략 패턴을 구현하는것이다.

- 자바로 이패턴을 구현하기 위해서는 전략을 표현하는 인터페이스를 선언하고 실행 가능 전략 클래스가 전부 해당 인터페이스를 구현하도록 해야한다.

- 실행가능 전략클래스가 전부 해당 인터페이스를 구현하도록 해야한다.

실행가능 전략이 한 번만 사용되는 경우에는 보통 그 전략을 익명 클래스 객체로 구현한다.

반복적으로 사용 된다면 private static 멤버 클래스로 전략을 표현한 다음, 전략 인터페이스가 자료형인 public static final 필드를 통해 외부에 공개하는것이 바람직 하다.

 

전략 패턴?

전략 패턴(Strategy pattern), 스트래티지 패턴(Strategy pattern)에서는 알고리즘군을 정의하고 각각을 캡슐화하여 교환해서 사용할 수 있도록 만든다. 스트래티지를 활용하면 알고리즘을 사용하는 클라이언트와는 독립적으로 알고리즘을 변경할 수 있다.

 

반응형
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유