ホームページ  >  記事  >  バックエンド開発  >  PHPオブジェクト指向インタプリタモードの詳細説明

PHPオブジェクト指向インタプリタモードの詳細説明

墨辰丷
墨辰丷オリジナル
2018-05-22 15:13:321345ブラウズ

以下のエディターは、PHP のオブジェクト指向インタープリター モードに関する決まり文句を提供します。編集者はこれがとても良いと思ったので、参考として共有します。編集者をフォローして見てみましょう

最近、『詳細な PHP オブジェクト指向パターンと実践』を読んでいて、この本の内容を勉強した後、すぐに少し上級者になったと感じました。 実際、それはまだ悪い考えです。この本を読んでいる初心者の友人もいると思います(私も初心者です)。個人的に難しいと思う本の内容について、私の学習経験を共有し、交換することで知識を定着させることができれば幸いです。理解を深める役割と学びました 2. この記事を読んで興味を持った初心者の友達に役立つことを願っています。

コンテンツのこの部分を何度も読み、コードを何度も入力しましたが、この記事で実現したい機能は、ユーザーが Web ページにコンテンツを入力し、それをバックグラウンド プログラムを通じて解析することであると推測しています。そして返信します(ナンセンスのように感じます)。たとえば、フロントエンド Web ページの入力ボックスに

$input = "4";
$input equals "4" or $input equals "four";

と入力して送信すると、システムは「条件が確立されました」または「条件が確立されていません」のような結果を返します。 (フロントエンドで直接コードを書いて実行し、バックグラウンドで解析すると結果が返されるのと似ています。元の本ではフロントエンドの入力からバックエンドの解析までのプロセス全体を説明していませんが、このバックエンド解析には、上記の 2 行のコードと同様に、正規表現を使用してキーワードを抽出するプロセスも含まれているはずです)

上記の 2 行のコードは作者が発明した言語ですが、それを行うのは難しくありません。 1 行目は変数を定義して値を代入し、2 行目は変数 (変数が 4 に等しいか 4 に等しいか) を判断します。

早速、このパターンで定義されたクラスを見てみましょう (クラス図の原文は自分で読んでください):

1.interpreterContext このクラスはコンテナのようなものです主に次の目的で使用されます。必要な処理を保存、取得する 上記コードの4、4、比較結果「true」「false」などの比較値と比較結果を配列またはクラス属性の形式で保存 $expressionstoreコードは次のとおりです:

class InterpreterContext{
  private $expressionstore = array(); //存放比较的值和结果
  
  function replace(Expression $exp,$value){    // 设置值
    $this->expressionstore[$exp->getKey()] = $value;
  }
  
  function lookup(Expression $exp){        //获取值
    return $this->expressionstore[$exp->getKey()];
  }
}

このクラスは、他のクラスが使用するツールのようなものです (他のクラスとの継承、合成、または集約関係はありません)。

2. Expression これは式の抽象クラスであり、抽象メソッドinterprete()とメソッドgetKey()を定義します

コードは次のとおりです:

abstract class Expression {
  private static $keycount = 0;  //计数用的
  private $key;          //存放一个唯一值


  //主要实现将前台获取到的数据存放到上述InterpreterContext类中的功能,看到下面的内容就会发现继承他的类调用了InterpreterContext类的replace()方法
  abstract function interpret (InterpreterContext $context); 

 //获取一个唯一值  
  function getKey(){       
    if(!isset($this->key)){
      self::$keycount++;
      $this->key= self::$keycount;
    }
    return $this->key;
  }
}

以下で説明するクラスは、このクラスを継承し、OperatorExpression (演算子式抽象クラス) と結合した関係を持ちます。つまり、OperatorExpression には、初期化中に Expression を継承するすべてのサブクラスを含めることができます (これは、本書がインターフェイス指向について強調していることでもあります)プログラミングでは、この Expression は、ポリモーフィズムを実現するために使用できます。詳細については、元の本のクラス図を参照してください。

3. LiteralExpression リテラル式クラス、この機能は文字列を InterpreterContext の小さなコンテナーに保存し、それをインデックス配列として保存します。たとえば、自己作成コードの最初の 2 文で 4 つまたは 4 つを保存します

コードは次のとおりです:

class LiteralExpression extends Expression{
  private $value;  
  function __construct ($value){      //初始化时传入要保存的值
    $this->value= $value;
  }
  function interpret(InterpreterContext $context){    //调用InterpreterContext类的replace()将$value保存到InterpreterContext这个小容器里
    $context->replace($this,$this->value);
  }
}

4. VariableExpression 変数式クラスは、データが連想配列として保存されることを除いて、上記のクラスと同じ機能を持ちます。 array は変数名、value は変数の値です (最初の 2 つの文の変数「input」と値「4」など)。

コードは次のとおりです:

class VariableExpression extends Expression{
  private $name;    //变量名
  private $val;      //变量值
  
  function __construct ($name,$val=null){
    $this->name = $name;
    $this->val = $val;
  }
  
  function interpret(InterpreterContext $context){
    if(!is_null($this->val)){
      $context->replace($this,$this->val);
      $this->val = null;
    }
  }
  
  function setValue($value){  //用于设置变量的值
    $this->val = $value;
  }
  
  function getKey(){    //这个复写了父类的getKey()方法,在小容器InterpreterContext的lookup()方法调用这个类的实例的getKey()方法时 它将返回一个字符串(即变量名)而不是数字索引
    return $this->name;
  }
}

5. OperatorExpression 演算子式抽象基本クラス、このクラスは Expression 抽象基本クラスを継承して結合し、インタプリタを実装します () メソッドは主に式の計算結果を保存します

コードは次のとおりです:

abstract class OperatorExpression extends Expression{
protected $l_op;  //表达式左边的值
protected $r_op;  //表达式右边的值

function __construct (Expression $l_op,Expression $r_op){    //初始化时可组合继承了Expression类的子类实例
$this->l_op = $l_op;
$this->r_op = $r_op;
}

function interpret(InterpreterContext $context){  //主要用于保存表达试的结果(保存到InterpreterContext 类的实例中)
$this->l_op->interpret($context);        //将Expression子类实例的值或计算结果保存到InterpreterContext 类的实例中
$this->r_op->interpret($context);
$result_l = $context->lookup($this->l_op);    //获取上一步的值或计算结果
$result_r = $context->lookup($this->r_op);
$this->doInterpret($context,$result_l,$result_r);  //具体的比较运算由继承的子类来实现
}

protected abstract function doInterpret(InterpreterContext $context,$result_l,$result_r);

}

6. EqualsExpression、BooleanOrExpression、BooleanAndExpression はそれぞれ、等しい式、または OperatorExpression 抽象基本クラスを継承する式です。式のメソッドは doInterpret() の 1 つだけであり、内部で replace() メソッドを呼び出します。 InterpreterContext クラスの計算結果を InterpreterContext クラスのインスタンスに保存するコードは次のとおりです。

//相等表达式
class EqualsExpression extends OperatorExpression {
protected function doInterpret(InterpreterContext $context,$result_l,$result_r){
$context->replace($this,$result_l == $result_r);
}
}

//或表达式
class BooleanOrExpression extends OperatorExpression{
protected function doInterpret(InterpreterContext $context,$result_l,$result_r){
$context->replace($this,$result_l || $result_r);
}
}


//与表达式
class BooleanAndExpression extends OperatorExpression{
protected function doInterpret(InterpreterContext $context,$result_l,$result_r){
$context->replace($this,$result_l && $result_r);
}
}

以上で、このモードに関連するクラスが導入されました。直接コピーして貼り付けて実行し、結果を確認してみましょう:

クライアント コード 1:

$context = new InterpreterContext();

$statement = new BooleanOrExpression (  //可尝试将此操作符表达式换成BooleanAndExpression 运行一下 看看执行结果

//可尝试将LiteralExpression中实例化的参数改成其他值看看运算结果,或者直接将EqualsExpression对象换成BooleanOrExpression 或BooleanAndExpression 
new EqualsExpression(new LiteralExpression('four'),new LiteralExpression('four')), 

new EqualsExpression(new LiteralExpression('b'),new LiteralExpression('4'))
);

$statement->interpret($context);
if($context->lookup($statement)){
echo '条件成立';
} else {
echo '条件不成立';
}

:

$context = new InterpreterContext();

$statement = new BooleanOrExpression(
new BooleanAndExpression(
new EqualsExpression(new LiteralExpression('4'),new LiteralExpression('4')),
new EqualsExpression(new LiteralExpression('4'),new LiteralExpression('4'))
),
new EqualsExpression(new LiteralExpression('b'),new LiteralExpression('4'))
);

$statement->interpret($context);
if($context->lookup($statement)){
echo '条件成立';
} else {
echo '条件不成立';
}

クライアント コード 3:

これは元のクライアント コードの例と上記のクライアント コードの違いは、VariableExpression が使用されていることです

$context = new InterpreterContext();    
$input = new VariableExpression('input');  //这里定义了一个变量input 但并未赋值

$statement = new BooleanOrExpression(
new EqualsExpression($input,new LiteralExpression('four')),  //这里变量表达式和文字表达式的值将进行一个是否相等的比较
new EqualsExpression($input,new LiteralExpression('4'))
);

foreach (array("four","4","52") as $val){
$input->setValue($val);        //对input这个变量赋值
print "变量input的值为:$val:<br/>";
$statement->interpret($context);  //进行比较并将比较结果存入InterpreterContext对象实例
if($context->lookup($statement)){  //获取比较的结果
print "条件成立 <br/>";
} else {
print "条件不成立 <br/>";
}
}

上記のコードはテスト後に正常に実行できます。必要な場合は、それをコピーして実行して結果を確認してください。

関連する推奨事項:

PHPインタープリターパターン詳しい使用方法の説明

phpデザインパターンインタープリターパターン徹底した分析と詳細な説明

PHPの高度なオブジェクト指向デザインパターンInterpreターパターン使用例

以上がPHPオブジェクト指向インタプリタモードの詳細説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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