老生常谈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 相关文章推荐
DOMXML函数笔记
Oct 09 PHP
PHP中for循环语句的几种变型
Nov 26 PHP
PHP的分页功能
Mar 21 PHP
怎样去阅读一份php源代码
Aug 21 PHP
PHP设置图片文件上传大小的具体实现方法
Oct 11 PHP
php+mysql实现无限分类实例详解
Jan 15 PHP
php通过array_merge()函数合并两个数组的方法
Mar 18 PHP
在html文件中也可以执行php语句的方法
Apr 09 PHP
PHP上传Excel文件导入数据到MySQL数据库示例
Oct 25 PHP
thinkphp5 migrate数据库迁移工具
Feb 20 PHP
PDO::query讲解
Jan 29 PHP
php5.3/5.4/5.5/5.6/7常见新增特性汇总整理
Feb 27 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设计模式 Chain Of Responsibility (职责链模式)
2011/06/26 PHP
php自定义urlencode,urldecode函数实例
2015/03/24 PHP
php file_get_contents取文件中数组元素的方法
2017/04/01 PHP
PHP文件操作实例总结【文件上传、下载、分页】
2018/12/08 PHP
学习YUI.Ext 第二天
2007/03/10 Javascript
ajax 文件上传应用简单实现
2009/03/03 Javascript
Jquery 基础学习笔记
2009/05/29 Javascript
javascript dom代码应用 简单的相册[firefox only]
2010/06/12 Javascript
javascript分页代码(当前页码居中)
2012/09/20 Javascript
js 图片随机不定向浮动的实现代码
2013/07/02 Javascript
js判断客户端是iOS还是Android等移动终端的方法
2013/12/11 Javascript
firefox下jquery ajax返回object XMLDocument处理方法
2014/01/26 Javascript
引用其它js时如何同时处理多个window.onload事件
2014/09/02 Javascript
完美JQuery图片切换效果的简单实现
2016/07/21 Javascript
Vue.js 父子组件通讯开发实例
2016/09/06 Javascript
Angularjs 动态改变title标题(兼容ios)
2016/12/29 Javascript
解决IE7中使用jQuery动态操作name问题
2017/08/28 jQuery
在 Linux/Unix 中不重启 Vim 而重新加载 .vimrc 文件的流程
2018/03/21 Javascript
Vue 实现展开折叠效果的示例代码
2018/08/27 Javascript
pygame加载中文名mp3文件出现error
2017/03/31 Python
Python+OpenCV图像处理——实现直线检测
2020/10/23 Python
css3媒体查询中device-width和width的区别详解
2020/03/27 HTML / CSS
HTML5实现Notification API桌面通知功能
2016/03/02 HTML / CSS
HTML5 canvas基本绘图之图形组合
2016/06/27 HTML / CSS
党校自我鉴定范文
2013/10/02 职场文书
长辈证婚人证婚词
2014/01/09 职场文书
职务任命书范本
2014/06/05 职场文书
计算机多媒体专业自荐信
2014/07/04 职场文书
房屋转让协议书
2014/10/18 职场文书
简历自我评价优缺点
2015/03/11 职场文书
红色革命电影观后感
2015/06/18 职场文书
python使用pygame创建精灵Sprite
2021/04/06 Python
Oracle更换为MySQL遇到的问题及解决
2021/05/21 Oracle
mysql 索引合并的使用
2021/08/30 MySQL
JAVA长虹键法之建造者Builder模式实现
2022/04/10 Java/Android
Spring中bean集合注入的方法详解
2022/07/07 Java/Android