最近在看 “深入PHP面向对象模式与实践” ,学习书中的内容后瞬间觉得自己有点高大上了,哈 ! 其实还是个菜B。相信也会有新手朋友在看这本(我自己也是新手),对书中我个人认为比较难的内容的学习心得就想拿出来分享和交流,1是希望对自己所学知识能够起到巩固和加深理解的作用 2是希望对看到本文且感兴趣的新手朋友一些帮助。
这部分内容看了好几遍了代码也跟着敲了几遍,估计本文想要实现的功能大概就是用户在web页面上输入一些内容,然后通过后台程序解析后进行回复(感觉就是在废话)。例如我在前台web页面输入框里输入:
$input = "4"; $input equals "4" or $input equals "four";
然后提交,系统就会回复类似 “条件成立” 或者 “条件不成立”的结果(有点类似直接在前台写代码并运行,后台解析后会返回一个结果。原书中虽然没有讲解整个前台输入到后台解析的过程但我猜这个后台解析应该还有一个使用正则表达式提取类似上面2行代码中关键字的过程)
上面这二行代码虽然是作者发明的语言,但根据字面含义也不难理解,第一行是定义一个变量并赋值,第二行是对变量进行一个判断(变量等于4或者等于four)。
废话不多说来看看这个模式定义的这几个类 (类图请自行看原文):
一、interpreterContext 这个类就像一个容器 主要是用来存放和获取需要进行比较的值和比较的结果的,例如上述代码中的4, four,和比较结果 “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()]; } }
这个类就像一个工具,供其他类来使用(它和其他类不存在继承、组合或聚合的关系)。
二、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的子类(这也是本书一直在强调的要面向接口编程,这个Expression就是个接口,利用这个接口可以实现多态,不知道自己装B说的对不对,哈! 具体可以在看看原书的类图)
三、LiteralExpression 文字表达式类,作用就是将一个字符串保存到InterpreterContext这个小容器里,保存成一个索引数组,例如保存开头那二句自创代码中的 4 或者 four
代码如下:
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); } }
四、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; } }