PHP设计模式之模板方法模式TemplateMethodPattern详解
模板方法模式是一种行为型设计模式,它定义了一个算法的骨架,将一些步骤延迟到子类中实现。PHP中,模板方法模式通常用于实现一些通的算法,以及在不同的子类中实现特定的步。
模板方法模式的实现
模板方法模式通常由两个主要组成部分组成:抽象类和具体类抽象类定义了算法的骨架,包含一些通用步骤和抽象方法,具体类实现了抽象方法,以完成算法的特定步骤。
以下是模板方法模式的实现步骤:
- 定义抽象类
抽象类定义了算法的骨架,包含一些通用步骤和抽象方法。
abstract class AbstractClass {
public function templateMethod() {
$this->step1();
$this->step2();
$this->step3();
}
abstract protected function step1();
abstract protected function step2();
abstract protected function step3();
}
在这个示例中,我们定义了一个AbstractClass
抽象类,它包含了一个templateMethod()
方法,以及三个抽象方法step1()
、step2()
和step3()
。
- 实现具体类
具体类实现了抽象方法,以完成算法的特定步骤。
class ConcreteClass extends AbstractClass {
protected function step1() {
// 实现步骤1
}
protected function step2() {
// 实现步骤2
}
protected function step3() {
// 实现步骤3
}
}
在这个示例中,实现了一个ConcreteClass
具体类,它继承了AbstractClass
抽象类,并实现了step1()
、step2()
和step3()
方法。
- 使用模板方法模式
使用模板方法模式时,需要创建一个具体类的实例,并调用它的templateMethod()
方法。
以下是使用模板方法模式的示例:
// 创建具体类的实例
$object = new ConcreteClass();
// 调用模板方法
$object->templateMethod();
在这个示例中,我们创建了一个ConcreteClass
具体类的实例,并调用它的templateMethod()
方法。
示例1:使用模板方法模生成HTML表格
以下是使用模板方法模式生成HTML表格的示例:
abstract class Table {
protected $data;
public function __construct($data) {
$this->data = $data;
}
public function render() {
$html = '<table>';
$html .= $this->renderHeader();
$html .= $this->renderBody();
$html .= '</table>';
return $html;
}
abstract protected function renderHeader();
abstract protected function renderBody();
}
class UsersTable extends Table {
protected function renderHeader() {
$html = '<thead><tr>';
$html .= '<th>ID</th>';
$html .= '<th>Name</th>';
$html .= '<th>Email</th>';
$html .= '</tr></thead>';
return $html;
}
protected function renderBody() {
$html = '<tbody>';
foreach ($this->data as $row) {
$html .= '<tr>';
$html .= '<td>' . $row['id'] . '</td>';
$html .= '<td>' . $row['name'] . '</td>';
$html .= '<td>' . $row['email'] . '</td>';
$html .= '</tr>';
}
$html .= '</tbody>';
return $html;
}
}
// 使用模板方法模式生成HTML表格
$data = [
['id' => 1, 'name' => 'Alice', 'email' => 'alice@example.com'],
['id' => 2, 'name' => 'Bob', 'email' => 'bob@example.com'],
['id' => 3, 'name' => 'Charlie', 'email' => 'charlie@example.com'],
];
$table = new UsersTable($data);
$html = $table->render();
在这个示例中,我们使用模板方法模式生成HTML表格。我们定义了一个Table
抽象类,它包含了一个render()
方法和两个抽象方法renderHeader()
和renderBody()
。我们还实现了一个UsersTable
具体类,它继承了Table
抽象类,并实现了renderHeader()
和renderBody()
方法。
使用模板方法模式生成HTML表格的步骤如下:
- 定义抽象类
Table
,它包含了一个render()
方法和两个抽象方法renderHeader()
和renderBody()
。 - 实现具体类
UsersTable
,它继承了Table
抽象类,并实现了renderHeader()
和renderBody()
方法。 - 创建
UsersTable
具体类的实例,并调用它的render()
方法。
示例2:使用模板方法模式生成PDF报告
以下是使用模板方法模式生成PDF报告的示例:
abstract class Report {
protected $data;
public function __construct($data) {
$this->data = $data;
}
public function generate() {
$pdf = new PDF();
$pdf->AddPage();
$pdf->SetFont('Arial', 'B', 16);
$pdf->Cell(40, 10, $this->getTitle(), 0, 1);
$pdf->SetFont('Arial', '', 12);
$pdf->MultiCell(0, 10, $this->getContent(), 0, 1);
$pdf->Output();
}
abstract protected function getTitle();
abstract protected function getContent();
}
class SalesReport extends Report {
protected function getTitle() {
return 'Sales Report';
}
protected function getContent() {
$content = '';
foreach ($this->data as $row) {
$content .= $row['product'] . ': ' . $row['sales'] . "\n";
}
return $content;
}
}
// 使用模板方法模式生成PDF报告
$data = [
['product' => 'Product A', 'sales' => 100],
['product' => 'Product B', 'sales' => 200],
['product' => 'Product C', 'sales' => 300],
];
$report = new SalesReport($data);
$report->generate();
在这个示例中,我们使用模板方法模式生成PDF报告。我们定义了一个Report
抽象类,它包含了一个generate()
方法和两个抽象方法getTitle()
和getContent()
。我们还实现了一个SalesReport
具体类,它继承了Report
抽象类,并实现了getTitle()
和getContent()
方法。在generate()
方法中,我们使用PDF
类生成PDF报告。
使用模板方法模式生成PDF报告的步骤如下:
- 定义抽象类
Report
,它包含了一个generate()
方法和两个抽象方法getTitle()
和getContent()
。 - 实现具体类
SalesReport
,它继承了Report
抽象类,并实现了getTitle()
和getContent()
方法。 - 创建
SalesReport
具体类的实例,并调用它的generate()
方法。
总结
模板方法模式是一种行为型设计模式,它定义了一个算法的骨架,将一些步骤延迟到子类中实现。在PHP中,模板方法模式通常于实现一些通用的算法,以及在不同的子类中实现特定的步骤。实现模板方法模式的关键是定义一个抽象类,它包含了一个模板方法和一些抽象方法,以及一个具体类,它继承了抽象类,并实现了抽象方法。在使用模板方法模式时,需要创建一个具体类的实例,并调用它的模板方法。