访问者模式

在不改变集合元素的前提下,为一个集合中的每个元素提供多种访问方式,即每个元素有多个访问者对象访问。

角色:

  • Visitor:抽象的访问者
  • ConcreteVistor:具体访问者
  • ObjectStructure:提供一个高层接口,允许访问者访问元素
  • Element:定义了accept方法,接收访问者对象
  • ConcreteElement:具体元素,实现accept方法
package com.strife.pattern.visitor;

import java.time.Period;
import java.util.LinkedList;
import java.util.List;

/**
 * 访问者模式
 * 测评
 * @author mengzhenghao
 * @date 2022/6/2
 */
public class Visitor {

    public static void main(String[] args) {
        //成功测评
        ObjectStructure successStructure = new ObjectStructure();
        successStructure.attach(new Man());
        successStructure.attach(new Man());
        successStructure.attach(new Man());
        successStructure.attach(new Woman());

        AbstractAction success = new Success();
        successStructure.display(success);

        //失败测评
        ObjectStructure failStructure = new ObjectStructure();
        AbstractAction fail = new Fail();
        failStructure.attach(new Man());
        failStructure.attach(new Woman());
        failStructure.display(fail);
    }
}

/** 抽象访问者:Visitor */
abstract class AbstractAction {

    /** 得到男性的测评结果 */
    public abstract void getManResult(Man man);

    /** 得到女性的测评结果 */
    public abstract void getWomanResult(Woman woman);

}

/** 具体访问者:ConcreteVistor */
class Success extends AbstractAction {

    @Override
    public void getManResult(Man man) {
        System.out.println("man success");
    }

    @Override
    public void getWomanResult(Woman woman) {
        System.out.println("woman success");
    }
}

/** 具体访问者:ConcreteVistor */
class Fail extends AbstractAction {

    @Override
    public void getManResult(Man man) {
        System.out.println("man fail");
    }

    @Override
    public void getWomanResult(Woman woman) {
        System.out.println("woman fail");
    }
}

/** 抽象元素:Element */
abstract class AbstractPerson {

    /** 定义accept方法 */
    public abstract void accept(AbstractAction visitor);
}

/**
 * 具体元素:ConcreteElement
 * 双分派
 * 首先在客户端将具体状态作为参数传入Man(第一次分派)
 * 然后Man类调用作为参数的 “具体方法” 中方法 getManResult ,同时将自己(this)作为参数传入(第二次分派)
 */
class Man extends AbstractPerson {

    @Override
    public void accept(AbstractAction visitor) {
        visitor.getManResult(this);
    }
}

/** 具体元素:ConcreteElement */
class Woman extends AbstractPerson {

    @Override
    public void accept(AbstractAction visitor) {
        visitor.getWomanResult(this);
    }
}

/** 数据结构(ObjectStructure):管理很多AbstractPerson */
class ObjectStructure {
    private List<AbstractPerson> people = new LinkedList<>();

    public void attach(AbstractPerson person) {
        people.add(person);
    }

    public void detach(AbstractPerson person) {
        people.remove(person);
    }

    /** 显示测评情况 */
    public void display(AbstractAction action) {
        for (AbstractPerson person : people) {
            person.accept(action);
        }
    }
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容