`

设计模式之 Visitor - 访问者模式

阅读更多

Visitor模式也叫访问者模式,是由GoF提出的23种软件设计模式的一种。Visitor模式是行为模式之一,它分离对象的数据和行为,使用Visitor模式,可以不修改已有类的情况下,增加新的操作。


本文介绍设计模式中的(Visitor)模式的概念,用法,以及实际应用中怎么样使用Visitor模式进行开发。
Visitor模式的概念
Visitor模式是一种分离对象数据结构与行为的方法,通过这种分离,可以为一个已存在的类或类群增加新的操作而无需为它们作任何修改。
Visitor模式UML类图

Visitor
    访问者抽象接口,通过visit(Element)方法访问Element(数据结构),完成对Element的操作行为。
ConcreteVisitor
    访问者的具体实现类。
ObjectStructure
    复合对象。包括所有需要被访问的数据结构对象(Element)。ObjectStructure本身也可以作为被访问者。
Element
    元素,也就是被访问者。通过accept(Visitor)方法接受Visitor的访问。
ConcreteElement
    Element的具体实现类。

Visitor模式的应用场景
我们举例来说明Visitor模式的应用场景。
比如有一个公园,有一到多个不同的组成部分;
该公园存在多个访问者:清洁工A负责打扫公园的A部分,清洁工B负责打扫公园的B部分,公园的管理者负责检点各项事务是否完成,上级领导可以视察公园等等。

也就是说,对于同一个公园,不同的访问者有不同的行为操作,而且访问者的种类也可能需要根据时间的推移而变化(行为的扩展性)。
根据软件设计的开闭原则(对修改关闭,对扩展开放),我们怎么样实现这种需求呢?
在这个例子中,如果我们在公园类里实现所有的访问者行为,势必造成以下问题:
1,由于所有的访问者的行为各不一样,在一个类中实现所有访问者行为,会造成该类功能过多,代码冗长。
2,不利于扩展。每增加一个访问者,就需要在已有的类里为其实现一个新的行为,就是说不得不修改已有的类,显然不符合软件设计开闭原则。

Visitor模式便可以解决这类问题。

当一个应用满足以下条件时,我们可以使用Visitor设计模式:
- 一个对象可能存在一到多个数据元素
- 存在多种行为,分别对不同的数据元素或数据的全体进行处理
- 行为的不确定性或者说行为的扩展性


Visitor模式的优点
上面已经提到过Visitor模式的优点:
- 分离对象的数据结构与行为,让不同的类完成不同的功能
- 可以不修改已有类的基础上增加新的操作行为
- 从另一个角度来看,同一个数据结构,为其实现不同的观察者,便可呈现不同的行为。

Visitor模式的实现步骤:
1,定义具有继承关系的数据结构对象群(相当于Element与ConcreteElement角色),并定义accept(Visitor)方法接受Visitor访问
2,定义包含上述数据结构对象群的复合结构对象(相当于ObjectStructure角色)
3,定义Visitor抽象接口,定义所有访问行为方法(相当于Visitor角色)
4,定义具体的访问者对象,并实现所有visit方法(相当于ConcreteVisitor角色)


Visitor模式的应用范例

文件一览:
Client
    测试类。
Visitable
    相当于Element角色。
Park
    公园类,包含ParkPartA与ParkPartB部分。相当于ObjectStructure以及ConcreteElement角色。
ParkPartA
    公园的ParkPartA部分。相当于ConcreteElement角色。
ParkPartB
    公园的ParkPartB部分。相当于ConcreteElement角色。
Visitor
    访问者抽象接口。相当于Visitor角色。
VisitorCleanerA
    负责打扫ParkPartA部分的清洁工类。相当于ConcreteVisitor角色。
VisitorCleanerB
    负责打扫ParkPartA部分的清洁工类。相当于ConcreteVisitor角色。
VisitorManager
    公园的管理人员类。相当于ConcreteVisitor角色。

代码:
public class Client {

    /**
     * Test Visitor Pattern
     *
     */

    public static void main(String[] args) {
        //创建复合对象(公园对象)
        Park park = new Park("Park");
        
        //创建打扫A部分的清洁工访问者
        System.out.println("---Visitor: CleanerA---");
        Visitor visitorCleanerA = new VisitorCleanerA();
        park.accept(visitorCleanerA);
        
        //创建打扫B部分的清洁工访问者
        System.out.println("---Visitor: CleanerB---");
        Visitor visitorCleanerB = new VisitorCleanerB();
        park.accept(visitorCleanerB);
        
        //创建管理公园的管理人访问者
        System.out.println("---Visitor: Manager---");
        Visitor visitorManager = new VisitorManager();
        park.accept(visitorManager);
        
    }
}

/**
* Visitor Role
*
*/

interface Visitor {
    void visit(Park park);
    void visit(ParkPartA parkPartA);
    void visit(ParkPartB parkPartB);
}

/**
* ConcreteVisitor
* 负责打扫ParkPartA部分的清洁工类
*
*/

class VisitorCleanerA implements Visitor {

    public void visit(Park park) {}

    public void visit(ParkPartA parkPartA) {
        System.out.println("Clean " + parkPartA.name);
    }

    public void visit(ParkPartB parkPartB) {}
}

/**
* ConcreteVisitor
* 负责打扫ParkPartB部分的清洁工类
*
*/

class VisitorCleanerB implements Visitor {

    public void visit(Park park) {}

    public void visit(ParkPartA parkPartA) {}

    public void visit(ParkPartB parkPartB) {
        System.out.println("Clean " + parkPartB.name);                
    }
}

/**
* ConcreteVisitor
* 公园的管理人员类
*
*/

class VisitorManager implements Visitor {

    public void visit(Park park) {
        System.out.println("Check " + park.name);
    }

    public void visit(ParkPartA parkPartA) {
        System.out.println("Check " + parkPartA.name);
    }

    public void visit(ParkPartB parkPartB) {
        System.out.println("Check " + parkPartB.name);
    }
}


/**
* Element Role
*
*/

interface Visitable {
    void accept(Visitor visitor);
}

/**
* ObjectStructure & ConcreteElement Role
* 公园类,包含ParkPartA与ParkPartB部分
*
*/

class Park implements Visitable {
    String name;
    ParkPartA parkPartA = new ParkPartA("ParkPartA");
    ParkPartB parkPartB = new ParkPartB("ParkPartB");;
    
    public Park(String name) {
        this.name = name;
    }

    public void accept(Visitor visitor) {
        visitor.visit(this);
        
        parkPartA.accept(visitor);
        parkPartB.accept(visitor);
    }
}

/**
* ConcreteElement Role
* 公园的一部分ParkPartA
*
*/

class ParkPartA implements Visitable {
    String name;
    
    public ParkPartA(String name) {
        this.name = name;
    }
    
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}

/**
* ConcreteElement Role
* 公园的一部分ParkPartB
*
*/

class ParkPartB implements Visitable {
    String name;
    
    public ParkPartB(String name) {
        this.name = name;
    }
    
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}



执行Client,输出结果:
C:\Visitor>javac *.java
C:\Visitor>java Client
---Visitor: CleanerA---
Clean ParkA
---Visitor: CleanerB---
Clean ParkB
---Visitor: Manager---
Check Park
Check ParkA
Check ParkB
C:\Visitor>
不同的访问者执行不同的行为,而且行为与数据本身完全分开了。当需要新增加一个访问者时,只需要创建一个实现Visitor接口的新类就可以了。
分享到:
评论

相关推荐

    设计模式C++学习之访问者模式(Visitor)

    访问者模式(Visitor)是一种行为设计模式,它允许在不修改对象结构的前提下向对象结构中的元素添加新的操作。这种模式将算法与数据结构分离,使得算法可以独立于数据结构进行变化,增强了系统的可扩展性。 在C++中...

    设计模式之访问者模式(Visitor)

    访问者模式是一种行为设计模式,它使你可以在不修改对象结构的情况下,为对象添加新的操作。这种模式的核心在于将数据结构与对这些数据的操作解耦,使得增加新的操作变得容易,同时也允许独立地改变元素类和访问者类...

    设计模式-访问者模式(Visitor)

    访问者模式(Visitor)是一种行为设计模式,它允许在不修改对象结构的前提下向对象结构中的元素添加新的操作。这种模式的核心思想是分离了算法和对象结构,使得算法可以在不改变对象结构的情况下独立变化。 访问者...

    设计模式-访问者(Visitor)模式详解和应用.pdf

    ### 设计模式-访问者(Visitor)模式详解和应用 #### 一、访问者模式简介 访问者模式(Visitor Pattern)是一种行为型设计模式,它允许我们向一组已存在的类添加新的行为,而无需修改这些类。这种模式的核心思想是在...

    设计模式精解-GoF-23种设计模式解析--附C++源代码

    - 访问者模式(Visitor):表示一个作用于某对象结构中的各元素的操作,它可以在不改变各元素的类的前提下定义作用于这些元素的新操作。 在C++中,这些设计模式通常通过面向对象的特性,如继承、封装和多态来实现...

    c++设计模式-行为型模式-访问者模式

    c++设计模式-行为型模式-访问者模式;qt工程;c++简单源码; 访问者(Visitor)模式的定义:将作用于某种数据结构中的各元素的操作分离出来封装成独立的类,使其在不改变数据结构的前提下可以添加作用于这些元素的新...

    设计模式系列之visitor

    "设计模式系列之visitor"是一个关于软件设计模式的讨论,特别是关注于“访问者”(Visitor)模式。这个模式是GOF(Gamma, Helm, Johnson, Vlissides)在他们的经典著作《设计模式:可复用面向对象软件的基础》中提出...

    设计模式 - 访问者模式

    访问者模式(Visitor Pattern)是一种行为设计模式,它使你能在不修改对象结构的前提下向其添加新的操作。这种模式常用于处理具有相同接口或抽象类的对象结构,使得可以在不改变原有结构的基础上增加功能,实现对...

    设计模式之访问者模式(Visitor Pattern)

    **访问者模式(Visitor Pattern)**是一种行为设计模式,它提供了一种在不修改对象结构的情况下增加新操作的方法。这种模式的主要思想是将数据结构与算法分离,使得算法可以在不改变对象结构的情况下独立变化。 在...

    软件设计与体系结构-设计模式-访问者模式-ppt制作

    访问者模式(Visitor Pattern)是软件工程领域中一种重要的设计模式,主要用于处理数据结构中元素的操作问题。该模式的核心思想在于将数据操作与数据结构本身相分离,通过这种方式,可以在不改变数据结构的前提下...

    C#面向对象设计模式纵横谈(24):(行为型模式) Visitor 访问者模式

    ### C#面向对象设计模式纵横谈(24):(行为型模式) Visitor 访问者模式 #### 概述 在本篇文章中,我们将深入探讨面向对象设计模式中的一个非常重要的模式——**Visitor(访问者)模式**。此模式属于行为型模式的一...

    设计模式-访问者模式(讲解及其实现代码)

    访问者模式是一种行为设计模式,它允许在不修改对象结构的情况下向对象添加新的操作。这种模式的核心思想是将数据结构与算法分离,使得算法可以在不改变对象结构的前提下增加对对象的操作。 在软件开发中,有时我们...

    java设计模式---诙谐易懂版

    代理模式(Proxy Pattern)、单例模式(Singleton Pattern)、工厂方法...访问者模式(Visitor Pattern)、状态模式(State Pattern)、原型模式(Prototype Pattern)、中介者模式(Mediator Pattern)、解释器模式...

    java常用设计模式-访问者模式

    访问者模式(Visitor Pattern)是 Java 中的一种行为型设计模式,它允许开发者在不修改对象结构的前提下定义新的操作。这种模式将对象结构和操作分离开来,使得操作可以独立地应用于对象结构中的元素。 在访问者...

    设计模式之访问者模式

    访问者模式是一种软件设计模式,它在对象结构中定义了一个访问者的接口,使得该访问者可以访问该结构中的每一个元素,同时不影响这些元素自身的行为。这种模式的主要目的是将数据操作和业务逻辑分离,使得数据结构...

    基于visitor模式和访问者模式的表达式树_求值引擎

    2. **访问者模式**:这是与Visitor模式相关的另一种设计模式,但在这里,我们可能是指在表达式树的节点上应用访问者模式。访问者模式使得可以在不修改节点类的情况下,增加对节点的新功能。在本项目中,可能是通过在...

    C#设计模式之Visitor

    **C#设计模式之Visitor** **一、设计模式概述** 设计模式是软件开发中的经验总结,它提供了解决常见问题的可复用解决方案。在C#编程中,设计模式可以帮助我们编写更灵活、可扩展和易于维护的代码。"Visitor"(访问...

    C++设计模式--基于Qt4开源跨平台开发框架

    行为型模式如观察者模式(Observer)、策略模式(Strategy)和访问者模式(Visitor),关注对象之间的交互和责任分配。 在C++中,设计模式的应用通常涉及到面向对象编程的特性,如继承、封装和多态。Qt4框架则为...

    (行为型模式) Visitor 访问者模式

    C#面向对象设计模式 (行为型模式) Visitor 访问者模式 视频讲座下载

Global site tag (gtag.js) - Google Analytics