PHP设计模式之模板方法模式Template Method Pattern详解

  • Post category:PHP

PHP设计模式之模板方法模式TemplateMethodPattern详解

模板方法模式是一种行为型设计模式,它定义了一个算法的骨架,将一些步骤延迟到子类中实现。PHP中,模板方法模式通常用于实现一些通的算法,以及在不同的子类中实现特定的步。

模板方法模式的实现

模板方法模式通常由两个主要组成部分组成:抽象类和具体类抽象类定义了算法的骨架,包含一些通用步骤和抽象方法,具体类实现了抽象方法,以完成算法的特定步骤。

以下是模板方法模式的实现步骤:

  1. 定义抽象类

抽象类定义了算法的骨架,包含一些通用步骤和抽象方法。

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()

  1. 实现具体类

具体类实现了抽象方法,以完成算法的特定步骤。

class ConcreteClass extends AbstractClass {
  protected function step1() {
    // 实现步骤1
  }

  protected function step2() {
    // 实现步骤2
  }

  protected function step3() {
    // 实现步骤3
  }
}

在这个示例中,实现了一个ConcreteClass具体类,它继承了AbstractClass抽象类,并实现了step1()step2()step3()方法。

  1. 使用模板方法模式

使用模板方法模式时,需要创建一个具体类的实例,并调用它的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表格的步骤如下:

  1. 定义抽象类Table,它包含了一个render()方法和两个抽象方法renderHeader()renderBody()
  2. 实现具体类UsersTable,它继承了Table抽象类,并实现了renderHeader()renderBody()方法。
  3. 创建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报告的步骤如下:

  1. 定义抽象类Report,它包含了一个generate()方法和两个抽象方法getTitle()getContent()
  2. 实现具体类SalesReport,它继承了Report抽象类,并实现了getTitle()getContent()方法。
  3. 创建SalesReport具体类的实例,并调用它的generate()方法。

总结

模板方法模式是一种行为型设计模式,它定义了一个算法的骨架,将一些步骤延迟到子类中实现。在PHP中,模板方法模式通常于实现一些通用的算法,以及在不同的子类中实现特定的步骤。实现模板方法模式的关键是定义一个抽象类,它包含了一个模板方法和一些抽象方法,以及一个具体类,它继承了抽象类,并实现了抽象方法。在使用模板方法模式时,需要创建一个具体类的实例,并调用它的模板方法。