老生常谈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 相关文章推荐
php discuz 主题表和回帖表的设计
Mar 13 PHP
ajax+php打造进度条 readyState各状态
Mar 20 PHP
php cli 小技巧
Jun 03 PHP
探讨:如何使用PHP实现计算两个日期间隔的年、月、周、日数
Jun 13 PHP
php读取csv文件后,uft8 bom导致在页面上显示出现问题的解决方法
Aug 10 PHP
浅析ThinkPHP中的pathinfo模式和URL重写
Jan 06 PHP
php查询相似度最高的字符串的方法
Mar 12 PHP
php实现将wav文件转换成图像文件并在页面中显示的方法
Apr 21 PHP
在Debian系统下配置LNMP的教程
Jul 09 PHP
curl 出现错误的调试方法(必看)
Feb 13 PHP
php生成复杂验证码(倾斜,正弦干扰线,黏贴,旋转)
Mar 12 PHP
Laravel框架实现调用百度翻译API功能示例
May 30 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插入中文到sqlserver 2008里出现乱码的解决办法分享
2012/07/19 PHP
thinkphp在模型中自动完成session赋值示例代码
2014/09/09 PHP
PHP入门教程之日期与时间操作技巧总结(格式化,验证,获取,转换,计算等)
2016/09/11 PHP
yii框架搜索分页modle写法
2016/12/19 PHP
jquery实现div拖拽宽度示例代码
2013/07/31 Javascript
写JQuery插件的基本知识
2013/11/25 Javascript
js实现div闪烁原理及实现代码
2014/06/24 Javascript
将数字转换成大写的人民币表达式的js函数
2014/09/21 Javascript
jquery插件jquery.confirm弹出确认消息
2015/12/22 Javascript
javascript插件开发的一些感想和心得
2016/02/28 Javascript
浅谈JSON.stringify()和JOSN.parse()方法的不同
2016/08/29 Javascript
详解Node.js中的事件机制
2016/09/22 Javascript
jQuery继承extend用法详解
2016/10/10 Javascript
JavaScript数组迭代方法
2017/03/03 Javascript
jQuery EasyUI 为Combo,Combobox添加清除值功能的实例
2017/04/13 jQuery
windows下vue-cli导入bootstrap样式
2017/04/25 Javascript
详解angular ui-grid之过滤器设置
2017/06/07 Javascript
JavaScript 完成注册页面表单校验的实例
2017/08/19 Javascript
vue项目中axios请求网络接口封装的示例代码
2018/12/18 Javascript
JavaScript闭包与作用域链实例分析
2019/01/21 Javascript
bootstrap-table实现表头固定以及列固定的方法示例
2019/03/07 Javascript
angular4+百分比进度显示插件用法示例
2019/05/05 Javascript
JS中的算法与数据结构之链表(Linked-list)实例详解
2019/08/20 Javascript
Vue3 响应式侦听与计算的实现
2020/11/11 Javascript
Python的socket模块源码中的一些实现要点分析
2016/06/06 Python
Python脚本获取操作系统版本信息
2016/12/17 Python
解决Python3 抓取微信账单信息问题
2019/07/19 Python
Python模拟FTP文件服务器的操作方法
2020/02/18 Python
让Django的BooleanField支持字符串形式的输入方式
2020/05/20 Python
Python3+Django get/post请求实现教程详解
2021/02/16 Python
Canon佳能美国官方商店:购买数码相机、数码单反相机、镜头和打印机
2016/11/15 全球购物
Answear匈牙利:来自全球200多个知名时尚品牌
2017/04/21 全球购物
资深生产主管自我评价
2013/09/22 职场文书
2014年纳税评估工作总结
2014/12/23 职场文书
心灵捕手观后感
2015/06/02 职场文书
如何用JS实现简单的数据监听
2021/05/06 Javascript