템플릿 메서드 패턴

yanju·2023년 1월 13일
0
post-thumbnail

템플릿 메소드 패턴

템플릿 메소드 패턴은 전체적으로는 동일하면서 부분적으로는 다른 구문으로 구성된 메서드의 코드 중복을 최소화할 때 유용하다.

동일한 기능을 상위 클래스에서 정의하면서 확장, 변화가 필요한 부분만 서브 클래스에서 구현할 수 있도록 한다.

여러 데이터 마이닝 클래스들

// DocDataMiner
rawData = extractDocData(file)
data = parseDocData(rawData)

// CSVDataMiner
rawData = extractCSVData(file)
data = parseCSVData(rawData)

// PDFDataMiner
rawData = extractPDFData(file)
data = parsePDFData(rawData)

위 세 클래스에는 유사한 코드가 많다.

다양한 데이터 형식을 처리하는 코드는 클래스마다 다르지만 데이터 처리 및 분석을 위한 코드는 거의 같다.

알고리즘은 그대로 두고, 코드 중복을 제거하는 방법이 필요하다.

해결책

세 가지 변환 알고리즘을 일련의 단계로 나누고, 이를 메서드로 변환한다.

그리고 단일 템플릿 메서드 내부에서 위에서 변환한 메서드들을 호출한다.

다양한 변환 알고리즘을 사용하기 위해 변환 메소드는 추상화한다.

class DataMiner {

	public void mine(Path path) { // 템플릿 메소드
		file = openFile(path)
		rawData = extractData(file)
		data = parseData(rawData)  // 이 메소드를 하위 클래스에서 재정의함
		analysis = analyzeData(data)	
		sendReport(analysis)
		closeFile(file)
	}

	protected abstract Data parseData(Data data); // 자식 클래스에서 구현 강제화
}
class PDFDataMiner extends DataMiner {

	protected Data parseData(Data data) {
		rawData = extractPDFData(file)
		data = parsePDFData(rawData)
		return data;
	}

}
class CSVDataMiner extends DataMiner {

	protected Data parseData(Data data) {
		rawData = extractCSVData(file)
		data = parseCSVData(rawData)
		return data;
	}

}

위 예제처럼 DataMiner 클래스의 mine 메소드는 PDFDataMiner, CSVDataMiner에서 동일한 기능을 구현한다.

각 자식 클래스에서 구체적으로 정의가 필요한 부분, 즉 parseData 메소드 부분만 각 하위 클래스에서 오버라이드 되도록 한다.

이러한 경우 mine 메소드를 템플릿 메소드라고 부른다.

오버라이드할 필요가 있는 parseDataprimitive 또는 hook 메소드라 부른다.

자바 / 스프링과 템플릿 메서드 패턴

자바

  • HttpServlet

스프링

템플릿 메소드 패턴

  • Configuration

템플릿 콜백 패턴

  • JdbcTemplae
  • RestTemplate

HttpServlet

보통 다음과 같이 HttpServlet을 상속 받아서 doGet, doPost를 재정의한다.

public class MyHello extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doGet(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}

doGet, doPost는 다음과 같이 HttpServlet 안에 service 템플릿 메소드 안에서 호출한다.

템플릿 콜백 패턴

RestTemplate을 이용할때 exchange를 이용해 요청을 보낸다.

// RestTemplate
RestTemplate restTemplate = new RestTemplate();

HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
headers.set("X-COM-PERSIST", "NO");
headers.set("X-COM-LOCATION", "USA");

HttpEntity<String> entity = new HttpEntity<String>(headers);
ResponseEntity<String> responseEntity = restTemplate
        .exchange("http://localhost:8080/users", HttpMethod.GET, entity, String.class);

다음과 같이 doExceute 템플릿 메소드에서 재정의한 execute를 사용한다.

0개의 댓글