소행성이야기

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

소행성왕자 2018. 7. 11. 09:35

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


template method 패턴은 고차원 중복을 제거할 목적으로 자주 사용하는 기법입니다.

간단한 예와 개념을 살펴보도록 하겠습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
 
class VacationPolicy
{
    public function accrueUSDivisionVacation() {
        // 지금까지 근무한 시간을 바탕으로 휴가 일수를 계산하는 코드
        ...
        ...
        // 휴가 일수가 미국 최소 법정 일수를 만족하는지 확인하는 코드
        ...
        ...
        // 휴가 일수를 급여 대장에 적용하는 코드
    }
 
    public function accrueEUDivisionVacation() {
        // 지금까지 근무한 시간을 바탕으로 휴가 일수를 계산하는 코드
        ...
        ...
        // 휴가 일수가 유럽 연합 최소 최소 법정 일수를 만족하는지 확인하는 코드
        ...
        ...
        // 휴가 일수를 급여 대장에 적용하는 코드
    }
}
cs



위 소스코드를 보면 최소 법정 일수를 계산하는 코드만 제외하면 두 메서드는 동일합니다.

최소 법정 일수를 계산하는 알고리즘은 직원 유형에 따라 변합니다.

여기서 바로 template method 패턴 을 적용하여 눈에 들어오는 중복을 제거합니다.

코드를 한번 보겠습니다.


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
<?php
 
abstract class VacationPolicy 
{
    public function accrueVacation() {
        $this->calculateBaseVacationHours();
        $this->alterForLegaMinimums();
        $this->applyToPayroll();
    }
 
    private function calculateBaseVacationHours() { }
    abstract function alterForLegaMinimums();
    private function applyToPayroll() { }
}
 
class USVacationPolicy extends VacationPolicy
{
    public function alterForLegaMinimums() {
        //미국 최소 법정일수를 사용
    }
}
 
class EUVacationPolicy extends VacationPolicy
{
    public function alterForLegaMinimums() {
        //유럽연합 최소 법정 일수를 사용
    }
}
cs

또 하나의 예제를 보겠습니다.

아래 예제는 화면에 출력될 2개를 분리하는 예제입니다.

위의 예제와 마찬가지로 거의 비슷한 함수가 있을때 사용하시면 됩니다.



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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
<?php
 
abstract class TemplateAbstract {
    public final function showBookTitleInfo($book_in) {
        $title = $book_in->getTitle();
        $author = $book_in->getAuthor();
        $processedTitle = $this->processTitle($title);
        $processedAuthor = $this->processAuthor($author);
       
    if (NULL == $processedAuthor) {
            $processed_info = $processedTitle;
        } else {
            $processed_info = $processedTitle.' by '.$processedAuthor;
        }
        return $processed_info;
    }
    abstract function processTitle($title);
    function processAuthor($author) {
        return NULL;
    } 
}
 
class TemplateExclaim extends TemplateAbstract {
    function processTitle($title) {
      return Str_replace(' ','!!!',$title); 
    }
    function processAuthor($author) {
      return Str_replace(' ','!!!',$author);
    }
}
 
class TemplateStars extends TemplateAbstract {
    function processTitle($title) {
        return Str_replace(' ','*',$title); 
    }
}
 
 
class Book {
    private $author;
    private $title;
    function __construct($title_in$author_in) {
        $this->author = $author_in;
        $this->title  = $title_in;
    }
    function getAuthor() { return $this->author; }
    function getTitle() { return $this->title; }
    function getAuthorAndTitle() {
        return $this->getTitle() . ' by ' . $this->getAuthor();
    }
}
 
 
$book = new Book('PHP for Cats','Larry Truett');
 
$exclaimTemplate = new TemplateExclaim();  
$starsTemplate = new TemplateStars();
 
echo 'show exclaim template'.PHP_EOL;
echo $exclaimTemplate->showBookTitleInfo($book).PHP_EOL;
 
echo 'show stars template'.PHP_EOL;
echo $starsTemplate->showBookTitleInfo($book).PHP_EOL;
cs


실행결과


1
2
3
4
5
show exclaim template
PHP!!!for!!!Cats by Larry!!!Truett
 
show stars template
PHP*for*Cats
cs


이제 디자인 패턴중 전략패턴, 프로토타입패턴, 템플릿 메소드패턴  3개를 완벽히 마스터했습니다.

실제 프로그래밍할때 사용해봐야겠습니다.