策略模式

策略模式

将一组特定的行为和算法封装成类

举例:

一个电商网站系统,针对男性女性用户要各自跳转到不同的商品类目,并且所有广告位展示不同的广告。

策略模式从侧面 也反应了 Ioc, 依赖倒置, 控制反转。

只要发现自己正不断地在继承树的各个分支中重复同一个算法,(无论是通过子类还是通过重复条件语句),请将这些算法抽象成独立的类型。

好的代码结构 是重构出来的,或者是改出来的,重要的分析类与类关系结构工具就是 画UML。

问题

    我们创建了Question类,并为其添加了mark()方法。现在假设用户回答问题,可以使用多种不同的标记方式,应该怎么办呢?

比如支持简单的MarkLogic语言,直接匹配,以及正则表达式这3种标记方式。

你可能首先想到的是使用子类来实现这些差异,如图11-3所示。

 

如果只考虑这一方面的变化,这样做还能适应我们的需求。但是想象一下,如果我们被要求支持不同类型的问题-基于文本的问题和支持多媒体的问题,如图,在一个继承树中创建多个子类的方案会产生一些问题。

 

实现:

<?php

abstract class Question{
    protected $prompt;
    protected $marker;

    function __construct($prompt, Marker $marker)
    {
        $this->marker= $marker;
        $this->prompt = $prompt;
    }

    function mark($response){
        return $this->marker->mark($response);
    }

}

class TextQuestion extends Question{
    //处理文本问题特有的操作
}

class AVQuestion extends Question{
    //处理语音问题特有的操作
}

abstract class Marker{
    protected $test;
    function __construct($test)
    {
        $this->test = $test;
    }

    abstract function mark($response);
}

class MarkLogicMarker extends Marker{
    private $engine;
    function __construct($test)
    {
        parent::__construct($test);
        //$this->engine = new MarkParse($test);
    }

    function mark($response){
        //return $this->engine->evaluate($response);
        return true;
    }
}

class MatchMarker extends Marker{
    function mark($response){
        return ($this->test == $response);
    }
}

class RegexpMarker extends Marker{
    function mark($response)
    {
        // TODO: Implement mark() method.
        return (preg_match($this->test, $response));
    }
}


//下面是客户端代码的示例:
$markers = array(
    new RegexpMarker("/f.ve/")  ,
    new MatchMarker("five"),
    new MarkLogicMarker('$input equals "five"')
);

foreach($markers as $marker){
    print get_class($marker)."\n";
    $question = new TextQuestion("how many beans make five", $marker);
    foreach(array("five","four") as $response){
        print "\tresponse: $response: ";
        if($question->mark($response)){
            print "well done\n";
        }else {
            print "never mind\n";
        }
    }
}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值