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

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

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

一、概述

访问者模式(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 条评论
登录 后参与评论

相关文章

来自专栏北京马哥教育

Python with提前退出:坑与解决方案

? 问题的起源 早些时候使用with实现了一版全局进程锁,希望实现以下效果: ? 全局进程锁本身不用多说,大部分都依靠外部的缓存来实现的,redis上用的是s...

2975
来自专栏企鹅号快讯

Java后台编程初学者,这些常识你都知道吗?

Java编程中的一些常识,希望有心学习的可以多看一眼,如果你是高手欢迎指点文中小编的不足,感谢支持。以下这些编程常识均由小编结合个人水平以及搜寻相关资料整理编辑...

20210
来自专栏老马说编程

(67) 线程的基本协作机制 (上) / 计算机程序的思维逻辑

上节介绍了多线程之间竞争访问同一个资源的问题及解决方案synchronized,我们提到,多线程之间除了竞争,还经常需要相互协作,本节就来介绍Java中多线程协...

2116
来自专栏用户2442861的专栏

网易面试杂谈

http://blog.csdn.net/silangquan/article/details/18013967

842
来自专栏技术随笔

Bufbomb缓冲区溢出攻击实验详解-CSAPP

6528
来自专栏北京马哥教育

Python 函数库 APIs 编写指南

3184
来自专栏企鹅号快讯

《数据库系统概念》12-文件的组织

一个数据库被映射到多个不同的文件,这些文件由底层的操作系统来维护。每个文件分成定长的存储单元,称为块(bolck),块是存储分配和数据传输的基本单元。数据库默认...

2819
来自专栏wOw的Android小站

[设计模式]之十二:状态模式

在很多情况下,一个对象的行为取决于一个或多个动态变化的属性,这样的属性叫做状态,这样的对象叫做有状态的(stateful)对象,这样的对象状态是从事先定义好的一...

911
来自专栏精讲JAVA

Java 虚拟机 2 : Java 内存区域及对象

为以后写文章考虑,也为巩固自己的知识和一些基本概念,这里要理清楚几个计算机中的概念。

1232
来自专栏后端技术探索

PHP 使用协同程序实现合作多任务(二)

waitingForRead 及 waitingForWrite 属性是两个承载等待的socket 及等待它们的任务的数组。有趣的部分在于下面的方法,它将检查 ...

1211

扫码关注云+社区

领取腾讯云代金券