자바/자바 자료실

[디자인 패턴] 08. 템플릿 메소드 패턴 (Template Method Pattern)

Chipmunks 2018. 10. 23.
728x90


템플릿 메소드 패턴 (Template Method Pattern)

어떤 작업 알고리즘의 골격을 정의합니다. 일부 단계는 서브클래스에서 구현하도록 할 수 있습니다.

템플릿 메소드를 이용하면 알고리즘의 구조는 그대로 유지하면서 특정 단계만 서브클래스에서 새로 정의하도록 할 수 있습니다.


객체지향 원칙

헐리우드 원칙

저수준 구성요소에서 시스템에 접속을 할 수는 있지만, 언제 어떤 식으로 그 구성요소들을 사용할지는 고수준 구성요소에서 결정합니다.

템플릿 메소드 패턴에서, 구상 클래스는 절대로 추상 클래스를 직접 호출하지 않습니다. 구상 클래스를 활용하는 것은 오로지 추상 클래스의 몫입니다.


예제 코드

1. 바리스타 커피 예제 코드

- barista/CaffeineBeverage

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package barista;
 
public abstract class CaffeineBeverage {
  
    final void prepareRecipe() {
        boilWater();
        brew();
        pourInCup();
        addCondiments();
    }
 
    abstract void brew();
  
    abstract void addCondiments();
 
    void boilWater() {
        System.out.println("Boiling water");
    }
  
    void pourInCup() {
        System.out.println("Pouring into cup");
    }
}
 
cs


- barista/Coffee.java


1
2
3
4
5
6
7
8
9
10
11
package barista;
 
public class Coffee extends CaffeineBeverage {
    public void brew() {
        System.out.println("Dripping Coffee through filter");
    }
    public void addCondiments() {
        System.out.println("Adding Sugar and Milk");
    }
}
 
cs


- barista/Tea.java


1
2
3
4
5
6
7
8
9
10
11
package barista;
 
public class Tea extends CaffeineBeverage {
    public void brew() {
        System.out.println("Steeping the tea");
    }
    public void addCondiments() {
        System.out.println("Adding Lemon");
    }
}
 
cs


- barista/CaffeineBeverageWithHook.java


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package barista;
 
public abstract class CaffeineBeverageWithHook {
 
    final void prepareRecipe() {
        boilWater();
        brew();
        pourInCup();
        if (customerWantsCondiments()) {
            addCondiments();
        }
    }
 
    abstract void brew();
 
    abstract void addCondiments();
 
    void boilWater() {
        System.out.println("Boiling water");
    }
 
    void pourInCup() {
        System.out.println("Pouring into cup");
    }
 
    boolean customerWantsCondiments() {
        return true;
    }
}
 
cs


- barista/CoffeeWithHook.java


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package barista;
 
import java.io.*;
 
public class CoffeeWithHook extends CaffeineBeverageWithHook {
 
    public void brew() {
        System.out.println("Dripping Coffee through filter");
    }
 
    public void addCondiments() {
        System.out.println("Adding Sugar and Milk");
    }
 
    public boolean customerWantsCondiments() {
 
        String answer = getUserInput();
 
        if (answer.toLowerCase().startsWith("y")) {
            return true;
        } else {
            return false;
        }
    }
 
    private String getUserInput() {
        String answer = null;
 
        System.out.print("Would you like milk and sugar with your coffee (y/n)? ");
 
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        try {
            answer = in.readLine();
        } catch (IOException ioe) {
            System.err.println("IO error trying to read your answer");
        }
        if (answer == null) {
            return "no";
        }
        return answer;
    }
}
 
cs


- barista/TeaWithHook.java


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
package barista;
 
import java.io.*;
 
public class TeaWithHook extends CaffeineBeverageWithHook {
 
    public void brew() {
        System.out.println("Steeping the tea");
    }
 
    public void addCondiments() {
        System.out.println("Adding Lemon");
    }
 
    public boolean customerWantsCondiments() {
 
        String answer = getUserInput();
 
        if (answer.toLowerCase().startsWith("y")) {
            return true;
        } else {
            return false;
        }
    }
 
    private String getUserInput() {
        // get the user's response
        String answer = null;
 
        System.out.print("Would you like lemon with your tea (y/n)? ");
 
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        try {
            answer = in.readLine();
        } catch (IOException ioe) {
            System.err.println("IO error trying to read your answer");
        }
        if (answer == null) {
            return "no";
        }
        return answer;
    }
}
 
cs


- barista/BeverageTestDrive.java


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package barista;
 
public class BeverageTestDrive {
    public static void main(String[] args) {        
        Tea tea = new Tea();
        Coffee coffee = new Coffee();
 
        System.out.println("\nMaking tea...");
        tea.prepareRecipe();
 
        System.out.println("\nMaking coffee...");
        coffee.prepareRecipe();
 
 
        TeaWithHook teaHook = new TeaWithHook();
        CoffeeWithHook coffeeHook = new CoffeeWithHook();
 
        System.out.println("\nMaking tea...");
        teaHook.prepareRecipe();
 
        System.out.println("\nMaking coffee...");
        coffeeHook.prepareRecipe();
    }
}
 
cs


2. 오리 정렬 예제 코드

- sort/Duck.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package sort;
 
public class Duck implements Comparable<Duck> {
    String name;
    int weight;
  
    public Duck(String name, int weight) {
        this.name = name;
        this.weight = weight;
    }
 
    public String toString() {
        return name + " weighs " + weight;
    }
  
    public int compareTo(Duck object) {
 
        Duck otherDuck = object;
  
        if (this.weight < otherDuck.weight) {
            return -1;
        } else if (this.weight == otherDuck.weight) {
            return 0;
        } else { // this.weight > otherDuck.weight
            return 1;
        }
    }
}
 
cs


- sort/DuckSortTestDrive.java


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package sort;
 
import java.util.Arrays;
 
public class DuckSortTestDrive {
 
    public static void main(String[] args) {
        Duck[] ducks = { 
                        new Duck("Daffy"8), 
                        new Duck("Dewey"2),
                        new Duck("Howard"7),
                        new Duck("Louie"2),
                        new Duck("Donald"10), 
                        new Duck("Huey"2)
         };
 
        System.out.println("Before sorting:");
        display(ducks);
 
        Arrays.sort(ducks);
 
        System.out.println("\nAfter sorting:");
        display(ducks);
    }
 
    public static void display(Duck[] ducks) {
        for (Duck d : ducks) {
            System.out.println(d);
        }
    }
}
 
cs


댓글