Home > Article > Backend Development > Introduction to Design Patterns - Template Method Pattern (php version)
A joke says: How many steps does it take to put an elephant into the refrigerator?
1. Open the refrigerator
2. Stuff the elephant in
3. Close the refrigerator
Similarly, how many steps are needed to put the lion into the refrigerator?
1. Open the refrigerator
2. Stuff the lion in
3. Close the refrigerator
In the above example, did you find that the two methods actually have the same steps, but the specific implementation is slightly different? In other words, these two types of behaviors can share a step template. This can lead to the design pattern to be discussed this time - the template design pattern.
The principle of template design pattern can be represented by the UML class diagram as shown below:
Specific code example:
LockAnimal.php
<?php /** * 将动物锁进冰箱里抽象类 * @author ben * */ abstract class LockAnimal{ /** * 模板方法,使用final关键词防止子类覆盖 */ public final function lock(){ $this->open(); $this->push(); $this->close(); } /** * 打开冰箱 */ abstract function open(); /** * 将动物推进冰箱 */ abstract function push(); /** * 关上冰箱 */ abstract function close(); }LockElephant.php
<?php /** * 将狮子锁进冰箱里 * @author ben * */ require_once 'LockAnimal.php'; class LockElephant extends LockAnimal{ /** * (non-PHPdoc) * @see LockAnimal::open() */ public function open(){ echo "in order to lock an elephant into a fridge, you need to open the fridge first<br />"; } /** * (non-PHPdoc) * @see LockAnimal::push() */ public function push(){ echo "i'm pushing the elephant<br />"; } /** * (non-PHPdoc) * @see LockAnimal::close() */ public function close(){ echo "finally, now i can close the fridge<br />"; } }LockLion.php
<?php /** * 将狮子锁进冰箱里 * @author ben * */ require_once 'LockAnimal.php'; class LockLion extends LockAnimal{ /** * (non-PHPdoc) * @see LockAnimal::open() */ public function open(){ echo "in order to lock an lion into a fridge, you need to open the fridge first<br />"; } /** * (non-PHPdoc) * @see LockAnimal::push() */ public function push(){ echo "i'm pushing the lion<br />"; } /** * (non-PHPdoc) * @see LockAnimal::close() */ public function close(){ echo "finally, now i can close the fridge<br />"; } }
Now the question comes, which company has the best excavator technology? Just kidding. Some animals are more ferocious and will not be pushed into the refrigerator obediently. They need to be anesthetized. We need to add a hook to our program to handle this situation. The modified code is as follows:
LockAnimal.php
<?php /** * 将动物锁进冰箱里抽象类 * @author ben * */ abstract class LockAnimal{ /** * 模板方法,使用final关键词防止子类覆盖 */ public final function lock(){ $this->open(); if($this->needAnesthetic()){ $this->anesthetic(); } $this->push(); $this->close(); } /** * 打开冰箱 */ abstract function open(); /** * 是否需要麻醉 */ protected function needAnesthetic(){ return false; } protected function anesthetic(){ echo "anestheticing the animal"; } /** * 将动物推进冰箱 */ abstract function push(); /** * 关上冰箱 */ abstract function close(); }
<?php /** * 将狮子锁进冰箱里 * @author ben * */ require_once 'LockAnimal.php'; class LockElephant extends LockAnimal{ /** * (non-PHPdoc) * @see LockAnimal::open() */ public function open(){ echo "in order to lock an elephant into a fridge, you need to open the fridge first<br />"; } /** * (non-PHPdoc) * @see LockAnimal::push() */ public function push(){ echo "i'm pushing the elephant<br />"; } /** * (non-PHPdoc) * @see LockAnimal::close() */ public function close(){ echo "finally, now i can close the fridge<br />"; } }LockLion.php
<?php /** * 将狮子锁进冰箱里 * @author ben * */ require_once 'LockAnimal.php'; class LockLion extends LockAnimal{ /** * (non-PHPdoc) * @see LockAnimal::open() */ public function open(){ echo "in order to lock an lion into a fridge, you need to open the fridge first<br />"; } protected function needAnesthetic(){ return true; } protected function anesthetic(){ echo "anestheticing the lion<br />"; } /** * (non-PHPdoc) * @see LockAnimal::push() */ public function push(){ echo "i'm pushing the lion<br />"; } /** * (non-PHPdoc) * @see LockAnimal::close() */ public function close(){ echo "finally, now i can close the fridge<br />"; } }index.php
<?php require_once 'LockElephant.php'; require_once 'LockLion.php'; $elephant = new LockElephant(); $lion = new LockLion(); $elephant->lock(); $lion->lock();
The above introduces the introduction to design patterns - template method pattern (php version), including aspects of the content. I hope it will be helpful to friends who are interested in PHP tutorials.