crazytata 发表于 2019-3-13 19:29

【php】php设计模式之观察者模式

最近在学习php的设计模式,将我的源码与大家分享出来。有什么问题的地方希望大家指出来。
从面向过程的角度来看,首先是观察者向主题注册,注册完之后,主题再通知观察者做出相应的操作,整个事情就完了。从面向对象的角度来看,主题提供注册和通知的接口,观察者提供自身操作的接口。(这些观察者拥有一个同一个接口。)观察者利用主题的接口向主题注册,而主题利用观察者接口通知观察者。耦合度相当之低。如何实现观察者注册?通过前面的注册者模式很容易给我们提供思路,把这些对象加到一棵注册树上就好了嘛。如何通知?这就更简单了,对注册树进行遍历,让每个对象实现其接口提供的操作。以上代码直接创建对应的文件并放在对应的目录中,在系统中就直接可以访问。
一 .观察者相关代码:
[*]    观察者接口:

<?php
namespace design\observer;

interface Observer{
    public function modify($wear);
}


[*]Wang 观察者


<?php
namespace design\observer;

class Wang implements Observer
{
    protected $wearing='';
    public function modify($wear){
      $this->wearing=$wear;
    }

    public function getWearing(){
      return 'wang need wear '.$this->wearing;
    }
}



[*]Li观察着

<?php
namespace design\observer;

class Li implements Observer
{
    protected $wearing='';
    public function modify($wear){
      $this->wearing=$wear;
    }

    public function getWearing(){
      return 'li need wear '.$this->wearing;
    }
}

[*]Song观察者

<?php
namespace design\observer;

class Song implements Observer
{
    protected $wearing='';
    public function modify($wear){
      $this->wearing=$wear;
    }

    public function getWearing(){
      return 'song need wear '.$this->wearing;
    }
}

二 . 被观察者相关代码
[*]    被观察者接口

<?php
namespace design\observer;

interface Main{
    public function register(Observer $observer);
    public function notify($wear);
}

[*]    被观察者实现

<?php

namespace design\observer;

class Weather implements Main
{
    private $objects=[];
    public function register(Observer $observer)
    {
      if(!in_array($observer,$this->objects)){
            $this->objects []=$observer;
      }
    }

    public function notify($wear)
    {
      foreach ($this->objects as $obj){
            $obj->modify($wear);
      }
    }
}

三 . 三方触发
[*]主触发类

<?php
define('BASE_ROOT',__DIR__);
include_once 'Autoload.php';
spl_autoload_register("Autoload::autoloadS");
///////////////////////////////////策略模式////////////////////////
//$obj = new \design\strategy\Strategy($_GET['a']);
//$res = $obj->get();
//echo $res;
///////////////////////////////////策略模式////////////////////////

///////////////////////////////////观察者模式////////////////////////
$params         = $_GET['a'];
//实例化各个类
$weather   = \design\observer\Factory::getInstace('Weather');
$wang      = \design\observer\Factory::getInstace('Wang');
$song      = \design\observer\Factory::getInstace('Song');
$li      = \design\observer\Factory::getInstace('Li');

//将实例化的类进行注册
$weather->register($wang);
$weather->register($song);
$weather->register($li);

//根据外部环境触发被观察者的变化
$weather->notify($params);

//打印被观察者变化后推送给各个观察者的变化
echo $wang->getWearing()."<br>";
echo $song->getWearing()."<br>";
echo $li->getWearing()."<br>";
///////////////////////////////////观察者模式////////////////////////
die;


[*]工厂类

<?php
namespace design\observer;

class Factory
{
    private static $instances=[];
    private function __construct(){}
    public static function getInstace($alias){
      if(!isset(self::$instances [$alias])){
            $class = "\\design\\observer\\".$alias;
            self::$instances [$alias] = new $class;
      }
      return self::$instances [$alias];
    }
    private function __clone(){}
}



[*]自动加载类

<?php

class Autoload{
    public static function autoloadS($class){
      $arr = explode('\\',$class);
      $name = array_pop($arr);
      $rote = BASE_ROOT.'/';
      array_map(function($val) use(&$rote){
            $rote.= $val.'/';
      },$arr);
      return require_once($rote.$name.'.php');
    }
}

新手初次发帖,如有违规请版主通知删除。

源码:

小熊点灯 发表于 2019-3-13 19:37

小白路过

唯一丶 发表于 2019-3-14 08:52

观察者模式在官方的SPL中有完整规范化的接口,为了可通用性应该恪守。
页: [1]
查看完整版本: 【php】php设计模式之观察者模式