设计模式-行为型-访问者模式(Visitor)

本文深入解析访问者模式的定义、角色、优缺点及适用场景,通过具体代码示例展示如何在实际项目中应用该模式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

定义

封装某些作用于某种数据结构中各元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作

角色

抽象访问者(Visitor):声明访问者可以访问哪些元素

访问者:它决定访问者访问到一个类后该干什么,要做什么事情

抽象元素类(Element):声明接受哪一类访问者访问;它一般分为两个逻辑,一个是本身的业务,另一个是允许接收哪类访问者访问

元素类:实现抽象元素类

结构对象(Object Structure):一个接口容器

优点

  • 符合单一职责原则:元素类封装在访问者中的操作一定是与元素本身关系不大且是易变的操作,当需求变化时, 不改变元素类本身,即可实现扩展
  • 扩展性良好:元素可以通过接受不同的访问者来实现对不同操作的扩展

缺点

  • 增加元素比较麻烦,每增加一个元素都要修改访问者类

适用场景

  • 一个对象中存在一些与该对象不相干或关系较弱的操作,可用访问者模式把这些操作封装到访问者中
  • 一些对象存在相似操作,为了避免出现大量重复的代码,也可以将重复操作封装到访问者中
  • 由于新增元素比较困难,因此访问者模式比较适合对已有功能的重构
  • 对象结构的类很少改变,但又经常需要在此结构上定义新的操作时

类图

Visitor

package com.vapy.behavior.Visitor;

/**
 * 
 * @author vapy
 * 
 */
public abstract class Element {
    public abstract void accept(IVisitor visitor);
    public abstract void doSomething();
}
package com.vapy.behavior.Visitor;

/**
 * 
 * @author vapy
 * 
 */
public class Dancer extends Element {
    @Override
    public void accept(IVisitor visitor) {
        visitor.visit(this);
    }

    @Override
    public void doSomething() {
        System.out.println("dance");
    }
}
package com.vapy.behavior.Visitor;

/**
 * 
 * @author vapy
 * 
 */
public class Singer extends Element {
    @Override
    public void accept(IVisitor visitor) {
        visitor.visit(this);
    }

    @Override
    public void doSomething() {
        System.out.println("sing");
    }

}
package com.vapy.behavior.Visitor;

/**
 * 
 * @author vapy
 * 
 */
public interface IVisitor {
    public void visit(Dancer dancer);
    public void visit(Singer singer);
}
package com.vapy.behavior.Visitor;

/**
 * 
 * @author vapy
 * 
 */
public class Visitor implements IVisitor {
    @Override
    public void visit(Dancer dancer) {
        dancer.doSomething();
    }

    @Override
    public void visit(Singer singer) {
        singer.doSomething();
    }
}
package com.vapy.behavior.Visitor;

/**
 * 
 * @author vapy
 * 
 */
import java.util.ArrayList;
import java.util.List;

public class ObjectStruture {
    public static List<Element> getList() {
        List<Element> list = new ArrayList<Element>();
        list.add(new Dancer());
        list.add(new Dancer());
        list.add(new Dancer());
        list.add(new Singer());
        return list;
    }
}
package com.vapy.behavior.Visitor;

/**
 * 
 * @author vapy
 * 
 */
import java.util.List;

public class Client {
    public static void main(String[] args) {
        List<Element> list = ObjectStruture.getList();
        IVisitor visitor = new Visitor();
        for(Element e : list) {
            e.accept(visitor);
        }
    }
}

VisitorResult
本文代码可在github查看:点击此处

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值