老生常谈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 相关文章推荐
从康盛产品(discuz)提取出来的模板类
Jun 28 PHP
用PHP实现 上一篇、下一篇的代码
Sep 29 PHP
更改localhost为其他名字的方法
Feb 10 PHP
3款值得推荐的微信开发开源框架
Oct 28 PHP
Smarty中的注释和截断功能介绍
Apr 09 PHP
PHP加密解密字符串汇总
Apr 26 PHP
php使用flock阻塞写入文件和非阻塞写入文件的实例讲解
Jul 10 PHP
thinkPHP5实现的查询数据库并返回json数据实例
Oct 23 PHP
在 PHP 和 Laravel 中使用 Traits的方法
Nov 13 PHP
PHP使用openssl扩展实现加解密方法示例
Feb 20 PHP
TP5多入口设置实例讲解
Dec 15 PHP
PHP设计模式之命令模式示例详解
Dec 20 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函数解决SQL injection
2006/12/09 PHP
PHP中的MYSQL常用函数(php下操作数据库必备)
2010/09/12 PHP
php+mysqli预处理技术实现添加、修改及删除多条数据的方法
2015/01/30 PHP
使用JS进行目录上传(相当于批量上传)
2010/12/05 Javascript
Javascript实现网络监测的方法
2015/07/31 Javascript
js控制多图左右滚动切换效果代码分享
2015/08/26 Javascript
3种js实现string的substring方法
2015/11/09 Javascript
jQuery点击输入框显示验证码图片
2016/05/19 Javascript
Angular企业级开发——MVC之控制器详解
2017/02/20 Javascript
vue单页面打包文件大?首次加载慢?nginx带你飞,从7.5M到1.3M蜕变过程(推荐)
2018/01/16 Javascript
Vue结合后台导入导出Excel问题详解
2019/02/19 Javascript
Vue多组件仓库开发与发布详解
2019/02/28 Javascript
javascript绘制简单钟表效果
2020/04/07 Javascript
vue proxy 的优势与使用场景实现
2020/06/15 Javascript
JavaScript如何实现监听键盘输入和鼠标监点击
2020/07/20 Javascript
使用Python从有道词典网页获取单词翻译
2016/07/03 Python
Python用UUID库生成唯一ID的方法示例
2016/12/15 Python
Python常用算法学习基础教程
2017/04/13 Python
Python设计模式之代理模式简单示例
2018/01/09 Python
Python日期时间模块datetime详解与Python 日期时间的比较,计算实例代码
2018/09/14 Python
python之pyqt5通过按钮改变Label的背景颜色方法
2019/06/13 Python
Python 3.6打包成EXE可执行程序的实现
2019/10/18 Python
.dcm格式文件软件读取及python处理详解
2020/01/16 Python
澳大利亚首屈一指的在线购物目的地:Kogan.com
2017/02/02 全球购物
英国优质鞋类专家:Robinson’s Shoes
2017/12/08 全球购物
"引用"与指针的区别是什么
2016/09/07 面试题
母亲节演讲稿范文
2014/01/02 职场文书
2014学习全国两会精神心得体会2000字
2014/03/11 职场文书
《风娃娃》教学反思
2014/04/19 职场文书
求职信模板
2014/05/23 职场文书
中秋晚会活动方案
2014/08/31 职场文书
2015年医院保卫科工作总结
2015/07/23 职场文书
2016感恩母亲节校园广播稿
2015/12/17 职场文书
MySQL官方导出工具mysqlpump的使用
2021/05/21 MySQL
mysql使用 not int 子查询隐含陷阱
2022/04/12 MySQL
win10输入法不见了只能打出字母怎么解决?
2022/08/05 数码科技