hongcheol / CS-study

cs지식을 정리하는 공간
MIT License
248 stars 30 forks source link

템플릿 메소드 패턴 #132

Open hongcheol opened 3 years ago

hongcheol commented 3 years ago

템플릿 메소드 패턴

템플릿 메소드 패턴은 알고리즘의 구조를 메소드에 정의하고, 하위 클래스에서 알고리즘 구조의 변경없이 알고리즘을 재정의하는 디자인 패턴입니다.

알고리즘이 단계별로 나누어지거나 같은 역할을 하는 메소드이지만 여러 곳에서 다른 형태로 사용이 필요한 경우 유용하게 사용됩니다.

변하지 않는 기능을 상위 클래스에 만들어두고 상속해 사용하고 자주 변경하며 확장할 기능은 하위 클래스에서 만들도록 하는 방식입니다.

구현 방식은 추상클래스와 구현클래스로 작성하며, 메인이 되는 로직 부분은 추상 클래스의 일반 메소드로 선언해서 사용합니다. 그 후 구현마다 달라질 수 있는 메소드들은 구현 클래스에서 선언 후 호출하는 방식으로 사용됩니다.

template-method-pattern

//AbstractClass.java
public abstract class AbstractClass {

    protected abstract void hook1();

    protected abstract void hook2();

    public void templateMethod() {
        hook1();
        hook2();
    }

}
//ConcreteClass.java
public class ConcreteClass extends AbstractClass {

    @Override
    protected void hook1() {
        System.out.println("ABSTRACT hook1 implementation");
    }

    @Override
    protected void hook2() {
        System.out.println("ABSTRACT hook2 implementation");
    }

}
//TemplateMethodPatternClient.java
public class TemplateMethodPatternClient {
    public static void main(String[] args) {
        AbstractClass abstractClass = new ConcreteClass();
        abstractClass.templateMethod();
    }
}

장점

  1. 코드의 중복 제거
  2. 자식 클래스의 역할을 줄여서 핵심 로직의 관리가 용이
  3. 코드를 객체지향적으로 구성할 수 있다.

    단점

  4. 추상 메소드가 많아져 클래스 관리가 복잡하다.
  5. 클래스간의 관계와 코드가 꼬일 수 있다.

예제 AbstractMap<K,V>

public V get(Object key) {
    Iterator<Entry<K,V>> i = entrySet().iterator();
    if (key==null) {
        while (i.hasNext()) {
            Entry<K,V> e = i.next();
            if (e.getKey()==null)
                return e.getValue();
        }
    } else {
        while (i.hasNext()) {
            Entry<K,V> e = i.next();
            if (key.equals(e.getKey()))
                return e.getValue();
        }
    }
    return null;
}

HashMap<K,V> extends AbstractMap<K,V> 의 get()

public V get(Object key) {
    Node<K,V> e;
    return (e = getNode(hash(key), key)) == null ? null : e.value;
}

public class TreeMap<K,V> extends AbstractMap<K,V> 의 get() 메소드

public V get(Object key) {
    Entry<K,V> p = getEntry(key);
    return (p==null ? null : p.value);
}

추상클래스 vs 인터페이스 (Java 8 기준)

추상클래스, 인터페이스 사용 예시

추상클래스