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

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

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

一、概述

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

相关文章

来自专栏一个会写诗的程序员的博客

Spring Reactor 项目核心库Reactor Core

Non-Blocking Reactive Streams Foundation for the JVM both implementing a Reactiv...

2182
来自专栏张善友的专栏

Miguel de Icaza 细说 Mix 07大会上的Silverlight和DLR

Mono之父Miguel de Icaza 详细报道微软Mix 07大会上的Silverlight和DLR ,上面还谈到了Mono and Silverligh...

2717
来自专栏我和未来有约会

Kit 3D 更新

Kit3D is a 3D graphics engine written for Microsoft Silverlight. Kit3D was inita...

2536
来自专栏张善友的专栏

Mix 10 上的asp.net mvc 2的相关Session

Beyond File | New Company: From Cheesy Sample to Social Platform Scott Hansel...

2577
来自专栏落花落雨不落叶

canvas画简单电路图

62011
来自专栏一个爱瞎折腾的程序猿

sqlserver使用存储过程跟踪SQL

USE [master] GO /****** Object: StoredProcedure [dbo].[sp_perfworkload_trace_s...

2070
来自专栏魂祭心

原 canvas绘制clock

4094
来自专栏张善友的专栏

LINQ via C# 系列文章

LINQ via C# Recently I am giving a series of talk on LINQ. the name “LINQ via C...

2645
来自专栏C#

DotNet加密方式解析--非对称加密

    新年新气象,也希望新年可以挣大钱。不管今年年底会不会跟去年一样,满怀抱负却又壮志未酬。(不过没事,我已为各位卜上一卦,卦象显示各位都能挣钱...)...

4888
来自专栏我和未来有约会

Silverlight第三方控件专题

这里我收集整理了目前网上silverlight第三方控件的专题,若果有所遗漏请告知我一下。 名称 简介 截图 telerik 商 RadC...

4025

扫码关注云+社区