728x90
반응형
Template Method Pattern
알고리즘 구조를 서브 클래스가 확장할 수 있도록 템플릿으로 제공하는 방법
추상 클래스는 템플릿을 제공하고 하위 클래스는 구체적인 알고리즘을 제공한다.
- 콜백으로 상속 대신 위임을 사용하는 템플릿 패턴
- 상속 대신 익명 내부 클래스 또는 람다 표현식을 사용할 수 있다.
BEFORE
Client
public class Client {
public static void main(String[] args) {
FileProcessor fileProcessor = new FileProcessor("number.txt");
int result = fileProcessor.process();
System.out.println(result);
}
}
FileProcessor
public class FileProcessor {
private String path;
public FileProcessor(String path) {
this.path = path;
}
public int process() {
try(BufferedReader reader = new BufferedReader(new FileReader(path))) {
int result = 0;
String line = null;
while((line = reader.readLine()) != null) {
result += Integer.parseInt(line);
// 깨알 상식
// .parseInt() : int 반환
// .valueOf() : Integer 반환
}
return result;
} catch (IOException e) {
throw new IllegalArgumentException(path + "에 해당하는 파일이 없습니다.", e);
}
}
}
AFTER
Client
public class Client {
public static void main(String[] args) {
FileProcessor fileProcessor = new Multiply("number.txt");
int result = fileProcessor.process((sum, number) -> sum += number);
int result = fileProcessor.process(new Plus()); // 두가지 모두 가능
System.out.println(result);
}
}
FileProcessor - Multiply
public abstract class FileProcessor {
private String path;
public FileProcessor(String path) {
this.path = path;
}
public final int process(Operator operator) {
try(BufferedReader reader = new BufferedReader(new FileReader(path))) {
int result = 0;
String line = null;
while((line = reader.readLine()) != null) {
result = getResult(result, Integer.parseInt(line));
}
return result;
} catch (IOException e) {
throw new IllegalArgumentException(path + "에 해당하는 파일이 없습니다.", e);
}
}
protected abstract int getResult(int result, int number);
}
public class Multiply extends FileProcessor {
public Multiply(String path) {
super(path);
}
@Override
protected int getResult(int result, int number) {
return result *= number;
}
}
Operator - Plus
public interface Operator {
abstract int getResult(int result, int number);
}
public class Plus implements Operator {
@Override
public int getResult(int result, int number) {
return result += number;
}
}
[패턴 복습]
장점 | 단점 |
- 템플릿 코드를 재사용하고 중복 코드를 줄일 수 있다. - 템플릿 코드를 변경하지 않고 상속을 받아서 구체적인 알고리즘만 변경 할 수 있다. |
- 리스코프 치환 원칙을 위반할 수도 있다. - 알고리즘 구조가 복잡할 수록 템플릿을 유지하기 어려워진다. |
리스코프 치환 원칙
부모객체와 이를 상속한 자식 객체가 있을 대 부모 객체를 호출하는 동작에서 자식 객체가 부모객체를 완전히 대체할 수 있다는 원칙
[실무에서 쓰이는 경우]
- 자바
- HttpServlet
- 스프링
- 템플릿 메소드 패턴 : Configuration
- 템플릿 콜백 패턴
- JdbcTemplate
- RestTemplate
- ...
728x90
반응형
'Design Patterns > 행동(Behavioral)' 카테고리의 다른 글
[Visitor]방문자 패턴 (0) | 2022.11.22 |
---|---|
[Strategy]전략패턴 (2) | 2022.11.22 |
[State]상태 패턴 (0) | 2022.11.22 |
[Observer]옵저버패턴 (0) | 2022.11.08 |
[Memento]메멘토패턴 (0) | 2022.11.03 |