PHP的设计模式(二)之策略模式、观察者模式

分享于:2019-10-06 18:16:32

策略模式


策略模式,将一组特定的行为和算法封装成类,以适应某些特定的上下文环境。 
eg:假如有一个电商网站系统,针对男性女性用户要各自跳转到不同的商品类目,并且所有的广告位展示不同的广告。在传统的代码中,都是在系统中加入各种if else的判断,硬编码的方式。如果有一天增加了一种用户,就需要改写代码。使用策略模式,如果新增加一种用户类型,只需要增加一种策略就可以。其他所有的地方只需要使用不同的策略就可以。 
首先声明策略的接口文件,约定了策略的包含的行为。然后,定义各个具体的策略实现类。

UserStrategy.php
<?php
/*
 * 声明策略文件的接口,约定策略包含的行为。
 */
interface UserStrategy
{
    function showAd();
    function showCategory();
}
FemaleUser.php
<?php
require_once 'Loader.php';
class FemaleUser implements UserStrategy
{
    function showAd(){
        echo "2016冬季女装";
    }
    function showCategory(){
        echo "女装";
    }
}
MaleUser.php
<?php
require_once 'Loader.php';
class MaleUser implements UserStrategy
{
    function showAd(){
        echo "IPhone6s";
    }
    function showCategory(){
        echo "电子产品";
    }
}
Page.php//执行文件
<?php
require_once 'Loader.php';
class Page
{
    protected $strategy;
    function index(){
        echo "AD";
        $this->strategy->showAd();
        echo "<br>";
        echo "Category";
        $this->strategy->showCategory();
        echo "<br>";
    }
    function setStrategy(UserStrategy $strategy){
        $this->strategy=$strategy;
    }
}

$page = new Page();
if(isset($_GET['male'])){
    $strategy = new MaleUser();
}else {
    $strategy = new FemaleUser();
}
$page->setStrategy($strategy);
$page->index();


执行结果图:

1.png


总结: 
通过以上方式,可以发现,在不同用户登录时显示不同的内容,但是解决了在显示时的硬编码的问题。如果要增加一种策略,只需要增加一种策略实现类,然后在入口文件中执行判断,传入这个类即可。实现了解耦。 
实现依赖倒置和控制反转 (有待理解) 
通过接口的方式,使得类和类之间不直接依赖。在使用该类的时候,才动态的传入该接口的一个实现类。如果要替换某个类,只需要提供一个实现了该接口的实现类,通过修改一行代码即可完成替换。


观察者模式


也是监听模式,顾名思意就是观察与被观察的关系。事件类(event)是被观察者,一旦事件类被触发(trigger),它的观察者(可以有多个观察者,可以是函数可以是对象)就会执行相应的处理。


观察者模式也是应用非常广泛的一个设计模式。


1:观察者模式(Observer),当一个对象状态发生变化时,依赖它的对象全部会收到通知,并自动更新。 
2:场景:一个事件发生后,要执行一连串更新操作。传统的编程方式,就是在事件的代码之后直接加入处理的逻辑。当更新的逻辑增多之后,代码会变得难以维护。这种方式是耦合的,侵入式的,增加新的逻辑需要修改事件的主体代码。 
3:观察者模式实现了低耦合,非侵入式的通知与更新机制。 


事件类:

class Event{ //事件
    private $_observers = array();
 
    public function register($sub){//注册观察者
        $this->_observers[] = $sub;
    }
     
    public function trigger(){//外部统一访问
        if( !empty($this->_observers) ){
            foreach($this->_observers as $observer){
                $observer->update();
            }      
        }
    }
}

观察者:

interface Observerable{
    public function update();
}
 
class Subscriber implements Observerable{
    public function update(){
        echo "Callback\n";
    }
}
//测试
$event = new Event();
$event->register(new Subscriber());
//$event->register(new Subscriber1());
//$event->register(new Subscriber2());
$event->trigger();


当某个事件发生后,需要执行的逻辑增多时,可以以松耦合的方式去增删逻辑。只需要定义一个实现了观察者接口的类,实现复杂的逻辑,然后在事件中注册即可。这样实现了低耦合。