php策略模式怎样理解?有哪些应用场景?
Admin 2021-05-25 群英技术资讯 2048 次浏览
关于设计模式,我们可以理解为是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。PHP设计模式有单例模式、注册模式、策略模式等等,文本主要给大家介绍的策略模式。
这个策略模式,意思就是定义一系列算法,把它们一个个封装起来,并且使它们可相互替换,使用得算法的变化可独立于使用它的客户,简单来讲就是,策略模式设计帮助构建的对象不必自身包含逻辑,而是能够根据需要利用其他对象中的算法。
来看下应用场景:
1、 多个类只区别在表现行为不同,可以使用Strategy模式,在运行时动态选择具体要执行的行为。
2、 需要在不同情况下使用不同的策略(算法),或者策略还可能在未来用其它方式来实现。
3、 对客户隐藏具体策略(算法)的实现细节,彼此完全独立。
4、客户端必须知道所有的策略类,并自行决定使用哪一个策略类,策略模式只适用于客户端知道所有的算法或行为的情况。
5、 策略模式造成很多的策略类,每个具体策略类都会产生一个新类。
有点模糊是吧,咱就来看一个完整的应用场景:
例如有一个CD类,我们类存储了CD的信息。
原先的时候,我们在CD类中直接调用getCD方法给出XML的结果,随着业务扩展,需求方提出需要JSON数据格式输出。这个时候我们引进了策略模式,可以让使用方根据需求自由选择是输出XML还是JSON。
大概了解了之后,咱们来看一个代码实例,我在网上找的啊,比较简单,大家可以根据自己需要的来扩展一下,如下:
<?php
//策略模式
//cd类
class cd {
protected $cdArr;
public function __construct($title, $info) {
$this->cdArr['title'] = $title;
$this->cdArr['info'] = $info;
}
public function getCd($typeObj) {
return $typeObj->get($this->cdArr);
}
}
class json {
public function get($return_data) {
return json_encode($return_data);
}
}
class xml {
public function get($return_data) {
$xml = '<?xml version="1.0" encoding="utf-8"?>';
$xml .= '<return>';
$xml .= '<data>' .serialize($return_data). '</data>';
$xml .= '</return>';
return $xml;
}
}
$cd = new cd('cd_1', 'cd_1');
echo $cd->getCd(new json);
echo $cd->getCd(new xml);
咱们接下来,再来了解一下一个网上比较经典的案例,来看张图片:

上面图片的意思可以按着下面这个方式来理解:
1.Joe做了一套相当成功的模拟鸭子的游戏。设计了一个超类Duck,然后让各种鸭子继承这个类。
2.后来客户提出要让鸭子有飞的能力。所以Joe就在超类中加了个fly()方法,这样下面的子类都有飞行的行为。
问题来了:1>原来Duck的子类中竟然有橡皮鸭,橡皮鸭是不会飞的。――Joe用重载的方式,把橡皮鸭的fly()方法设置为空.
2>覆盖fly(),我们看到了橡皮鸭的fly()里,没有任何代码,如果以后我们再添加别的不会飞的鸭子,那我么还要这么处理吗?――那么代码重复了!
3.上面2的方式我们知道是有问题的,所以Joe想到把Duck做成接口,这样每个子类必须实现Duck里的方法。这样就保证每个鸭子都能根据自己的需要添加行为。
问题来了:产品经常处于更新中,规格也在不断的变化。导致每当有新鸭子的时候,Joe就要被迫检查一遍子类是否覆盖了fly()方法。――当你修改某个行为的时候,你必须得往下追踪并在每一个定义此行为的类中修改它。
4.综合以上问题,Joe想到了把那些变化的部分从不变化的位置中抽出来。比如,我们对fly()行为,做了单独的接口FlyBehavior。如果鸭子想要飞行功能的时候,我们就让鸭子实现FlyBehavior.
5.深造:我们想让鸭子有不同的飞行功能,让它在运行时候做不同的飞行动作。让鸭子类实现接口,只能让鸭子有一种行为。
好,接下来看下代码实例:
<?php
interface FlyBehavior{
public function fly();
}
class FlyWithWings implements FlyBehavior{
public function fly(){
echo "Fly With Wings \n";
}
}
class FlyWithNo implements FlyBehavior{
public function fly(){
echo "Fly With No Wings \n";
}
}
class Duck{
private $_flyBehavior;
public function performFly(){
$this->_flyBehavior->fly();
}
public function setFlyBehavior(FlyBehavior $behavior){
$this->_flyBehavior = $behavior;
}
}
class RubberDuck extends Duck{
}
// Test Case
$duck = new RubberDuck();
/* 想让鸭子用翅膀飞行 */
$duck->setFlyBehavior(new FlyWithWings());
$duck->performFly();
/* 想让鸭子不用翅膀飞行 */
$duck->setFlyBehavior(new FlyWithNo());
$duck->performFly();
运行结果:
Fly With Wings
Fly With No Wings
咱们可以来总结下在开发过程中,这些设计模式的设计原则,如下:
1.找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起;
2.针对接口编程,不针对实现编程;
3.多用组合,少用继承;
以上就是关于php设计模式中策略模式的简单介绍,上述示例对大家理解php策略模式与一定的参考价值,需要的朋友可以看看,希望文本对大家学习有帮助,想要了解更多php设计模式的内容,可以继续关注其他文章。
文本转载自脚本之家
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
我们经常使用php-fpm,但是不一定所有人都知道fpm有三种模式,今天小年就带大家了解一下fpm的三种模式,有需要的可以参考参考。
1. 注意(Notices)这些都是比较小而且不严重的错误,比如去访问一个未被定义的变量。通常,这类的错误是不提示给用户的,但有时这些错误会影响到运行的结果。2. ...
在之前的 PHP 版本中, 必须使用静态值来定义常量,声明属性以及指定函数参数默认值。 现在你可以使用包括数值、字符串字面量以及其他常量在内的数值表达式来 定义常量、声明属性以及设置函数参数默认值。
文本主要介绍的是关于laravel 服务容器绑定的方法,包括简单的绑定,上下文绑定和扩展绑定等等,下文有具体介绍和示例,感兴趣的朋友可以参考学习。
在laravel中,fill方法是一个给Eloquent实例赋值属性的方法,该方法可以理解为用于过滤前端传输过来的与模型中对应的多余字段;当调用该方法时,会先去检测当前Model的状态,根据fillable数组的设置,Model会处于不同的状态。
成为群英会员,开启智能安全云计算之旅
立即注册关注或联系群英网络
7x24小时售前:400-678-4567
7x24小时售后:0668-2555666
24小时QQ客服
群英微信公众号
CNNIC域名投诉举报处理平台
服务电话:010-58813000
服务邮箱:service@cnnic.cn
投诉与建议:0668-2555555
Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 ICP核准(ICP备案)粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008