안녕하세요. J4J입니다.
이번 포스팅은 템플릿 메서드 (Template Method) 패턴에 대해 적어보는 시간을 가져보려고 합니다.
Template Method 패턴이란?
template method 패턴은 상위 클래스에서 공통으로 사용되는 템플릿을 제공하여 하위 클래스에서 구체적인 단계를 재 정의할 수 있도록 도와줍니다.
template method의 기본 구조는 다음과 같습니다.
구조를 보시면 상위 클래스에서는 공통으로 재 사용될 수 있는 메서드 (= Template Method)를 제공하고 있습니다.
그리고 하위 클래스 별로 상세 로직을 정의할 수 있도록 추상 메서드 (= Primitive Method)를 제공하고 있습니다.
개인적으로 template method는 구조만 확인하더라도 어떤 목적으로써 사용되는지 한 눈에 확인되는 디자인 패턴 중 하나인 것으로 생각합니다.
구조를 보고 이해되시는 것처럼 동일한 목적을 가지는 공통 기능을 가지고 있어야 하지만 일부 기능들에 대해서는 서로 다른 비즈니스 로직이 필요하다고 생각한다면 template method를 사용은 여러 선택지 중 한 개가 될 수 있습니다.
template method를 사용하지 않는다면 각각의 기능 처리가 필요할 때 분기를 나누는 행위를 해야 할 수 있습니다.
예를 들어 다음과 같은 소스 코드가 작성될 수 있습니다.
public void method() {
// 공통 기능 처리
// 타입 별 기능 처리
switch(type) {
// A 타입 정의
// B 타입 정의
}
// 공통 기능 처리
}
이런 코드를 작성하는 것이 자연스러운 행위일 수 있지만 위와 같은 타입 별 기능 처리를 하는 구간이 많아지거나, 분기 처리되어야 하는 타입들이 많아진다면 결국 확장성 있는 개발을 하기 어렵게 만듭니다.
매번 타입이 추가되거나 삭제될 때 공통으로 사용되는 기능들을 변경해야 되기 때문에 예상치 못한 다양한 문제들도 발생시킬 수 있습니다.
해당 상황에서 만약 소스 코드가 다음과 같이 변경된다고 가정해보겠습니다.
public void method() {
// 공통 기능 처리
primitiveMethod();
// 공통 기능 처리
}
public void primitiveMethod();
코드가 위와 같이 변경된다면 매번 타입의 변경 사항에 대해 고려하지 않게 될 것이고 결국 확장성이 개발을 하게 될 겁니다.
즉, 타입 별 상세 로직이 더 많이 필요하게 되더라도 전체적인 구조에 영향을 주는 상황은 발생하지 않게 됩니다.
Template Method 패턴 특징
template method 패턴의 특징은 다음과 같습니다.
[ 장점 ]
- 상위 클래스가 가지고 있는 구조를 재 사용할 수 있음
- 새로운 유형에 대한 확장성이 좋아짐
- 하위 클래스만이 가지고 있는 로직에 대해 집중할 수 있음
- 템플릿을 기반으로 원하는 부분만 재 정의하여 사용할 수 있음
[ 단점 ]
- 상위 클래스에 의존되어 있기 때문에 공통 로직이 변경되는 경우 하위 클래스들에 영향도를 검토해야 함
- 정해진 템플릿에 의존되어 있기 때문에 전체 구조를 벗어나는 행위를 할 수 없음
- 필요한 하위 클래스만큼 클래스 파일의 개수가 증가함
template method의 가장 큰 특징은 결국 oop의 추상화와 다형성이라고 얘기해 볼 수 있습니다.
추상 메서드를 선언하여 하위 클래스에서 정의를 하도록 제공하고 있으며, 동일한 상위 클래스를 이용한 다형성의 특징도 확인해 볼 수 있습니다.
Template Method 패턴 예시 (1) - Before
이번엔 template method를 활용한 간단한 예시를 작성해 보겠습니다.
먼저 template method 패턴을 적용하지 않는 경우입니다.
// shape
package com.jforj.templatemethod.before;
public class Shape {
public void printShape(String type, int width, int height, int radius) {
System.out.println("print common shape.");
System.out.println("calculate area");
int area = 0;
switch (type) {
case "circle": {
area = radius * radius;
break;
}
case "rectangle": {
area = width * height;
break;
}
}
System.out.println("area of shape is " + area);
}
}
// main
package com.jforj.templatemethod.before;
public class Main {
public static void main(String[] args) {
Shape circle = new Shape();
circle.printShape("circle", 0, 0, 3);
Shape rectangle = new Shape();
rectangle.printShape("rectangle", 4, 3, 0);
}
}
원과 직사각형이 모두 소유할 수 있는 도형의 넓이에 대해 계산을 해야 되는 상황에서 위와 같은 코드가 작성될 수 있습니다.
하지만 각 도형마다 특징들을 가지고 있기 때문에 특징들을 고려하여 넓이를 구하는 코드가 작성되어야 합니다.
그러다 보니 모든 경우를 고려한 비즈니스 로직이 한 곳에 담기게 되고 확장성이 좋지 않은 코드가 된 것을 확인할 수 있습니다.
Template Method 패턴 예시 (2) - After
이번엔 위의 코드에서 template method 패턴을 적용해 보겠습니다.
// shape
package com.jforj.templatemethod.after;
public abstract class Shape {
public void printShape() {
System.out.println("print common shape.");
System.out.println("calculate area");
int area = calculate();
System.out.println("area of shape is " + area);
}
public abstract int calculate();
}
// circle
package com.jforj.templatemethod.after;
public class Circle extends Shape {
private int radius;
public Circle(int radius) {
this.radius = radius;
}
@Override
public int calculate() {
return radius * radius;
}
}
// rectangle
package com.jforj.templatemethod.after;
public class Rectangle extends Shape {
private int width;
private int height;
public Rectangle(int width, int height) {
this.width = width;
this.height = height;
}
@Override
public int calculate() {
return width * height;
}
}
// main
package com.jforj.templatemethod.after;
public class Main {
public static void main(String[] args) {
Shape circle = new Circle(3);
circle.printShape();
Shape rectangle = new Rectangle(4, 3);
rectangle.printShape();
}
}
코드를 보시면 상위 클래스를 기반으로 하위 클래스 별 특징들을 각각 정의하여 코드가 작성된 것을 확인할 수 있습니다.
다른 타입들이 가지고 있어야 하는 불필요한 정보들도 모두 제거되고 하위 클래스에서 필요한 것에만 집중되어 구체적인 정의가 된 것도 볼 수 있습니다.
이상으로 템플릿 메서드 (Template Method) 패턴에 대해 간단하게 알아보는 시간이었습니다.
읽어주셔서 감사합니다.
'설계 > 디자인패턴' 카테고리의 다른 글
[디자인패턴] 옵저버(Observer) 패턴 이해하기 (0) | 2024.04.30 |
---|---|
[디자인패턴] 추상 팩토리(Abstract Factory) 패턴 이해하기 (0) | 2024.04.28 |
[디자인패턴] 팩토리 메서드(Factory Method) 패턴 이해하기 (0) | 2024.04.22 |
[디자인패턴] 퍼사드(Facade) 패턴 이해하기 (0) | 2024.04.01 |
[디자인패턴] 싱글톤(Singleton) 패턴 이해하기 (0) | 2024.03.30 |
댓글