>  기사  >  백엔드 개발  >  PHP 객체지향 인터프리터 모드에 대한 자세한 설명

PHP 객체지향 인터프리터 모드에 대한 자세한 설명

墨辰丷
墨辰丷원래의
2018-05-22 15:13:321345검색

아래 편집기는 PHP의 객체 지향 인터프리터 모드에 대한 진부한 표현을 제공합니다. 에디터가 꽤 좋다고 생각해서 지금 공유해서 참고용으로 올려보겠습니다. 에디터를 따라가서 살펴볼까요

최근에 "심층 PHP 객체지향 패턴 및 실습"을 읽었습니다. 책의 내용을 공부하고 나니 제가 조금 발전했다는 느낌이 들었습니다. 하하! 사실, 그것은 여전히 ​​​​나쁜 생각입니다. 이 책을 읽는 초보 친구들도 있을 거라 믿습니다. (저도 초보입니다.) 개인적으로 어렵다고 생각하는 책의 내용에 대한 학습 경험을 공유하고 교환하고 싶습니다. 2. 이 글을 읽고 관심을 갖고 있는 초보 친구들에게 도움이 되었으면 좋겠습니다.

이 부분의 내용을 여러 번 읽고 코드를 여러 번 입력해 본 결과, 이 글에서 구현하고 싶은 기능은 사용자가 웹 페이지에 일부 내용을 입력한 후 백그라운드 프로그램을 통해 구문 분석하는 것이라고 추정합니다. 그리고는 (말도 안 되는 소리처럼 느껴집니다) 대답합니다. 예를 들어 프런트 엔드 웹 페이지의 입력 상자에

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

을 입력하고 제출하면 시스템에서 "조건이 설정되었습니다." 또는 "조건이 설정되지 않았습니다."와 유사한 결과로 응답합니다. (프론트엔드에서 직접 코드를 작성해서 실행하고, 백그라운드에서 파싱을 하면 결과가 나오는 것과 다소 비슷합니다. 원서에는 프론트엔드 입력부터 백엔드 파싱까지의 전 과정이 설명되어 있지는 않지만, 이 백엔드 파싱에는 위의 두 줄의 코드와 유사한 키워드를 추출하기 위해 정규식을 사용하는 프로세스도 포함되어야 할 것 같습니다.)

위의 두 줄의 코드는 저자가 발명한 언어이지만 어렵지 않습니다. 첫 번째 줄은 변수를 정의하고 값을 할당하는 것이고, 두 번째 줄은 변수에 대한 판단(변수는 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 이것은 표현의 추상 클래스로, Interpret() 추상 메소드와 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을 상속하는 모든 하위 클래스를 포함할 수 있음을 의미합니다. 프로그래밍에서 이 표현식은 인터페이스를 사용하여 다형성을 달성할 수 있습니다. B인 척하는 것이 맞는지 모르겠습니다. 자세한 내용은 원본 책의 클래스 다이어그램을 참조하세요.

3. LiteralExpression Literal Expression Class , 이 함수는 문자열을 InterpreterContext의 작은 컨테이너에 저장하고 이를 인덱스 배열로 저장하는 것입니다. 예를 들어 자체 생성 코드의 처음 두 문장에 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 변수 표현식 클래스는 데이터가 연관 배열로 저장된다는 점을 제외하면 위 클래스와 동일한 기능을 갖습니다. 배열은 변수 이름이고 값은 변수의 값입니다. 예를 들어 처음 두 문장의 변수는 "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() 메소드가 하나만 있습니다. 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 '条件不成立';
}

클라이언트 코드 2

:

$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 고급 객체 지향 디자인 패턴 Inter 프리터 패턴사용예

위 내용은 PHP 객체지향 인터프리터 모드에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.