老生常谈PHP面向对象之标识映射


Posted in PHP onJune 21, 2017

标识映射在数据映射器的基础上增加了标识映射类,主要功能是保存已经创建好的对象,在需要的时候可以直接获取而不是重复创建造成系统性能的下降。

在数据映射器基础上还增加了部分调用标识映射类的方法,示例代码如下:

namespace woo\domain;

//标识映射类
class ObjectWatcher{
  
  private $all = array();        //存放对象的小仓库
  private static $instance;      //单例
  
  private function __construct (){}
  
  static function instance(){
    if(!self::$instance){
      self::$instance = new ObjectWatcher();
    }
    return self::$instance;
  }
  
  //获取一个唯一的标识,这里采用了领域类类名+ID的方式创建一个唯一标识,避免多个数据库表调用这个类时出现ID重复的问题
  function globalKey(DomainObject $obj){
    $key = get_class($obj) . "." . $obj->getId();
    return $key;
  }
  
  //添加对象
  static function add(DomainObject $obj){
    $inst = self::instance();
    $inst->all[$inst->globalKey($obj)] = $obj;
  }
  
  //获取对象
  static function exists($classname,$id){
    $inst = self::instance();
    $key = "$classname.$id";
    if(isset($inst->all[$key]){
      return $inst->all[$key];
    }
    return null;
  }
}

namespace woo\mapper;

abstract class Mapper{      //抽象基类
  abstract static $PDO;    //操作数据库的pdo对象
  function __construct (){
    if(!isset(self::$PDO){
      $dsn = \woo\base\ApplicationRegistry::getDSN();
      if(is_null($dsn)){
        throw new \woo\base\AppException("no dns");
      }
      self::$PDO = new \PDO($dsn);
      self::$PDO->setAttribute(\PDO::ATTR_ERRMODE,\PDO::ERRMODE_EXCEPTION);
    }
  }
  
  //数据映射器基础上新增的方法以下会简称新增,这里的作用的是获取对象而不是查询数据库并重复创建对象
  //(对比一下原数据映射器的相关代码即可了解)
  private function getFroMap($id){
    return \woo\domain\ObjectWatcher::exists($this->targetClass(),$id);
  }
  
  //新增,这里的作用的是将创建的对象保存起来
  private function addToMap(\woo\domain\DomainObject $obj){//////
    return \woo\domain\ObjectWatcher::add($obj);
  }
  
  
  //对比原数据映射器的代码,便发现它不是直接创建对象而是首先在标识映射类中查找,找不到才调用的
  //子类的方法创建并插入到标识映射类,下面的find方法也遵循了这一原则
  function createObject($array){          
    $old = $this->getFromMap($array['id']);  //新增
    if($old){return $old}          //新增
    $obj = $this->doCreateObject($array);  //在子类中实现
    $this->addToMap($obj);          //新增
    return $obj;
  }
  
  //
  function find($id){                //通过ID从数据库中获取一条数据并创建为对象  
    $old = $this->getFromMap($id);        //新增
    if($old){return $old}            //新增
    
    $this->selectStmt()->execute(array($id));
    $array= $this->selectStmt()->fetch();
    $this->selectStmt()->closeCursor();
    if(!is_array($array)){
      return null;
    }
    if(!isset($array['id'])){
      return null;
    }
    $object = $this->createObject($array);
    $this->addToMap($object);          //新增
    return $object;  
  }
  
  function insert(\woo\domain\DomainObject $obj){      //将对象数据插入数据库
    $this->doInsert($obj);
    $this->addToMap($obj);            //新增
  }
  
  //需要在子类中实现的各抽象方法
  abstract function targetClass();//////
  abstract function update(\woo\domain\DomainObject $objet);
  protected abstract function doCreateObject(array $array);
  protected abstract function selectStmt();
  protected abstract function doInsert(\woo\domain\DomainObject $object);
}

class SpaceMapper extends Mapper {
  //其他代码在数据映射器一文中已有实现这里略过
  //.............
  
  //类名,在标识映射类中生成唯一标识用的
  protected function targetClass(){
    return "woo\\domain\\Space";
  }
}

以上这篇老生常谈PHP面向对象之标识映射就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

PHP 相关文章推荐
一个程序下载的管理程序(二)
Oct 09 PHP
上传多个文件的PHP脚本
Nov 26 PHP
php巧获服务器端信息
Dec 06 PHP
PHP中的CMS的涵义
Mar 11 PHP
PHP的分页功能
Mar 21 PHP
PHP 抓取网页图片并且另存为的实现代码
Mar 24 PHP
PHP 验证码的实现代码
Jul 17 PHP
二招解决php乱码问题
Mar 25 PHP
Cygwin中安装PHP方法步骤
Jul 04 PHP
PHP实现的策略模式简单示例
Aug 25 PHP
Phpstorm+Xdebug断点调试PHP的方法
May 14 PHP
laravel框架模型和数据库基础操作实例详解
Jan 25 PHP
PHP封装的PDO数据库操作类实例
Jun 21 #PHP
PHP基于ORM方式操作MySQL数据库实例
Jun 21 #PHP
php 猴子摘桃的算法
Jun 20 #PHP
详解php框架Yaf路由重写
Jun 20 #PHP
PHP简单计算两个时间差的方法示例
Jun 20 #PHP
php实现的错误处理封装类实例
Jun 20 #PHP
PHP实现在windows下配置sendmail并通过mail()函数发送邮件的方法
Jun 20 #PHP
You might like
php数组键值用法实例分析
2015/02/27 PHP
thinkPHP实现多字段模糊匹配查询的方法
2016/12/01 PHP
php 后端实现JWT认证方法示例
2018/09/04 PHP
PHP实现字符串的全排列详解
2019/04/24 PHP
AutoSave/自动存储功能实现
2007/03/24 Javascript
JavaScript模板入门介绍
2012/09/26 Javascript
javascrpt绑定事件之匿名函数无法解除绑定问题
2012/12/06 Javascript
JavaScript拆分字符串时产生空字符的解决方案
2014/09/26 Javascript
jQuery实现仿路边灯箱广告图片轮播效果
2015/04/15 Javascript
Jquery判断radio、selelct、checkbox是否选中及获取选中值方法总结
2015/04/15 Javascript
jquery插件bxslider用法实例分析
2015/04/16 Javascript
jQuery实现图片与文字描述左右滑动自动切换的方法
2015/07/27 Javascript
JavaScript仿支付宝密码输入框
2015/12/29 Javascript
Javascript之Date对象详解
2016/06/07 Javascript
JSON对象转化为字符串详解
2017/08/11 Javascript
原生JS实现的雪花飘落动画效果
2018/05/03 Javascript
vue移动端监听滚动条高度的实现方法
2018/09/03 Javascript
使用Node.js写一个代码生成器的方法步骤
2019/05/10 Javascript
JavaScript单线程和任务队列原理解析
2020/02/04 Javascript
es6数组includes()用法实例分析
2020/04/18 Javascript
5个你不知道的JavaScript字符串处理库(小结)
2020/06/01 Javascript
Vue路由权限控制解析
2020/11/09 Javascript
在Linux系统上部署Apache+Python+Django+MySQL环境
2015/12/24 Python
selenium+python实现自动登录脚本
2018/04/22 Python
python实现电子产品商店
2019/02/26 Python
python selenium 弹出框处理的实现
2019/02/26 Python
python日志logging模块使用方法分析
2019/05/23 Python
Python判断三段线能否构成三角形的代码
2020/04/12 Python
python查看矩阵的行列号以及维数方式
2020/05/22 Python
Elasticsearch py客户端库安装及使用方法解析
2020/09/14 Python
css3绘制百度的小度熊
2018/10/29 HTML / CSS
.NET面试题:什么是反射
2016/09/30 面试题
暑假家长评语大全
2014/04/17 职场文书
保护环境倡议书300字
2014/05/19 职场文书
琅琊山导游词
2015/02/05 职场文书
关于flex 上下文中自动 margin的问题(完整例子)
2021/05/20 HTML / CSS