设计模式专题(二十四) ——访问者模式

设计模式专题(二十四)——访问者模式

(原创内容,转载请注明来源,谢谢)

一、概述

访问者模式(visitor)表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变各元素的类的前提下,定义作用于这些元素的新操作。

访问者模式适用于数据结构相对稳定的系统,并把数据结构和作用于结构上的操作之间的耦合解开,使操作可以自由地演化。

访问者模式的目的是为了把处理从数据结构分离出来,如果有比较稳定的数据结构,易于变化的算法,则访问者模式比较合适。

访问者模式的优点在于增加新的操作很容易,意味着增加一个新的访问者,访问者模式将有关的行为集中到一个访问者对象中。

访问者模式的缺点在于增加新的数据结构很难,因为其设计的时候基本已经按照数据结构设定好了。

访问者模式使用了运行期间的执行,根据实际传入的类型执行其特定的方法,这个称为双分派技术(double dispatch)。

二、类图

三、设计实现

1、业务场景

现需要实现工作单元,将数据库中查询的内容,转换成一个类进行存储,而在查询后对该类进行的增删改操作,会等工作单元执行commit的时候一并提交,而期间会先计入缓存,这样既可以实现多个增删改操作一并提交,又能保证数据一致性。

2、实现过程

<?php
//访问者模式
//1.抽象element
abstract class Element{
         protected$isDelete;
         protected$isUpdate;
         protected$isInsert;
         protected$sql;
         protected$data;
         publicfunction __construct(){
                   $this->isDelete= false;
                   $this->isUpdate= false;
                   $this->isInsert= false;
                   $this->sql= '';
                   $this->data= array();
         }
         protectedfunction delete(){
                   $this->isDelete= true;
         }
         protectedfunction isUpdate(){
                   $this->isUpdate= true;
         }
         protectedfunction isInsert(){
                   $this->isInsert= true;
         }
         publicfunction getSql(){
                   return$this->sql;
         }
         publicfunction setData($type, $data){
                   switch($type) {
                            case'insert':
                                     $this->isInsert();
                                     $this->insert($data);
                                     break;
                            case'update':
                                     $this->isUpdate();
                                     $this->update($data);
                            case'delete':
                                     $this->isDelete();
                                     $this->delete($data);
                            default:
                                     $this->select($data);
                                     break;
                   }
                   $this->data= $data;
         }
         publicfunction insert($data){}
         publicfunction update($data){}
         publicfunction delete($data){}
         publicfunction select($data){}
}
//2.具体element--delete
class ElementTableA{
         publicfunction __construct(){
                   parent::__construct();
         }
         publicfunction insert($data){
                   $this->sql= 'insert tableA的sql';
         }
         publicfunction update($data){
                   $this->sql= 'update tableA的sql';
         }
         publicfunction delete($data){
                   $this->sql= 'delete tableA的sql';
         }
}
//table B 同 table A
//3.执行类
class UnitWork{
         public$sqls;
         public$elements;
         privatefunction setElements(array $elements){
                   foreach($elements as $index => $ele) {
                            if(!($eleinstanceof Element)){
                                     unset($elements[$index]);
                            }
                   }
                   if(empty($elements)){
                            returnfalse;
                   }
                   $this->elements= $elements;
                   returntrue;
         }
         privatefunction setSqls(){
                   foreach($this->elements as $element) {
                            if(empty($element->getSql())){
                                     continue;
                            }
                            $this->sqls[]= $element->sql;
                   }
                   if(empty($this->sqls)){
                            returnfalse;
                   }
                   returntrue;
         }
         privatefunction run(){
                   //1.连接数据库
                   foreach($this->sqls as $sql) {
                            //2.执行sql
                   }
                   //3.断开数据库连接
         }
         publicfunction commit(array $elements){
                   if(empty($elements)){
                            returnfalse;
                   }
                   $res= $this->setElements($elements);
                   if(!$res){
                            returnfalse;
                   }
                   $res= $this->setSqls();
                   if(!$res){
                            returnfalse;
                   }                
                   $this->run();
         }
}
//4.客户端
$ea = new ElementTableA();
$ea->insert(array('col1'=>'a','col2'=>'b'));
$eb = new ElementTableA();
$eb->update(array('id'=>'xx','col1'=>'a', 'col2'=>'b'));
$uw = new UnitWork();
$uw->commit(array($ea, $eb));

——written by linhxx 2017.09.05

相关阅读:

设计模式专题(二十三) ——解释器模式

设计模式专题(二十二) ——享元模式

设计模式专题(二十一) ——中介者模式

设计模式专题(二十) ——职责链模式

设计模式专题(十九) ——命令模式

设计模式专题(十八) ——桥接模式

设计模式专题(十七) ——单例模式

设计模式专题(十六)——迭代器模式

设计模式专题(十五) ——组合模式

设计模式专题(十四)——适配器模式

设计模式专题(十三) ——备忘录模式

设计模式专题(十二)——状态模式

设计模式专题(十一)——抽象工厂模式

设计模式专题(十)——观察者模式

设计模式专题(九) ——外观模式

设计模式专题(八) ——模板方法模式

设计模式专题(七)——建造者模式

设计模式专题(六)——原型模式

设计模式专题(五)——工厂方法模式

设计模式专题(四)——代理模式

设计模式专题(三)——装饰模式

设计模式专题(二)——策略模式

设计模式专题(一)——面向对象的设计原则

原文发布于微信公众号 - 决胜机器学习(phpthinker)

原文发表时间:2017-09-05

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏進无尽的文章

设计模式| 创建型模式

GOF23种设计模式中创建型模式共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。

672
来自专栏云加新鲜事儿

腾讯云李海翔:数据库的并发控制技术深度探索

在2017第八届中国数据库技术大会(DTCC2017)上,腾讯云数据库专家工程师李海翔作为内核专场主持人和专家组成员,代表腾讯云进行了题为《数据库的并发控制技术...

4380
来自专栏性能与架构

系统高峰限流

限流是通过限制访问数量,防止系统压力过大而崩溃,是保障系统稳定性的一道屏障 例如网站计划做促销活动 活动前会预估访问量,然后进行压力测试和预演,如果现在的性能...

3345
来自专栏逸鹏说道

C#线程篇---线程池如何管理线程(6完结篇)

C#线程基础在前几篇博文中都介绍了,现在最后来挖掘一下线程池的管理机制,也算为这个线程基础做个完结。   我们现在都知道了,线程池线程分为工作者线程和I/O线程...

3496
来自专栏Java成长之路

mo9 2年java面试总结

mo9是一家做数字货币交易所的公司,在4月份的时候自己去mo9参加了java开发的面试。mo9的面试更加注重基础,问了很多java基础方面的知识。下面将面试的一...

792
来自专栏京东技术

多级缓存设计详解 | 给数据库减负,刻不容缓!

物流研发部架构师,GIS技术部负责人,2012年加入京东,多年一线团队大促备战经验,负责物流研发一些部门的架构工作,专注于低延迟系统设计与海量数据处理。曾负责青...

1315
来自专栏数据和云

表分区“拖出”的性能Error

作者介绍: 曾令军,云和恩墨技术专家,2009年开始接触ORACLE数据库,8年数据库运维经验。思维敏捷,擅长于数据库开发、解决棘手的数据库故障和性能问题。服务...

3107
来自专栏韩伟的专栏

经典的服务器结构概述(中)

. 经典的服务器结构概述(中) 今天将和大家详细探讨分服模型,本文结构如下: ? 1模型描述 分服模型是游戏服务器中最典型,也是历久最悠久的模型。其特征是游...

3157
来自专栏ImportSource

并发编程-多线程的好处

上一文:并发编程-并发的简史 如果线程使用得当,多线程可以降低你的开发和维护成本,而且还能改善复杂应用程序的性能。多线程让模仿人类工作方式以及交互变得简单,多线...

3376
来自专栏用户2442861的专栏

高性能网络编程6--reactor反应堆与定时器管理

反应堆开发模型被绝大多数高性能服务器所选择,上一篇所介绍的IO多路复用是它的实现基础。定时触发功能通常是服务器必备组件,反应堆模型往往还不得不将定时器的管理囊括...

641

扫码关注云+社区