개발/디자인패턴

[Java][디자인 패턴] 22. 템플릿 메서드 패턴

nova_dev 2022. 3. 26. 00:00
반응형

디자인패턴
[Java][디자인 패턴] 22. 템플릿 메서드 패턴

템플릿 메서드 패턴은 메서드를 이용해 각 단계를 템플릿 구조화하고 행동을 구분한다.

 

 템플릿 메서드 패턴이란?

  • 템플릿 메서드는 공통된 로직을 분리하여 캡슐화한다. (붕어빵 틀 만들기)
  • 공통 단계인 템플릿은 별도의 메서드로 작성한다. 이 때 공통 기능이 하위 클래스에서 오버라이딩 되지 않도록 final을 사용한다.
  • 템플릿 메서드는 공통된 알고리즘을 정의하며, 공통된 로직을 처리하는 행동이다. 템플릿 메서드는 로직 전체의 구조를 변경하지 않고 일부분만 수정할 때 유용하다.
  • 큰 틀의 공통된 로직만 처리하는 메서드와 변화된 작은 동작을 처리하는 메서드를 서로 분리한다. 이런 분리는 추상 클래스로 구현한다.

 

 

 템플릿 메서드 패턴 예시 코드 구조

템플릿 메서드 패턴은 틀을 만드는 것과 같다. 마치 붕어빵 기계의 틀을 만들어서, 붕어빵 안에 어떤 팥을 넣고 밀가루를 어떤것을 쓰느냐에 따라 붕어빵, 찹쌀 팥 붕어빵, 슈크림 붕어빵, 피자 붕어빵 등의 다양한 붕어빵들을 만들 수 있는 것과 같이 항상 비슷한 애들을 만들고 만드는 과정이 비슷하다면, 이 중 공통화 시킬 수 있는 부분을 빼내서 추상클래스로 만들어 템플릿으로 만드는게 템플릿 메서드 패턴의 특징이다.

예시코드에서는 햄버거를 만들 수 있는 햄버거 템플릿을 만들고, 치킨 버거와 불고기 버거 등을 소스와 야채, 빵만 변경해가면서 만들 수 있도록 코드를 구성했다.

 템플릿 메서드 패턴 코드

1. Hamberger 클래스

public class Hamburger {
    private String bread;
    private List<String> meat;
    private String source;
    private List<String> vegetable;

    @Override
    public String toString() {
        return "Hamburger{" +
                "bread='" + bread + '\'' +
                ", meat=" + meat +
                ", source='" + source + '\'' +
                ", vegetable=" + vegetable +
                '}';
    }

    public void setBread(String bread) {
        this.bread = bread;
    }

    public void setMeat(List<String> meat) {
        this.meat = meat;
    }

    public void setSource(String source) {
        this.source = source;
    }

    public void setVegetable(List<String> vegetable) {
        this.vegetable = vegetable;
    }
}

2. HamburgerTemplate 추상 클래스

public abstract class HamburgerTemplate {

    public final Hamburger make() {
        System.out.println("==햄버거 만들기==");
        Hamburger hamburger = new Hamburger();

        String bread = bread();
        System.out.println("1. 빵 올리기 : " + bread);
        hamburger.setBread(bread);

        List<String> meatList = meatList();
        System.out.println("2. 고기 올리기: " + meatList);
        hamburger.setMeat(meatList);

        String source = source();
        System.out.println("3. 소스 올리기: " + source);
        hamburger.setSource(source);

        List<String> vegetableList = vegetableList();
        System.out.println("4. 야채 올리기: " + vegetableList);
        hamburger.setVegetable(vegetableList);

        System.out.println("==완성==");
        return hamburger;
    }

    protected abstract String bread();

    protected abstract List<String> meatList();

    protected abstract String source();

    abstract protected List<String> vegetableList();

}

3. HamburgerTemplate을 상속받아 만드는 불고기 버거와 치킨 버거

public class BulgogiBurger extends HamburgerTemplate {
    @Override
    protected String bread() {
        return "빵";
    }

    @Override
    protected List<String> meatList() {
        return Collections.singletonList("불고기");
    }

    @Override
    protected String source() {
        return "불고기맛 소스";
    }

    @Override
    protected List<String> vegetableList() {
        return Arrays.asList("양배추", "토마토");
    }
}
public class ChickenBurger extends HamburgerTemplate {
    @Override
    protected String bread() {
        return "빵";
    }

    @Override
    protected List<String> meatList() {
        return Collections.singletonList("치킨");
    }

    @Override
    protected String source() {
        return "달달구리 소스";
    }

    @Override
    protected List<String> vegetableList() {
        return Arrays.asList("양배추", "토마토");
    }
}

5. 테스트 코드

 

class HamburgerTest {
    @Test
    @DisplayName("치킨버거 테스트")
    void chickenTest() {
        HamburgerTemplate hamburgerTemplate = new ChickenBurger();
        Hamburger hamburger = hamburgerTemplate.make();
    }

    @Test
    @DisplayName("불고기버거 테스트")
    void bulgogiTest() {
        HamburgerTemplate hamburgerTemplate = new BulgogiBurger();
        Hamburger hamburger = hamburgerTemplate.make();
    }
}

 

==햄버거 만들기==
1. 빵 올리기 : 빵
2. 고기 올리기: [치킨]
3. 소스 올리기: 달달구리 소스
4. 야채 올리기: [양배추, 토마토]
==완성==
==햄버거 만들기==
1. 빵 올리기 : 빵
2. 고기 올리기: [불고기]
3. 소스 올리기: 불고기맛 소스
4. 야채 올리기: [양배추, 토마토]
==완성==

 Github 코드

Github 예제 코드 링크

Github 예제 테스트 코드 링크

참고 자료

 

 

 

 

 

반응형