1. 개요

이 빠른 사용방법(예제)에서는 가장 인기 있는 GoF 패턴 중 하나인 템플릿 메서드 패턴 을 활용하는 방법을 살펴봅니다 .

단일 메서드에 논리를 캡슐화하여 복잡한 알고리즘을 더 쉽게 구현할 수 있습니다.

2. 시행

템플릿 메서드 패턴이 어떻게 작동하는지 보여주기 위해 컴퓨터 스테이션 구축을 나타내는 간단한 예제를 만들어 보겠습니다.

패턴의 정의가 주어지면 알고리즘의 구조는 템플릿 build() 메서드 를 정의하는 기본 클래스에서 정의됩니다 .

public abstract class ComputerBuilder {
    
    // ...
    
    public final Computer buildComputer() {
        addMotherboard();
        setupMotherboard();
        addProcessor();
        return new Computer(computerParts);
    }
   
    public abstract void addMotherboard();
    public abstract void setupMotherboard();
    public abstract void addProcessor();
    
    // ...
}

ComputerBuilder 클래스 는 마더보드 및 프로세서와 같은 다양한 구성 요소를 추가하고 설정하는 방법을 선언하여 컴퓨터를 구축하는 데 필요한 단계를 설명합니다 .

여기서 build() 메서드 는 컴퓨터 부품을 조립하는 알고리즘의 단계를 정의하고 완전히 초기화된 Computer 인스턴스 를 반환 하는 템플릿 메서드 입니다.

재정의되는 것을 방지하기 위해 i t가 final 로 선언되어 있음에 유의 하십시오.

3. 실행 중

기본 클래스가 이미 설정되어 있으므로 두 개의 하위 클래스를 만들어 사용해보자. 하나는 "표준" 컴퓨터를 구축하고 다른 하나는 "고사양" 컴퓨터를 구축합니다.

public class StandardComputerBuilder extends ComputerBuilder {

    @Override
    public void addMotherboard() {
        computerParts.put("Motherboard", "Standard Motherboard");
    }
    
    @Override
    public void setupMotherboard() {
        motherboardSetupStatus.add(
          "Screwing the standard motherboard to the case.");
        motherboardSetupStatus.add(
          "Pluging in the power supply connectors.");
        motherboardSetupStatus.forEach(
          step -> System.out.println(step));
    }
    
    @Override
    public void addProcessor() {
        computerParts.put("Processor", "Standard Processor");
    }
}

다음은 HighEndComputerBuilder 변형입니다.

public class HighEndComputerBuilder extends ComputerBuilder {

    @Override
    public void addMotherboard() {
        computerParts.put("Motherboard", "High-end Motherboard");
    }
    
    @Override
    public void setupMotherboard() {
        motherboardSetupStatus.add(
          "Screwing the high-end motherboard to the case.");
        motherboardSetupStatus.add(
          "Pluging in the power supply connectors.");
        motherboardSetupStatus.forEach(
          step -> System.out.println(step));
    }
    
    @Override
    public void addProcessor() {
         computerParts.put("Processor", "High-end Processor");
    }
}

보시다시피 전체 어셈블리 프로세스에 대해 걱정할 필요가 없으며 별도의 메서드에 대한 구현을 제공하는 데만 필요합니다.

이제 실제로 작동하는 것을 살펴보겠습니다.

new StandardComputerBuilder()
  .buildComputer();
  .getComputerParts()
  .forEach((k, v) -> System.out.println("Part : " + k + " Value : " + v));
        
new HighEndComputerBuilder()
  .buildComputer();
  .getComputerParts()
  .forEach((k, v) -> System.out.println("Part : " + k + " Value : " + v));

4. 자바 코어 라이브러리의 템플릿 메서드

이 패턴은 Java 코어 라이브러리(예: java.util.AbstractList 또는 java.util.AbstractSet)에서 널리 사용됩니다.

예를 들어 Abstract List 는 List 인터페이스 의 뼈대 구현을 제공합니다 .

템플릿 메서드의 예는 addAll() 메서드일 수 있지만 명시적으로 final로 정의되지는 않았습니다.

public boolean addAll(int index, Collection<? extends E> c) {
    rangeCheckForAdd(index);
    boolean modified = false;
    for (E e : c) {
        add(index++, e);
        modified = true;
    }
    return modified;
}

사용자는 add() 메서드만 구현하면 됩니다.

public void add(int index, E element) {
    throw new UnsupportedOperationException();
}

여기서 주어진 인덱스(List 알고리즘의 변형 부분)에서 List에 요소를 추가하기 위한 구현을 제공하는 것은 프로그래머의 책임입니다.

5. 결론

이 기사에서는 템플릿 메소드 패턴과 이를 Java로 구현하는 방법을 보여주었습니다.

템플릿 메서드 패턴은 코드 재사용 및 분리를 촉진하지만 상속을 사용하는 비용이 있습니다.

항상 그렇듯이 이 문서에 표시된 모든 코드 샘플은 GitHub 에서 사용할 수 있습니다 .

Generic footer banner