首页 > 编程技术 > php

php Prototype原型模式学习笔记

发布时间:2016-11-25 14:58

我们一般用new来新增对象,不过很多时候新增一个对象需要一些工作。而星际里面往往会新增某些类的大量的对象,比如新增很多机枪兵和龙骑

待解决的问题:我们能否减少new的使用,同时避免需要新增对象的时候,了解对象的类名。


思路:php5提供了克隆方法,我们可以新增一个对象,然后每次需要新增和她同类的对象,克隆他就可以了。


原型(Prototype)模式示例:

 代码如下 复制代码

<?php

//机兵类

class Marine

{

  //所属的用户ID

  public $playerID

  //构造函数,参数为用户的id

  public function __construct($id)

  {

  $this->playerID = $id;

  }

}

//兵种的管理类

class TroopManager

{

  //数组,用于存放多个兵种的原型

  public $troopPrototype = array();

  //增加原型,第一个参数为原型的名字,第二个参数为原型对象

  public function addPrototype($name, $prototype)

  {

    $this->troopPrototype[$name] = $prototype;

  }

  //获取原型的克隆,也就是替代new的方法,参数为原型的名字

  public function getPrototype($name)

  {

    return clone $this->troopPrototype[$name];

  }

}

//初始化兵种的管理类

$manager = new TroopManager();

//初始化两个属于不同玩家的机兵的原型

$m1 = new Marine(1);

$m2 = new Marine(2);

//增加原型,同时用比较容易记忆的名字来命名原型

$manager->addPrototype('Marine of 1', $m1);

$manager->addPrototype('Marine of 2', $m2);

//当需要新增对象的时候,我们可以不必知道对象的类名和初始化的工作

$m3 = $manager->getPrototype('Marine of 1');

?>

用途总结:原型模式可以将新增对象的工作细节封装。


实现总结:需要一个原型管理类,实现增加和获取克隆原型的方法。注意这里由于为了简明,省略了一些东西,实际上我们可以在克隆方法上做一些改动,也可以用接口规范每个原型类。

在php网站开发过程中有时候需要把结果集进行分组,使用php的内置函数array_chunk就可以实现
 代码如下 复制代码

<?php
$teams=array(1,2,3,4,5,6,7,8,9);
$teams=array_chunk($teams,2);
print_r($teams);
/*

Array

(

    
[0] => Array

        
(

            
[0] => 1

            
[1] => 2

        
)

 
    
[1] => Array

        
(

            
[0] => 3

            
[1] => 4

        
)

 
    
[2] => Array

        
(

            
[0] => 5

            
[1] => 6

        
)

 
    
[3] => Array

        
(

            
[0] => 7

            
[1] => 8

        
)

 
    
[4] => Array

        
(

            
[0] => 9

        
)

 
)

*/

?>

array_chunk() 函数把一个数组分割为新的数组块。
其中每个数组的单元数目由 size 参数决定。最后一个数组的单元数目可能会少几个。
可选参数 preserve_key 是一个布尔值,它指定新数组的元素是否有和原数组相同的键(用于关联数组),还是从 0 开始的新数字键(用于索引数组)。默认是分配新的键。

Memcache是php中常用到的一个高性能的分布式的内存对象缓存系统,我们可以利用它来对网站进行性能提高并且减少服务器负载,下面是我的学习笔记本大家一起看看。 最简单的连接方法

例子

 代码如下 复制代码

<?php
$mem = new Memcache;
$mem->connect('127.0.0.1', 11211) or die ("Could not connect");
$mem->set('key', 'This is a test!', 0, 60);
$val = $mem->get('key');
echo $val;
?>

应用中会做一个类

 代码如下 复制代码

class MCache
{

    private static $server  = array('127.0.0.1', 11211);
    private static $client  = 'memcached'; // memcache or memcached

    private static function get_memcache()
    {
        static $memcache;
        if (!is_object($memcache))
        { www.111cn.net
            $memcache = self::$client === 'memcached' ?  new Memcached() : new Memcache ;
            $memcache->addServer(self::$server[0],self::$server[1]);
        }
        return $memcache;
    }

    public static  function set($key, $value, $expire=600)
    {
        self::$client === 'memcached' ?  self::get_memcache()->set($key, $value, $expire)
                                :  self::get_memcache()->set($key, $value, MEMCACHE_COMPRESSED, $expire);
    }

    public static  function get($key)
    {
        return self::get_memcache()->get($key);
    }

}

MCache::set('test_one', 'value_one', 60); # 60 Sec
print_r(MCache::get('test_one'));


PHP的Memcache客户端所有方法总结

memcache函数所有的方法列表如下:
Memcache::add – 添加一个值,如果已经存在,则返回false
Memcache::addServer – 添加一个可供使用的服务器地址
Memcache::close – 关闭一个Memcache对象
Memcache::connect – 创建一个Memcache对象
memcache_debug – 控制调试功能
Memcache::decrement – 对保存的某个key中的值进行减法操作
Memcache::delete – 删除一个key值
Memcache::flush – 清除所有缓存的数据
Memcache::get – 获取一个key值
Memcache::getExtendedStats – 获取进程池中所有进程的运行系统统计
Memcache::getServerStatus – 获取运行服务器的参数
Memcache::getStats – 返回服务器的一些运行统计信息
Memcache::getVersion – 返回运行的Memcache的版本信息
Memcache::increment – 对保存的某个key中的值进行加法操作
Memcache::pconnect – 创建一个Memcache的持久连接对象
Memcache::replace -对一个已有的key进行覆写操作
Memcache::set – 添加一个值,如果已经存在,则覆写
Memcache::setCompressThreshold – 对大于某一大小的数据进行压缩
Memcache::setServerParams – 在运行时修改服务器的参数

 

星际的战斗达到后面,地图里面的部队很多,如果我们把每个兵的图像动画和属性值作为一个对象的话,系统的内存里会消耗极大

我们在玩的时候会发现,因为星际里面的种族只有三个,其实兵种只有几十个。

虽然每个独立的士兵剩余的血不同,但是同一兵种的图像动画是一样的,即使不同的玩家,只是不同的颜色。比如每个人族的机枪兵。

而且大多数玩家只用到常用的一些兵种,很多时候不会制造所有的兵种。

待解决的问题:把把兵种的图像动画共享。

思路:我们把每个兵种的图像动画建模作为对象,放入内存共享。一旦有某个画面用到这个兵种,只要把共享的图像动画拿出来,更改颜色就可以了。

享元(Flyweight)模式示例:

 代码如下 复制代码

<?php

//机枪兵享元

class MarineFlyweight

{

  //绘制机枪兵的图像动画,参数为状态,比如属于哪一个玩家

  public function drawMarine($state)

  {

  //绘制机枪兵

  }

}

//享元工厂

class FlyweightFactory

{

  //享元数组,用于存放多个享元

  private $flyweights;

  //获取享元的方法

  public function getFlyweight($name)

  {

    if (!isset($flyweights[$name]))

    {

      $flyweights[$name] = new $name."Flyweight";

    }

    return $flyweights[$name];

  }

}

//初始化享元工厂

$flyweightFactory = new FlyweightFactory();

//当我们需要绘制一个机枪兵的时候,同时传递一个状态数组,里面包含剩余的血等等

$marine = $flyweightFactory->getFlyweight("Marine");

$marine->drawMarine($status);

?>

用途总结:享元模式可以将需要共享的资源集中起来,统一管理,防止重复消耗。

实现总结:需要一个享元工厂管理共享的资源,比如上面的FlyweightFactory。把所有共享的资源的生产全部交给个享元工厂。

我爱水煮鱼有个微信插件,会时不时的退出一些插件的 “插件”,直接下载一个提供的 PHP 文件,上传到插件一个指定的目录即可,插件会自动检测、引入并执行这个文件,研究了下,也想弄一个类似的功能。

 

 代码如下 复制代码
/*
 *引入一个目录的所有文件
 *http://www.111cn.net
*/
function Bing_include_all_php( $folder ){
 foreach( glob( "{$folder}/*.php" ) as $filename ) require_once $filename;
}

使用方法就是直接调用这个函数,第一个参数放上要引入的相对目录即可。

还有一种办法可以使用魔术方法__autoload来加载

 代码如下 复制代码

set_include_path('aa' . PATH_SEPARATOR . get_include_path());
function __autoload($className)
{
    //如果加这个检测, 因为此文件不在当前目录下,它就会检测不到文件存在,
   //但include是能成功的
    if (file_exists($className . '.php')) {
   include_once($className . '.php');
    } else {
        exit('no file');
    }
}
 
$a = new Acls();

我们一般使用_autoload自动加载类如下:

 代码如下 复制代码

<?php  
 
  function __autoload($class_name) {  
       require_once ($class_name . “class.php”);  
  }  
   $memo= new Demo();  

标签:[!--infotagslink--]

您可能感兴趣的文章: