【深入PHP 面向对象】读书笔记(十二)
来源:互联网 发布:阿里云国际站 编辑:程序博客网 时间:2024/06/05 22:06
11.2 策略模式
11.2.1 问题
我们继续之前的例子,之前的例子实现了自动判断答案正确性的功能,现在需要一个「添加问题」的功能,因此我们创建一个 Question 类,并为其添加 mark() 方法。
现在假设用户回答问题时可以使用多种不同的标记方式,比如支持MarkLogic语音、直接匹配以及正则表达式这 3 种标记方式。我们该如何实现呢?
最简单的处理方式就是通过继承来让子类实现这些差异。
如果只考虑这一方面的变化,这样做能适应我们的需求。但是,如果我们被要求支持不同类型的问题(基于文本的问题和基于多媒体的问题),则我们的继承树就会从两层变成三层:
这样做不仅导致了需要在体系汇总创建大量的类,而且还会导致代码的重复。
11.2.2 实现
当类必须支持同一个接口的多种实现时,最好的方法是提取出这些实现,并将它们放在自己的类型中,而不是通过继承原有的类去支持这些实现。
因此,我们将标记方式 Marker类 抽取出来:
下面是 Question 类及其子类的代码:
/* 抽象Question类 */abstract class Question { protected $prompt; protected $marker; function __construct($prompt, Marker $marker) { $this->prompt = $prompt; $this->marker = $marker; } function mark($response) { return $this->marker->mark($response); }}/* TextQuestion文本问题类 */class TextQuestion extends Question { // 处理文本问题特有的操作}/* AVQuestion多媒体类 */class AVQuestion extends Question { // 处理语音问题特有的操作}
Question抽象类定义基本的功能,保存了一个$prompt属性和一个Marker对象。具体的处理能力交给子类(TextQuestion文本问题类、AVQuestion多媒体类)实现。
当 Question::mark() 使用终端用户的响应作为参数时,mark() 方法之委托 Marker对象来解决问题。
接下来我们再来定义 Marker 对象,这里我们关注结构设计,简单处理实现细节:
abstract class Marker { protected $test; function __construct($test) { $this->test = $test; } abstract function mark($response);}class MarkLogicMarker extends Marker { function mark($response) { return true; }}class MatchMarker extends Marker { function mark($response) { return $this->test == $response; }}class RegexpMarker extends Marker { function mark($response) { return preg_match($this->test, $response); }}
至此,我们可以在客户端做一个演示代码:
/* 三种情况下的正确答案规则 */$markers = array( new RegexpMarker('/five/'), new MatchMarker('five'), new MarkLogicMarker('$input equals "five"'));foreach ($markers as $marker) { /* 对于每一种答案规则下,进行问题设置 */ $question = new TextQuestion("Guess a number", $marker); /* 模拟两个答案'four','five'来验证 */ foreach (array('four','five') as $response) { if ($question->mark($response)) { echo "true"; } else { echo "false"; } }}
输入'four'
的答案,得到 false;输入'five'
的答案,会得到 true。(MarkLogicMarker 这个类的逻辑处理需要结合上一章节的内容,这里直接输出 true)。
- 【深入PHP 面向对象】读书笔记(十二)
- 【深入PHP 面向对象】读书笔记(二十二)
- 【深入PHP 面向对象】读书笔记(一)
- 【深入PHP 面向对象】读书笔记(二)
- 【深入PHP 面向对象】读书笔记(三)
- 【深入PHP 面向对象】读书笔记(四)
- 【深入PHP 面向对象】读书笔记(五)
- 【深入PHP 面向对象】读书笔记(六)
- 【深入PHP 面向对象】读书笔记(七)
- 【深入PHP 面向对象】读书笔记(八)
- 【深入PHP 面向对象】读书笔记(九)
- 【深入PHP 面向对象】读书笔记(十)
- 【深入PHP 面向对象】读书笔记(十一)
- 【深入PHP 面向对象】读书笔记(十三)
- 【深入PHP 面向对象】读书笔记(十四)
- 【深入PHP 面向对象】读书笔记(十五)
- 【深入PHP 面向对象】读书笔记(十六)
- 【深入PHP 面向对象】读书笔记(十七)
- 模式和原则
- 记录
- Java——同步函数
- SSM框架——(Spring+SpringMVC+MyBatis)
- 105. Construct Binary Tree from Preorder and Inorder Traversal
- 【深入PHP 面向对象】读书笔记(十二)
- QListWidget和QTableWidget的使用和属性,QTableWidget和QListWidget样式表的设置,滚动条的样式设置
- kk《必然》后感之'使用'
- AngularJs实现简易的计算器
- first day
- Codeforces Round #438 A. Bark to Unlock
- 数据库 SQL实战练习
- OpenCV 2.4.9 配置使用
- python爬虫