设计模式——访问者模式

  访问者模式是对象的行为模式。访问者模式的目的是封装一些施加于某种数据结构元素之上的操作。一旦这些操作需要修改的话,接受这个操作的数据结构则可以保持不变。

主要角色

  抽象访问者:抽象类或者接口,声明访问者可以访问哪些元素,具体到程序中就是visit方法中的参数定义哪些对象是可以被访问的。
  访问者:实现抽象访问者所声明的方法,它影响到访问者访问到一个类后该干什么,要做什么事情。
  抽象元素类:接口或者抽象类,声明接受哪一类访问者访问,程序上是通过accept方法中的参数来定义的。抽象元素一般有两类方法,一部分是本身的业务逻辑,另外就是允许接收哪类访问者来访问。
  元素类:实现抽象元素类所声明的accept方法,通常都是visitor.visit(this),基本上已经形成一种定式了。
  结构对象:一个元素的容器,一般包含一个容纳多个不同类、不同接口的容器,如List、Set、Map等,在项目中一般很少抽象出这个角色。

适用性

  1、一个对象结构内部包含很多实现了不同接口的类对象,你想对这些对象执行依赖于其具体类的操作。
  2、需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而你想避免让这些操作“污染”这些对象的类。访问者模式使得你可以将相关的操作集中起来定义在一个类中,当该对象结构被很多应用共享时,用访问者模式让每个应用仅包含需要用到的操作。
  3、定义对象结构的类很少改变,但经常需要在此结构上定义新的操作。改变对象结构类需要重定义对所有访问者的接口,这可能需要很大的代价。如果对象结构类经常改变,那么可能还是在这些类中定义这些操作较好。

优点

  1、访问者模式使得增加新的操作变得很容易。如果一些操作依赖于一个复杂的结构对象的话,那么一般而言,增加新的操作会很复杂。而使用访问者模式,增加新的操作就意味着增加一个新的

  2、访问者类,因此,变得很容易。
  3、访问者模式将有关的行为集中到一个访问者对象中,而不是分散到一个个的节点类中。
  4、访问者模式可以跨过几个类的等级结构访问属于不同的等级结构的成员类。迭代子只能访问属于同一个类型等级结构的成员对象,而不能访问属于不同等级结构的对象。访问者模式可以做到这一点。
  5、积累状态。每一个单独的访问者对象都集中了相关的行为,从而也就可以在访问的过程中将执行操作的状态积累在自己内部,而不是分散到很多的节点对象中。这是有益于系统维护的优点。

缺点

  1、增加新的节点类变得很困难。每增加一个新的节点都意味着要在抽象访问者角色中增加一个新的抽象操作,并在每一个具体访问者类中增加相应的具体操作。
  2、破坏封装。访问者模式要求访问者对象访问并调用每一个节点对象的操作,这隐含了一个对所有节点对象的要求:它们必须暴露一些自己的操作和内部状态。不然,访问者的访问就变得没有意义。由于访问者对象自己会积累访问操作所需的状态,从而使这些状态不再存储在节点对象中,这也是破坏封装的。

实现

  网上的资料中汽车的例子,实现访问者模式的一个小例子。类图如下:

IPart(被访问者的抽象定义)的定义:

package com.lidaming.design20.visitor;

public interface IPart {
    void accept(IWorker worker);
}

Engine(具体被访问者)的实现:

package com.lidaming.design20.visitor;

public class Engine implements IPart {

    public void accept(IWorker worker) {
        worker.visit(this);
    }

}

Wheel实现:

package com.lidaming.design20.visitor;

public class Wheel implements IPart {

    public void accept(IWorker worker) {
        worker.visit(this);
    }

}

Car的实现:

package com.lidaming.design20.visitor;

public class Car implements IPart {

    private Engine engine = new Engine();
    private Wheel wheel = new Wheel();

    public void accept(IWorker worker) {
        wheel.accept(worker);
        engine.accept(worker);
        worker.visit(this);
    }

}

IWorker(访问者的抽象)的定义:

package com.lidaming.design20.visitor;

public interface IWorker {
    void visit(Engine e);

    void visit(Wheel e);

    void visit(Car e);
}

Engineer(具体访问者)的实现:

package com.lidaming.design20.visitor;

public class Engineer implements IWorker {

    public void visit(Engine e) {
        System.out.println("check engine...");
    }

    public void visit(Wheel e) {
        System.out.println("check wheel...");
    }

    public void visit(Car e) {
        System.out.println("check car ...");
    }

}

场景类的实现:

package com.lidaming.design20.visitor;

public class Client {

    public static void main(String[] args) {
        Engineer engineer = new Engineer();
        Car car = new Car();
        car.accept(engineer);
    }

}

延伸

  仔细阅读会发现,代码中存在相互引用(环引用),会产生无效依赖,甚至OOM,要解决这个问题,就要具体实现不同的Engineer,在Car中进行组合,只对抽象操作。

参考
http://www.cnblogs.com/qicosmos/p/3357178.html
http://www.cnblogs.com/java-my-life/archive/2012/06/14/2545381.html
http://www.cnblogs.com/singlepine/archive/2005/10/30/265025.html

时间: 2024-10-31 18:57:06

设计模式——访问者模式的相关文章

.NET设计模式访问者模式

一.访问者模式的定义: 表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作. 二.访问者模式的结构和角色: 1.Visitor 抽象访问者角色,为该对象结构中具体元素角色声明一个访问操作接口.该操作接口的名字和参数标识了发送访问请求给具体访问者的具体元素角色,这样访问者就可以通过该元素角色的特定接口直接访问它.2.ConcreteVisitor.具体访问者角色,实现Visitor声明的接口.3.Element 定义一个接受访问操作(accept

[我的设计模式] 访问者模式

访问者模式(Visitor Pattern)是GoF提出的23种设计模式中的一种,属于行为模式. 定义(源于GoF<Design Pattern>):表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作. 从定义可以看出结构对象是使用访问者模式必备条件,而且这个结构对象必须存在遍历自身各个对象的方法. 应用场景 用户访问博客.[我的设计模式] 访问者模式

【C#设计模式-访问者模式】

一.访问者模式的定义: 表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作. 二.访问者模式的结构和角色: 1.Visitor 抽象访问者角色,为该对象结构中具体元素角色声明一个访问操作接口.该操作接口的名字和参数标识了发送访问请求给具体访问者的具体元素角色,这样访问者就可以通过该元素角色的特定接口直接访问它. 2.ConcreteVisitor.具体访问者角色,实现Visitor声明的接口. 3.Element 定义一个接受访问操作(acce

最复杂的设计模式---访问者模式

今天,我们一起来探讨最后一个.最复杂的设计模式 访问者模式:它表示一个作用于某个对象结构中的各个元素的操作.它使你可以在不改变个元素的类前提下,定义作用于这些元素的新操作.这个地方要注意:1.需要有个对象结构类用于存储循环遍历的方法的方式:2.访问者模式是对元素的操作:3.可以任意添加对这些元素的新操作.确实有点复杂,我们先看看其结构图: 代码部分: Visitor类抽象声明了对各种类型元素的访问方法: abstract class Visitor { public abstract void

C#设计模式-访问者模式

一.访问者模式介绍 1.1 访问者模式的定义 表示一个作用于某对象结构中的各个元素的操作.它使你可以在不改变各个元素的类的前提下定义作用于这些元素的新操作. 1.2 访问者模式的结构图 具体的访问者模式结构图如下所示. 这里需要明确一点:访问者模式中具体访问者的数目和具体节点的数目没有任何关系.从访问者的结构图可以看出,访问者模式涉及以下几类角色. 抽象访问者角色(Vistor):声明一个活多个访问操作,使得所有具体访问者必须实现的接口. 具体访问者角色(ConcreteVistor):实现抽象

小菜学设计模式——访问者模式

背景 最后一个设计模式,也是<大话设计模式>公认最难的设计模式,当然不是理解上困难,我觉得应该是使用上困难,这个设计模式虽然具有非常良好的扩展能力,但却需要类的结构早早定义清晰,试想,需求时刻变化,你的类可以稳定吗? 1.使用意图 容易扩展,满足开发封闭原则 2.生活实例 男人和女人的状态,把ConcreteElmentA看成男人,把ConcreteElementB看成女人,那么,所有的Visitor实例就是成功状态.失败状态.结婚状态.升职状态等.把这些状态放在客户端的集合中维护,一旦需要,

PHP设计模式——访问者模式

声明:本系列博客参考资料<大话设计模式>,作者程杰. 访问者模式表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作. UML类图: 角色: 1.抽象访问者(State):为该对象结构中具体元素角色声明一个访问操作接口.该操作接口的名字和参数标识了发送访问请求给具体访问者的具体元素角色,这样访问者就可以通过该元素角色的特定接口直接访问它. 2.具体访问者(Success):实现访问者声明的接口. 3.抽象元素(Person):定义一个接受访问操

深入浅出设计模式——访问者模式(Visitor Pattern)

模式动机 对于系统中的某些对象,它们存储在同一个集合中,且具有不同的类型,而且对于该集合中的对象,可以接受一类称为访问者的对象来访问,而且不同的访问者其访问方式有所不同,访问者模式为解决这类问题而诞生.在实际使用时,对同一集合对象的操作并不是唯一的,对相同的元素对象可能存在多种不同的操作方式.而且这些操作方式并不稳定,可能还需要增加新的操作,以满足新的业务需求.此时,访问者模式就是一个值得考虑的解决方案.访问者模式的目的是封装一些施加于某种数据结构元素之上的操作,一旦这些操作需要修改的话,接受这

iOS设计模式---访问者模式

一个简单的Car模型,含有1台Engine.4个Wheel,使用访问者模式添加对Car的升级与维修操作. 定义Engine类: // //  NimoEngine.h //  VisitorDemo // //  Created by fu zheng on 15/8/12. //  Copyright (c) 2015年 FuZheng. All rights reserved. // #import <Foundation/Foundation.h> #import "NimoC

C++设计模式——访问者模式

访问者模式 在GOF的<设计模式:可复用面向对象软件的基础>一书中对访问者模式是这样说的:表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作.访问者模式把数据结构和作用于结构上的操作之间的耦合解脱开,使得操作集合可以相对自由地演化.该模式的目的是要把处理从数据结构分离出来.访问者模式让增加新的操作很容易,因为增加新的操作就意味着增加一个新的访问者.访问者模式将有关的行为集中到一个访问者对象中.现在再来说说我之前经历过的那个项目. 是基于Wi