访问者模式

访问者模式

访问者模式:封装一些作用于某种数据结构中的各元素的操作,它可以在不改变数据结构的前提下定义作用与这些元素的新的操作。可以遍历不同的对象。
角色:1.Visitor抽象访问者:声明访问者可以访问哪些元素。
2.ConcreteVisitor具体访问者:访问者访问到一个类后应该做什么。
3.Element抽象元素:声明接受哪一类访问者访问,程序上是通过accept方法中的参数来定义的。
4.ConcreteElement具体元素:实现accept方法,通常是visitor.visit(this)。
5.ObjectStruture结构对象:元素产生者,很少抽象出这个角色。
适用场景:需要对一个对象结构中的对象进行很多不同并且不想关的操作。
具体实现:

通用实现

1.创建抽象元素

/**
 * 抽象元素
 */
public abstract class Element {
    //每个元素都有一个成绩和姓名
    private int grade = 0;
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getGrade() {
        return grade;
    }

    public void setGrade(int grade) {
        this.grade = grade;
    }
    //我允许一个访问者访问我
    public abstract void accept(IVisitor visitor);
}

2.创建具体元素1和2.各自属性有细微不同

/**
 * 具体访问者1
 * 访问者1存在money属性
 */
public class ConcreteElement1 extends Element {
    private int money = 0;

    public int getMoney() {
        return money;
    }

    public void setMoney(int money) {
        this.money = money;
    }

    @Override
    public void accept(IVisitor visitor) {
        visitor.visit(this);
    }
}
 	/**
 * 具体元素2
 * 具体元素2有职位属性
 */
public class ConcreteElement2 extends Element {
    private String position = "";

    public String getPosition() {
        return position;
    }

    public void setPosition(String position) {
        this.position = position;
    }

    @Override
    public void accept(IVisitor visitor) {
            visitor.visit(this);
    }
}

3.创建访问者接口

/**
 * 访问者接口
 */
public interface IVisitor {
    //可以访问哪些对象
    public void visit(ConcreteElement1 concreteElement1);
    public void visit(ConcreteElement2 concreteElement2);
}

4.创建具体访问者

/**
 * 具体访问者
 */
public class Visitor implements  IVisitor {
    @Override
    public void visit(ConcreteElement1 concreteElement1) {
        System.out.println(this.getConcreteElement1Info(concreteElement1));
    }

    @Override
    public void visit(ConcreteElement2 concreteElement2) {
        System.out.println(this.getConcreteElement2Info(concreteElement2));
    }

    public String getConcreteElement1Info(ConcreteElement1 concreteElement1){
        String info = "姓名:"+concreteElement1.getName();
        info+=" 成绩:"+concreteElement1.getGrade();
        info+=" 钱:"+concreteElement1.getMoney();
        return info;
    }
    public String getConcreteElement2Info(ConcreteElement2 concreteElement2){
        String info = "姓名:"+concreteElement2.getName();
        info+=" 成绩:"+concreteElement2.getGrade();
        info+=" 职位:"+concreteElement2.getPosition();
        return info;
    }
}

5.创建场景测试类

/**
 * 场景测试类
 */
public class Client {

    public static void main(String[] args) {
        IVisitor visitor = new Visitor();
        for (Element e:
             getMock()) {
            e.accept(visitor);
        }
    }

    //生产几个元素模拟
    public static List<Element> getMock(){
        ConcreteElement1 zhangshan = new ConcreteElement1();
        zhangshan.setMoney(1000);
        zhangshan.setName("张三");
        zhangshan.setGrade(79);
        ConcreteElement1 lisi = new ConcreteElement1();
        lisi.setMoney(2356);
        lisi.setName("李思");
        lisi.setGrade(84);

        ConcreteElement2 wangwu = new ConcreteElement2();
        wangwu.setPosition("经理");
        wangwu.setName("王五");
        wangwu.setGrade(99);

        List<Element> list = new ArrayList<>();
        list.add(zhangshan);
        list.add(lisi);
        list.add(wangwu);
        return list;
    }
}
统计功能(统计成绩之和,元素1的成绩乘5,元素2的成绩乘10)

1.修改访问者接口

/**
 * 访问者接口
 */
public interface IVisitor {
    //可以访问哪些对象
    public void visit(ConcreteElement1 concreteElement1);
    public void visit(ConcreteElement2 concreteElement2);
    //获取总成绩之和
    public int getTotalGrade();
}

2.修改访问者实现类

/**
 * 具体访问者
 */
public class Visitor implements  IVisitor {
    //元素一的成绩之和
    private int allGrade1 = 0;
    //元素二的成绩之和
    private int allGrade2 = 0;
    @Override
    public void visit(ConcreteElement1 concreteElement1) {
        this.AddGrade1(concreteElement1.getGrade());
        System.out.println(this.getConcreteElement1Info(concreteElement1));
    }

    @Override
    public void visit(ConcreteElement2 concreteElement2) {
        this.AddGrade2(concreteElement2.getGrade());
        System.out.println(this.getConcreteElement2Info(concreteElement2));
    }

    //获取元素一的信息
    public String getConcreteElement1Info(ConcreteElement1 concreteElement1){
        String info = "姓名:"+concreteElement1.getName();
        info+=" 成绩:"+concreteElement1.getGrade();
        info+=" 钱:"+concreteElement1.getMoney();
        return info;
    }
    //获取元素二的信息
    public String getConcreteElement2Info(ConcreteElement2 concreteElement2){
        String info = "姓名:"+concreteElement2.getName();
        info+=" 成绩:"+concreteElement2.getGrade();
        info+=" 职位:"+concreteElement2.getPosition();
        return info;
    }

    //获得元素一的成绩之和
    private void AddGrade1(int grade){
        this.allGrade1+=grade*5;
    }
    //获得元素二的成绩之和
    private void AddGrade2(int grade){
        this.allGrade2+=grade*10;
    }

    @Override
    public int getTotalGrade() {
        return this.allGrade1+this.allGrade2;
    }
}

3.修改场景测试类

/**
 * 场景测试类
 */
public class Client {

    public static void main(String[] args) {
        IVisitor visitor = new Visitor();
        for (Element e:
             getMock()) {
            e.accept(visitor);
        }
        System.out.println("总成绩为:"+visitor.getTotalGrade());
    }

    //生产几个元素模拟
    public static List<Element> getMock(){
        ConcreteElement1 zhangshan = new ConcreteElement1();
        zhangshan.setMoney(1000);
        zhangshan.setName("张三");
        zhangshan.setGrade(79);
        ConcreteElement1 lisi = new ConcreteElement1();
        lisi.setMoney(2356);
        lisi.setName("李思");
        lisi.setGrade(84);

        ConcreteElement2 wangwu = new ConcreteElement2();
        wangwu.setPosition("经理");
        wangwu.setName("王五");
        wangwu.setGrade(99);

        List<Element> list = new ArrayList<>();
        list.add(zhangshan);
        list.add(lisi);
        list.add(wangwu);
        return list;
    }
}
多个访问者

1.修改访问者接口

/**
 * 访问者接口
 */
public interface IVisitor {
    //可以访问哪些对象
    public void visit(ConcreteElement1 concreteElement1);
    public void visit(ConcreteElement2 concreteElement2);
}

2.添加二号访问者,二号访问者进行统计成绩

/**
 * 具体访问者2
 * 统计总成绩
 */
public class Visitor2 implements IVisitor {
    //元素一的成绩之和
    private int allGrade1 = 0;
    //元素二的成绩之和
    private int allGrade2 = 0;
    @Override
    public void visit(ConcreteElement1 concreteElement1) {
        this.AddGrade1(concreteElement1.getGrade());
    }

    @Override
    public void visit(ConcreteElement2 concreteElement2) {
        this.AddGrade2(concreteElement2.getGrade());
    }
    //获得元素一的成绩之和
    private void AddGrade1(int grade){
        this.allGrade1+=grade*5;
    }
    //获得元素二的成绩之和
    private void AddGrade2(int grade){
        this.allGrade2+=grade*10;
    }
    //获得总成绩
    public int getTotalGrade() {
        return this.allGrade1+this.allGrade2;
    }
}

3.修改一号访问者,一号访问者只展示基础数据

/**
 * 具体访问者1
 * 只展示基础信息
 */
public class Visitor implements  IVisitor {

    @Override
    public void visit(ConcreteElement1 concreteElement1) {
        System.out.println(this.getConcreteElement1Info(concreteElement1));
    }

    @Override
    public void visit(ConcreteElement2 concreteElement2) {
        System.out.println(this.getConcreteElement2Info(concreteElement2));
    }

    //获取元素一的信息
    public String getConcreteElement1Info(ConcreteElement1 concreteElement1){
        String info = "姓名:"+concreteElement1.getName();
        info+=" 成绩:"+concreteElement1.getGrade();
        info+=" 钱:"+concreteElement1.getMoney();
        return info;
    }
    //获取元素二的信息
    public String getConcreteElement2Info(ConcreteElement2 concreteElement2){
        String info = "姓名:"+concreteElement2.getName();
        info+=" 成绩:"+concreteElement2.getGrade();
        info+=" 职位:"+concreteElement2.getPosition();
        return info;
    }


}

4.修改场景测试类

/**
 * 场景测试类
 */
public class Client {

    public static void main(String[] args) {
        Visitor visitor = new Visitor();
        Visitor2 visitor2 = new Visitor2();
        for (Element e:
             getMock()) {
            e.accept(visitor);   //接受一号访问者访问
            e.accept(visitor2);  //接受二号访问者访问
        }
        System.out.println("总成绩为:"+visitor2.getTotalGrade());
    }

    //生产几个元素模拟
    public static List<Element> getMock(){
        ConcreteElement1 zhangshan = new ConcreteElement1();
        zhangshan.setMoney(1000);
        zhangshan.setName("张三");
        zhangshan.setGrade(79);
        ConcreteElement1 lisi = new ConcreteElement1();
        lisi.setMoney(2356);
        lisi.setName("李思");
        lisi.setGrade(84);

        ConcreteElement2 wangwu = new ConcreteElement2();
        wangwu.setPosition("经理");
        wangwu.setName("王五");
        wangwu.setGrade(99);

        List<Element> list = new ArrayList<>();
        list.add(zhangshan);
        list.add(lisi);
        list.add(wangwu);
        return list;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值