php Observer观察者模式之学习笔记

 更新时间:2016年11月25日 14:58  点击:2740
当我们在星际中开地图和几家电脑作战的时候,电脑的几个玩家相当于结盟,一旦我们出兵进攻某一家电脑,其余的电脑会出兵救援。 那么如何让各家电脑知道自己的盟友被攻击了呢?并且自动做出反应?

那么如何让各家电脑知道自己的盟友被攻击了呢?并且自动做出反应?


待解决的问题:一旦某个电脑被我们进攻,其他电脑就获知,并且自动出兵救援。


思路:为电脑设置一些额外的观察系统,由他们去通知其他电脑。

 

观察者(Observer)模式示例:

 代码如下 复制代码

<?php

//抽象的结盟类

abstractclassabstractAlly{

//放置观察者的集合,这里以简单的数组来直观演示

public$oberserverCollection;

//增加观察者的方法,参数为观察者(也是玩家)的名称

publicfunctionaddOberserver($oberserverName)

{

以元素的方式将观察者对象放入观察者的集合

$this->oberserverCollection[]=newoberserver($oberserverName);

}

//将被攻击的电脑的名字通知各个观察者

publicfunctionnotify($beAttackedPlayerName)

{

//把观察者的集合循环

foreach($this->oberserverCollectionas$oberserver)

{

//调用各个观察者的救援函数,参数为被攻击的电脑的名字,if用来排除被攻击的电脑的观察者

if($oberserver->name!=$beAttackedPlayerName)$oberserver->help($beAttackedPlayerName);

}

}

abstractpublicfunctionbeAttacked($beAttackedPlayer);

}

//具体的结盟类

classAllyextendsabstractAlly{

//构造函数,将所有电脑玩家的名称的数组作为参数

publicfunction__construct($allPlayerName)

{

//把所有电脑玩家的数组循环

foreach($allPlayerNameas$playerName)

{

//增加观察者,参数为各个电脑玩家的名称

$this->addOberserver($playerName);

}

}

//将被攻击的电脑的名字通知各个观察者

publicfunctionbeAttacked($beAttackedPlayerName)

{

//调用各个观察者的救援函数,参数为被攻击的电脑的名字,if用来排除被攻击的电脑的观察者

$this->notify($beAttackedPlayerName);

}

}

//观察者的接口

interfaceIoberserver{

//定义规范救援方法

functionhelp($beAttackedPlayer);

}

//具体的观察者类

classoberserverimplementsIoberserver{

//观察者(也是玩家)对象的名字

public$name;

//构造函数,参数为观察者(也是玩家)的名称

publicfunction__construct($name)

{

$this->name=$name;

}

//观察者进行救援的方法

publichelp($beAttackedPlayerName)

{

//这里简单的输出,谁去救谁,最后加一个换行,便于显示

echo$this->name."help".$beAttackedPlayerName."<br>";

}

abstractpublicfunctionbeAttacked($beAttackedPlayer);

}

//假设我一对三,两家虫族,一家神族

$allComputePlayer=array('Zerg1','Protoss2','Zerg2');

//新建电脑结盟

$Ally=newAlly($allComputePlayer);

//假设我进攻了第二个虫族

$Ally->beAttacked('Zerg2');

?>


途总结:观察者模式可以将某个状态的变化立即通知所有相关的对象,并调用对方的处理方法。


实现总结:需要一个观察者类来处理变化,被观察的对象需要实现通知所有观察者的方法

星际里面的战斗都是在地图上进行的,只要我们可以编辑地图,就可以创造一些新的战役。可是,星际里面的地图绘制相关的代码如果开放出来,估计大多数万家都看不懂,更不要说自己编辑地图了。

待解决的问题:在不了解地图代码的结构下,我们要让玩家自己编辑地图。


思路:对于玩家而言,他熟悉的是水晶矿,高地这些形状,他和系统通过鼠标交互。我们可以设计一个地图编辑器让玩家使用,而无需让他研究绘制地图的细节代码。(实际上暴雪公司就是这样做的,很多玩家甚至暴雪内部人员都是用星际中的地图编辑器制作地图)


正面模式(Facade)示例:

<?php

//玩家的鼠标对象,记录鼠标在编辑其中的状态

class mouse {

//鼠标所处的X轴坐标

public static $X;

//鼠标当前能绘制的对象,比如水晶矿,河流等

public static $object;

//鼠标所处的Y轴坐标

public static $Y;

}

//地图编辑器

class mapEdit {

    //绘制方法

  public static function draw()

  {

    //根据鼠标对象的状态在地图上绘制各种东西

    //如果是水晶矿

    if(mouse::$object == "ore")

    {

    //调用水晶矿类的绘制方法,这个类定义在下面,这是真正的绘制,但玩家不必学习他的细节

    ore::draw();

    //如果是河流

    }elseif(mouse::$object == "river"){

    //调用河流类的绘制方法,这个类定义在下面,这是真正的绘制,但玩家不必学习他的细节

    river::draw();

    }

  }

}

//水晶矿类

class ore {

    //剩余的矿,以及其他属性,这里略过

  public $remain;

    //绘制水晶矿

  public static function draw()

  {

   //实际的绘制水晶矿的底层细节代码

  }

}

//河流类

class river {

    //绘制河流

  public static function draw()

  {

   //实际的绘制河流的底层细节代码

  }

}

//玩家在地图编辑器上点击绘制对象列表上的水晶矿对象

mouse::$object = "ore";

//玩家移动鼠标

mouse::$X = 311;

mouse::$Y = 126;

//在地图上点击,表示绘制当前对象,也就是一个水晶矿

mapEdit::draw();

?>

用途总结:正面模式让使用者集中于他所要进行的工作,而不必知道全部细节,或者说提供了一个容易使用的工具,同时屏蔽了底层细节,不必让使用者重新学习。


实现总结:需要一个类似上面地图编辑器的代码类,帮助玩家方便的进行操作。

PHP中字符串中的字符可以通过一个以0为开始的,用类似数组结构中的方括号包含对应的数字来查找和修改,如获取第二个$str[1]或$str{1} ,不建议使用{},最好使用[] 测试如下:
 代码如下 复制代码


//获取字符最后一个字符
$str = '111cn.net';
echo $str[strlen($str)-1]; //m
 
//修改第一个字符
$str = '111cn.net';
$str[0] = 'a';  //ahpddt.com
 
//方括号中的数字超出范围将会产生空白。 
$str = '111cn.net';
$str[100] = 'y';  //111cn.net y
 
//如果是非整数类型被转换成整数
$str = '111cn.net';
$str['a'] = 'y'; //111cn.net y
 
$str = '111cn.net';
$str[-1] = 'y'; //负数会出错:Warning: Illegal string offset: -1

原文来自:phpddt.com

declare是PHP的流程控制结构,directive目前支持两个指令【ticks和encoding】,ticks的使用需配合register_tick_function函数(当然还有unregister_tick_function函数)使用。

declare 结构用来设定一段代码的执行指令,它的语法结构如下:

    declare (directive)

        statement


不懂?通俗解释如下:

ticks参数表示运行多少语句调用一次register_tick_function的函数。
register_tick_function函数定义了每个tick事件发生时的处理函数。那么什么是tick事件呢?

tick是一个事件。

tick事件在PHP每执行N条低级语句就发生一次,N由declare语句指定。
可以用register_tick_function()来指定tick事件发生时应该执行的操作。


问题又来了,什么是低级语句呢?它包括:

简单语句:空语句(就一个;号),return, break, continue, throw, goto, global, static, unset, echo,  内置的HTML文本,分号结束的表达式等均算一个语句。
    复合语句:完整的if/elseif, while, do...while, for, foreach, switch, try...catch等算一个语句。
    语句块:{} 括出来的语句块。
    最后特别的:declare块本身也算一个语句(按道理declare块也算是复合语句,但此处特意将其独立出来)。


看一个简单的例子:

 代码如下 复制代码

/**
 * declare
 * @link http://www.111cn.net
 */
function do_tick()
{
        echo "<font color=red>do_tick</font>";
}
 
register_tick_function('do_tick');
 
declare(ticks = 1)
{
        for($i = 1; $i < 5; $i++)
        {
                echo "<font color=blue>{$i}</font><br>";
        }
}


上面这段程序的运行结果:

PHP declare控制符及ticks的例子详解
PHP declare控制符及ticks详细教程对结果解释下:

第一次进入for循环,执行echo后执行第一次do_tick函数;
第一次for循环结束后;执行第二次do_tick函数;
循环四次......;
第五次进行for循环,条件不满足,for循环结束,执行一次do_tick函数;
declare本身也是一条语句,也要执行一次do_tick函数。

从上可以看出,declare和ticks可以用来做调试或性能测试。

我们需要写一个简单的函数可以获取指定时间日期内的一段日期列表,下面我找到一个比较合适的方法与各位朋友分享。

最近在做一个关于日程表的项目,给出一个开始时间和一个结束时间,需要列出这个时间段内的日期列表并同时判断是周几。经过研究,得出如下方法,和大家共享,方便有需要的朋友。

先贴一下此次需求的效果图:

PHP如何获取一段时间内的日期列表

 代码如下 复制代码
/*
*参数分别是开始时间戳,结束时间戳
*/
function timeList($beginTimeStamp,$endTimeStamp){
 if(!is_numeric($beginTimeStamp)||!is_numeric($endTimeStamp)||($endTimeStamp<=$beginTimeStamp)) return '';
 $tmp=array();
    for($i=$beginTimeStamp;$i<=$endTimeStamp;$i+=(24*3600)){
  $tmp['timeStampList'][]=$i;
        $tmp['dayList'][]=date('Y年m月d日',$i);
  $tmp['dayWeek'][]=getWeek($i);
    }
 return $tmp;
}
function getWeek($timestamp){
 $timestamp=date('w',$timestamp);
 $str='';
 switch($timestamp){
  case '0':
   $str.='周日';
  break;
  case '1':
   $str.='周一';
  break;
  case '2':
   $str.='周二';
  break;
  case '3':
   $str.='周三';
  break;
  case '4':
   $str.='周四';
  break;
  case '5':
   $str.='周五';
  break;
  case '6':
   $str.='周六';
  break;
 }
 return $str;
}


php获取某段时间内每个月的方法,返回由这些月份组成的数组

 代码如下 复制代码

/**
* 生成从开始月份到结束月份的月份数组
* @param int $start 开始时间戳
* @param int $end 结束时间戳
*/
function monthList($start,$end){
 if(!is_numeric($start)||!is_numeric($end)||($end<=$start)) return '';
 $start=date('Y-m',$start);
 $end=date('Y-m',$end);
 //转为时间戳
 $start=strtotime($start.'-01');
 $end=strtotime($end.'-01');
 $i=0;//http://www.phpernote.com/php-function/224.html
 $d=array();
 while($start<=$end){
  //这里累加每个月的的总秒数 计算公式:上一月1号的时间戳秒数减去当前月的时间戳秒数
  $d[$i]=trim(date('Y-m',$start),' ');
  $start+=strtotime('+1 month',$start)-$start;
  $i++;
 }
 return $d;
}例如:

echo '<pre>';print_r(monthList(1395283229,1398960000));


例如:

echo '<pre>';print_r(monthList(1395283229,1398960000));结果将得到如下:

Array
(
    [0] => 2014-03
    [1] => 2014-04
    [2] => 2014-05
)

[!--infotagslink--]

相关文章

  • php上传图片学习笔记与心得

    我们在php中上传文件就必须使用#_FILE变量了,这个自动全局变量 $_FILES 从 PHP 4.1.0 版本开始被支持。在这之前,从 4.0.0 版本开始,PHP 支持 $HTTP_POST_FILES 数组。这...2016-11-25
  • Smarty模板学习笔记之Smarty简介

    1、简介Smarty是一个使用PHP写出来的模板PHP模板引擎,是目前业界最著名的PHP模板引擎之一。它分离了逻辑代码和外在的内容,提供了一种易于管理和使用的方法,用来将原本与HTML代码混杂在一起PHP代码逻辑分离。简单的讲,目...2014-05-31
  • php Observer观察者模式之学习笔记

    当我们在星际中开地图和几家电脑作战的时候,电脑的几个玩家相当于结盟,一旦我们出兵进攻某一家电脑,其余的电脑会出兵救援。 那么如何让各家电脑知道自己的盟友被攻击了...2016-11-25
  • PHP 日期函数 学习笔记介绍

    举一个简单的date例子 我将使用echo命令把内容输出到我们的客户端(浏览器)。我将使用下面的代码做为基础代码。 代码如下 复制代码 <!DOCTY...2016-11-25
  • 学习JavaScript设计模式之观察者模式

    这篇文章主要为大家介绍了JavaScript设计模式中的观察者模式,对JavaScript设计模式感兴趣的小伙伴们可以参考一下...2016-01-21
  • Android学习笔记之多界面切换实例

    一篇Android学习笔记之多界面切换实例,希望对各位朋友有所帮助。 用过VB 、 VC#的朋友都知道,在VB或VC#里要进行窗口(界面)切换很容易 例如在VB、C#里: 有 Fom1、...2016-09-20
  • php中的变量引用传值学习笔记

    引用:意思是将原始对象在内存中的地址传递给目标对象,就相当于原始对象和目标对象指向的是同一个内存地址。此时,如果对目标对象或者原始对象进行修改,内存中的数据也会改...2016-11-25
  • PHP中的cURL请求及示例学习笔记

    cURL是php中一个很强大的功能,可以模仿各种用户请求,如模仿用户登录,发送php cookie等等操作,下面我来整理一些相关的方法与各位同学看看 备注:使用curl_init函数,必须...2016-11-25
  • 那些年,我还在学习C# 学习笔记

    那些年学了ASP.NET后,才开始学习C#,说来也怪,怎么学了ASP.NET才来学习C#,其实没有什么的...2020-06-25
  • YII2 WIDGET的学习笔记

    CWidget是所有Widget的基类。CWidget是自包含组件,可以看出是MVC的简略版,CWidget相比Controller,既没有actions,也没有filters widget,英文意思为小工具,小挂件,在程序...2016-11-25
  • metasploit调用nexpose扫描学习笔记

    Metasploit是一个免费的、可下载的框架,通过它可以很容易地获取、开发并对计算机软件漏洞实施攻击。它本身附带数百个已知软件漏洞的专业级漏洞攻击工具 nexpose安...2016-11-25
  • php学习笔记之PHP扩展开发教程

    PHP扩展开发不是所有开发者都会操作的一个东西,下面我来演示一个关于PHP扩展开发实现过程,各位同学有需要可进入参考。 我们先假设需要这样一个扩展,提供一个叫tao_s...2016-11-25
  • Yii2学习笔记之汉化yii设置表单的描述

    小编推荐的这篇文章介绍了Yii2学习笔记之汉化yii设置表单的描述,非常实用,有兴趣的同学快来看看吧。 一:汉化框架&#8195;&#8195;框架汉化在这里设置,如果不生效,前台后...2017-07-06
  • php Builder建造器模式学习笔记

    星际里面有不少的任务关,也可以自己编辑地图,画面上有各种地形,建筑和部队,存在一个问题,初始化画面的流程很乱。待解决的问题:完成初始化画面的工作,同时尽量减少各种绘制...2016-11-25
  • php中session学习笔记

    Session指的就是用户在浏览某个网站时,从进入网站到浏览器关闭所经过的这段时间,也就是用户浏览这个网站所花费的时间。从上述的定义中我们可以看到,Session实际上是一个...2016-11-25
  • PHP单例模式学习笔记详解

    单例模式是php中一个为了简化大家开发及重复调用的一个功能,下面我来给各位朋友详细介绍单例模式用法。 1.单例模式的概念 顾名思义,单例模式只有一个实例,而且自行...2016-11-25
  • php正则表达式子模式的反向引用学习笔记

    本文章给大家分享一篇php正则表达式子模式的反向引用学习笔记,希望此教程对各位朋友有帮助哦。 需要用正则表达式获取字符串的标题。标题标签是h1~h6。 使用正则...2016-11-25
  • C#观察者模式(Observer Pattern)实例教程

    这篇文章主要介绍了C#观察者模式(Observer Pattern),主要以一个实例的形式讲述了C#观察者模式的实现过程,详细讲述了接口的定义、通知及动作的实现方法,需要的朋友可以参考下...2020-06-25
  • php 适配器模式的学习笔记

    适配器模式许多和php程序员都没有碰到关于适配器的应用了,这里小编整理了两个关于适配器的使用例子,下面我们就一起来看看吧,希望各位有帮助。 【目的】:将一个类的...2016-11-25
  • PHP CodeIgniter学习笔记详解

    今天做的是个简单的表明表页面,前端我用的是Bootstrap。没办法,自己不懂美工,也只有用别人的工具。BS真的很漂亮,而且插件丰富,不愧是twitter工程师弄出来的东西。 (中...2016-11-25