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

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

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

一、概述

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

相关文章

来自专栏精讲JAVA

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

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

1072
来自专栏企鹅号快讯

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

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

19410
来自专栏架构之路

wait方法和sleep方法的区别

一.概念、原理、区别 Java中的多线程是一种抢占式的机制而不是分时机制。线程主要有以下几种状态:可运行,运行,阻塞,死亡。抢占式机制指的是有多个线程处于可运...

3405
来自专栏xingoo, 一个梦想做发明家的程序员

【java开发系列】—— spring简单入门示例

回顾   1 JDK安装   2 Struts2简单入门示例 前言   作为入门级的记录帖,没有过多的技术含量,简单的搭建配置框架而已。这次讲到spring...

20410
来自专栏沈唁志

如何优化PHP性能呢?PHP性能优化总结

2053
来自专栏微信公众号:Java团长

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

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

1112
来自专栏Python小屋

Python选择结构注意事项

以百分制成绩转换为字母等级成绩为例,简单介绍一下Python选择结构需要注意的事项。

1373
来自专栏用户2442861的专栏

网易面试杂谈

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

612
来自专栏技术专栏

Scala入门与进阶(一)- 初始Scala

882
来自专栏技术随笔

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

5258

扫码关注云+社区