템플릿 메서드 패턴
Coddy PHP 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 91개 중 78번째.
Template Method Pattern은 기본 클래스에서 알고리즘의 뼈대를 정의하고, 전체 구조를 변경하지 않고도 서브클래스가 특정 단계를 재정의할 수 있도록 하는 행동 설계 패턴입니다. 기본 클래스는 작업 흐름을 제어하고, 서브클래스는 개별 요소를 사용자 지정합니다.
다양한 유형의 문서를 만드는 것을 고려해 보세요.
모든 문서는 동일한 프로세스를 따릅니다: create header, 콘텐츠 추가, create footer. 하지만 각 단계의 구체적인 내용은 문서 유형에 따라 달라집니다. 템플릿 method가 이 순서를 정의하고, 하위 클래스가 세부 사항을 implement합니다.
<?php
abstract class DocumentGenerator {
// 템플릿 메서드 - 알고리즘 구조를 정의합니다
public final function generate(): string {
$output = $this->createHeader();
$output .= $this->createContent();
$output .= $this->createFooter();
return $output;
}
// 서브클래스에서 구현해야 할 단계들
abstract protected function createHeader(): string;
abstract protected function createContent(): string;
abstract protected function createFooter(): string;
}
class HtmlDocument extends DocumentGenerator {
protected function createHeader(): string {
return "<html><head></head><body>";
}
protected function createContent(): string {
return "<p>Hello World</p>";
}
protected function createFooter(): string {
return "</body></html>";
}
}
class TextDocument extends DocumentGenerator {
protected function createHeader(): string {
return "=== DOCUMENT ===\n";
}
protected function createContent(): string {
return "Hello World\n";
}
protected function createFooter(): string {
return "=== END ===";
}
}
$html = new HtmlDocument();
echo $html->generate() . "\n";
$text = new TextDocument();
echo $text->generate();
출력:
<html><head></head><body><p>Hello World</p></body></html>
=== DOCUMENT ===
Hello World
=== END ===템플릿 메서드에 있는 final 키워드에 주목하세요. 이는 하위 클래스가 algorithm의 구조를 변경하지 못하도록 합니다. 이 패턴은 동일한 workflow를 따르지만 구현 세부 사항은 서로 다른 여러 클래스를 가지고 있을 때 이상적입니다. 새로운 문서 유형을 추가하려면 기존 코드를 건드리지 않고 새로운 하위 클래스를 생성하면 됩니다.
챌린지
쉬움Template Method Pattern을 사용하여 보고서 생성 시스템을 만들어 보겠습니다. 다양한 유형의 보고서는 제목 섹션, 데이터 섹션, 요약 섹션이라는 동일한 구조를 따르지만, 각 보고서 유형은 이러한 섹션을 서로 다르게 형식화합니다. 템플릿 메서드는 이 작업 흐름을 정의하고, 하위 클래스는 각 단계를 사용자 지정합니다.
코드를 네 개의 파일로 구성합니다:
ReportGenerator.php: 보고서 생성 algorithm의 뼈대를 defines하는 abstractReportGeneratorclass를 Create합니다. class는 다음을 수행해야 합니다:- constructor에서 보고서 제목을 accept합니다(constructor promotion 사용).
finalpublic methodgenerate(): string를 가지며,createTitle(),createBody(),createSummary()의 세 단계를 order대로 call하고 그 결과를 연결합니다.- 하위 클래스가 implement해야 하는 세 개의 abstract protected methods를 Declare합니다:
createTitle(): string,createBody(): string,createSummary(): string
HtmlReport.php: ReportGenerator 파일을 포함하고 이를 extends하는HtmlReportclass를 create합니다. 이 보고서는 output을 HTML로 형식화합니다:createTitle()은"<h1>[title]</h1>"을 반환합니다.createBody()는"<p>Report data goes here</p>"를 반환합니다.createSummary()는"<footer>End of report</footer>"를 반환합니다.
PlainTextReport.php: ReportGenerator 파일을 포함하고 이를 extends하는PlainTextReportclass를 create합니다. 이 보고서는 간단한 텍스트 형식을 사용합니다:createTitle()은"### [title] ###\n"을 반환합니다.createBody()는"Report data goes here\n"를 반환합니다.createSummary()는"--- End of report ---"를 반환합니다.
main.php: 두 보고서 파일을 모두 포함합니다. 두 개의 입력을 받습니다. 보고서 유형("html"또는"text")과 보고서 제목입니다.보고서 유형을 Based로 적절한 보고서 generator를 given 제목으로 Create합니다.
generate()를 Call하고 complete 보고서를 출력합니다.
Template Method Pattern은 모든 보고서가 동일한 세 단계 구조를 따르도록 하면서도 각 보고서 유형이 해당 섹션을 고유하게 형식화할 수 있도록 합니다. final keyword를 generate()에 사용하면 하위 클래스가 algorithm의 순서를 변경하는 것을 방지합니다. 하위 클래스는 개별 단계만 사용자 지정할 수 있습니다.
직접 해보기
<?php
require_once 'HtmlReport.php';
require_once 'PlainTextReport.php';
// 입력 읽기
$reportType = trim(fgets(STDIN));
$reportTitle = trim(fgets(STDIN));
// TODO: 보고서 유형("html" 또는 "text")에 따라,
// 주어진 제목으로 적절한 보고서 생성기를 만드세요
// TODO: generate()를 호출하고 완전한 보고서를 출력하세요
?>이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
직접 연습해 보세요: 온라인 PHP 컴파일러