티스토리 뷰
728x90
1. 템플릿 메소드 패턴
- 알고리즘 구조를 서브 클래스가 확장할 수 있도록 템플릿으로 제공하는 방법
- 추상 클래스는 템플릿을 제공하고, 하위 클래스는 구체적인 알고리즘을 제공한다.
- AbstractClass : 템플릿 메서드를 정의하는 클래스 , 하위클래스에 공통 알고리즘을 정의하고 하위 클래스에 구체적인 알고리즘을 정의하는 클래스
- templateMethod() : 알고리즘의 구조를 표현한 메소드 (데이터를 읽고,처리하고, 리턴해주는)
- step1() : 하위클래스의 구체적인 알고리즘1
- step2() : 하위클래스의 구체적인 알고리즘2
- ConcreateClass : 물려받은 templateMethod를 구현하는 클래스
- step1() : 재정의가 필요한 하위클래스의 구체적인 알고리즘1
- step2() : 재정의가 필요한 하위클래스의 구체적인 알고리즘2
2. 템플릿 메소드 패턴 적용
- 숫자로 구성된 파일을 읽어 덧셈과 곱셈을 하는 코드를 작성한다.
2.1. 적용 전 코드
- 처리하는 코드의 중복이 많이 발생
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);
}
return result;
} catch (IOException e) {
throw new IllegalArgumentException(path + "에 해당하는 파일이 없습니다.", e);
}
}
}
public class MultuplyFileProcessor {
private String path;
public MultuplyFileProcessor(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);
}
return result;
} catch (IOException e) {
throw new IllegalArgumentException(path + "에 해당하는 파일이 없습니다.", e);
}
}
}
public class Client {
public static void main(String[] args) {
FileProcessor fileProcessor = new FileProcessor("number.txt");
int result = fileProcessor.process();
System.out.println(result);
}
}
2.2. 적용 후 코드1 : 상속을 이용한 템플릿메소드 패턴 적용
public abstract class FileProcessor {
private String path;
public FileProcessor(String path) {
this.path = path;
}
public final int process() {
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)); //해당 Line을 구체적인 알고리즘의 메소드화 진행
}
return result;
} catch (IOException e) {
throw new IllegalArgumentException(path + "에 해당하는 파일이 없습니다.", e);
}
}
protected abstract int getResult(int result, int number);
}
public class Plus extends FileProcessor {
public Plus(String path){
super(path);
}
@Override
public int getResult(int result, int number) {
return result += number;
}
}
public class Multiply extends FileProcessor {
public Multiply(String path) {
super(path);
}
@Override
protected int getResult(int result, int number) {
return result *= number;
}
}
public class Client {
public static void main(String[] args) {
FileProcessor fileProcessor = new Multiply("number.txt");
int result = fileProcessor.process((sum, number) -> sum += number);
System.out.println(result);
}
}
적용 후 코드2 : 템플릿 콜백(Template-Callback)패턴
- 콜백으로 상속 대신 위임을 사용하는 템플릿 패턴
- 상속 대신 익명 내부 클래스 또는 람다 표현식을 활용할 수 있다.
- 템플릿메소드패턴보다 클래스를 줄일 수 있다.
- 전략 패턴의 기본 구조에 인터페이스를 상속하는 클래스를 만들지 않고 익명 내부 클래스를 활용하는 방식
public interface Operator {
int getResult(int result, int number);
}
public 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 = operator.getResult(result, Integer.parseInt(line));
}
return result;
} catch (IOException e) {
throw new IllegalArgumentException(path + "에 해당하는 파일이 없습니다.", e);
}
}
}
public class Client {
public static void main(String[] args) {
// 람다식
int result = fileProcessor.process((sum, number) -> sum += number);
System.out.println(result);
// 익명 내부 클래스
int result2 = fileProcessor.process(new Operator(){
@Override
public int getResult(int result, int number){
return result *= number;
}
});
System.out.println(result2);
}
}
3. 장점 및 단점
3.1. 장점
- 템플릿 코드를 재사용하고 중복 코드를 줄일 수 있다.
- 템플릿 코드를 변경하지 않고 상속을 받아서 구체적인 알고리즘만 변경할 수 있다.
3.2. 단점
- 리스코프 치환 원칙을 위반할 수도 있다.
- 리스코프 치환 원칙 : 상위 타입의 객체를 하위 타입의 객체로 치환해도 상위 타입을 사용하는 프로그램은 정상적으로 동작해야 한다.
- 알고리즘 구조가 복잡할 수록 템플릿을 유지하기 어려워진다.
위글은 인프런의 코딩으로 학습하는 GoF의 디자인 패턴강의를 정리하였습니다.
백기선님의 수락으로 정리하였으며 더 자세한 내용은 강의를 수강하시기 바랍니다.
https://www.inflearn.com/course/%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4/dashboard
728x90
'디자인 패턴' 카테고리의 다른 글
21. 전략 패턴 (0) | 2022.02.11 |
---|---|
20. 상태(State) 패턴 (0) | 2022.02.11 |
19. 옵저버 패턴 (0) | 2022.02.11 |
18. 메멘토 패턴 (0) | 2022.02.10 |
17. 중재자 패턴 (0) | 2022.02.10 |
댓글