在此模式中,算法是从复杂类提取的,因而可以方便地替换。例如,如果要更改搜索引擎中排列页的方法,则策略模式是一个不错的选择。思考一下搜索引擎的几个部分——一部分遍历页面,一部分对每页排列,另一部分基于排列的结果排序。在复杂的示例中,这些部分都在同一个类中。通过使用策略模式,您可将排列部分放入另一个类中,以便更改页排列的方式,而不影响搜索引擎的其余代码。
作为一个较简单的示例,清单显示了一个用户列表类,它提供了一个根据一组即插即用的策略查找一组用户的方法。
& lt; php ?//策略接口 接口IStrategy { 函数滤波器(记录); }//定义一种策略继承接口 类FindAfterStrategy实现IStrategy { 私人_name美元; 公共函数__construct(名称) { $ this→_name=$名称; } 公共函数滤波器(记录) { 返回strcmp ($ this→_name,美元记录)& lt;=0; } }//定义另一种策略 类RandomStrategy实现IStrategy { 公共函数滤波器(记录) { 返回兰德(0,1)祝辞=0.5; } }//定义用户列表类 类UserList { 私人数组$ _list=(); 公共函数__construct(名称) { 如果($名字!=null) { foreach(名称名称)美元 { $ this→_list[]=$名称; } } } 公共函数添加(名称) { $ this→_list[]=$名称; }//根据某个策略来获取用户 公共函数找到(过滤器) { 数组$ recs=(); foreach ($ this→_list美元用户) { 如果($过滤器→过滤(用户)美元) 美元recs []=$ user; } 返回$推荐; } }//初始化用户列表 ul美元=新UserList(阵列(“安迪”,“杰克”、“罗莉”、“梅根”));//根据第一个策略获取用户 f1=美元ul→找到(新FindAfterStrategy (“J”)); 回声的& lt; pre>; print_r (f1); 回声的& lt;/pre>;//根据第二个策略获取用户 f2=美元ul→找到(新RandomStrategy ()); 回声的& lt; pre>; print_r (f2); 回声的& lt;/pre>;
<代码> UserList> 代码类是打包名称数组的一个包装器。它实现<代码>找到代码>方法,该方法利用几个策略之一来选择这些名称的子集。这些策略由<代码> IStrategy 代码>接口定义,该接口有两个实现:一个随机选择用户,另一个根据指定名称选择其后的所有名称。运行测试代码时,将得到以下输出:
测试代码为两个策略运行同一用户列表,并显示结果。在第一种情况中,策略查找排列在<代码> J> 代码后的任何名称,所以您将得到杰克,罗莉和梅根。第二个策略随机选取名称,每次会产生不同的结果。在这种情况下,结果为安迪和梅根。
策略模式非常适合复杂数据管理系统或数据处理系统,二者在数据筛选,搜索或处理的方式方面需要较高的灵活性。