ホームページ  >  記事  >  バックエンド開発  >  デザインパターン入門 - テンプレートメソッドパターン(php版)

デザインパターン入門 - テンプレートメソッドパターン(php版)

WBOY
WBOYオリジナル
2016-08-08 09:27:09915ブラウズ

ジョークには次のようなものがあります: 象を冷蔵庫に入れるのに何歩かかりますか?

1. 冷蔵庫を開けます

2. 象を中に詰めます

同様に、ライオンを冷蔵庫に入れるには何ステップかかりますか?

1. 冷蔵庫を開けます

2. ライオンを中に詰めます

3. 冷蔵庫を閉めます

上記の例では、2 つの方法は実際には同じステップを持っていますが、具体的な実装が少し異なることがわかりましたか?つまり、これら 2 種類の動作はステップ テンプレートを共有できます。これは、今回説明するデザイン パターン、つまりテンプレート デザイン パターンにつながります。

テンプレート設計パターンの原理は、以下に示すような UML クラス図で表すことができます:

具体的なコード例:

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 &#39;LockAnimal.php&#39;;
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 />";
   }
}

さて問題は、どの会社が最高の掘削機技術を持っているのかということです。冗談です。一部の動物はより凶暴で、素直に冷蔵庫に押し込められません。この状況に対処するには、プログラムにフックを追加する必要があります。変更されたコードは次のとおりです:

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

LockElephant.php
<?php
/**
 * 将狮子锁进冰箱里
 * @author ben
 *
 */
require_once &#39;LockAnimal.php&#39;;
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 &#39;LockElephant.php&#39;;
require_once &#39;LockLion.php&#39;;

$elephant = new LockElephant();
$lion = new LockLion();

$elephant->lock();
$lion->lock();

テンプレート メソッド設計パターンの正式な定義は、次のとおりです。一部のステップをサブクラスに延期しながら、メソッド内でアルゴリズムのスケルトンを定義します。テンプレート メソッドを使用すると、アルゴリズムの構造を変更せずに、サブクラスがアルゴリズムの特定のステップを再定義できます。

以上、デザインパターン入門 - テンプレートメソッドパターン(php編)を関連内容も含めて紹介しましたので、PHPチュートリアルに興味のある方の参考になれば幸いです。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。