策略模式
概念:
将一组特定的行为和算法封装成类,以适应某些特定的上下文环境。
目的:
实现依赖倒置、控制反转。
场景:
男女用户跳转到不同的页面,并且所有的广告位展示不同的广告, 如果某天新增了一种中性的性别,则需要在所有判断的地方进行修改,使用策略模式规避修改。
示例:
// 策略接口
interface UserStrategy {
public function showAD();
}
// 女
class FemaleUser implements UserStrategy {
public function showAD(){
echo "女";
}
}
// 男
class MaleUser implements UserStrategy {
public function showAD(){
echo "男";
}
}
class Page {
private $obj;
public function index(){
$this->obj->showAD();
}
public function setStrategy(UserStrategy $class){
$this->obj = $class;
}
}
// 只在一个地方判断,配置策略对象(Page),其他地方使用
if($type=='male' ){
$obj = new MaleUser();
} else {
$obj = new FemaleUser();
}
$p = new Page();
$p->setStrategy($obj);
$p->index();
策略模式和简单工厂模式区别:
我们先看一下下面简单工厂的示例:
<?php
interface base {
function showAD();
}
// 女
class FemaleUser implements base {
public function showAD(){
echo "女";
}
}
// 男
class MaleUser implements base {
public function showAD(){
echo "男";
}
}
// 输出结果
class UserFactory {
public function outputResult($type) {
$res = null;
switch ($type) {
case 'Female':
$res = new FemaleUser();
break;
case 'Male':
$res = new MaleUser();
break;
default:
return null;
}
return $res;
}
}
$userFactory = new UserFactory();
$factory1 = $userFactory->outputResult('Female');
echo $factory1->showAD(). '<br/>';
$factory1 = $userFactory->outputResult('Male');
echo $factory1->showAD(). '<br/>';
关注点不一样:一个关注对象创建;一个关注行为的封装。
简单工厂模式注重于返回对象,工厂模式是差异类继承抽象类,然后工厂直接调用对应的差异类
策略模式注重于返回行为结果,策略模式更加侧重于算法的替换,策略模式也是差异类继承抽象类,通过客户端实例化差异类,再通过工厂调用行为(方法)
解决不同的问题:
工厂模式
是创建型的设计模式,它接受指令,创建出符合要求的实例;它主要解决的是资源的统一分发,将对象的创建完全独立出来,让对象的创建和具体的使用客户无关。主要应用在多数据库选择,类库文件加载等。
策略模式
是为了解决的是策略的切换与扩展,更简洁的说是定义策略族,分别封装起来,让他们之间可以相互替换,策略模式让策略的变化独立于使用策略的客户。
个人理解:
工厂模式是对创建对象统一管理,方便调用对象;策略模式则是对对象进行封装,再通过工厂调用行为。
依赖倒转(反转控制)原则: 依赖注入和控制反转说的实际上是同一个东西,它们是一种设计模式,这种设计模式用来减少程序间的耦合
优点:
使用依赖注入,最重要的一点好处就是有效的分离了对象和它所需要的外部资源,使得它们松散耦合,有利于功能复用,更重要的是使得程序的整个体系结构变得非常灵活
依赖倒置是一种软件设计思想,在传统软件中,上层代码依赖于下层代码,当下层代码有所改动时,上层代码也要相应进行改动,因此维护成本较高。而依赖倒置原则的思想是,上层不应该依赖下层,应依赖接口。意为上层代码定义接口,下层代码实现该接口,从而使得下层依赖于上层接口,降低耦合度,提高系统弹性。