Java描绘规划方法(23):访问者方法

本文源码:GitHub·点这儿 || GitEE·点这儿

一、日子场景

1、场景描绘

电竞是游戏竞赛抵达“竞技”层面的体育项目。运用电子设备作为运动器械进行的、人与人之间的智力仇视运动。通过电竞,能大大的提高人的反响才华、谐和才华、团队精神等。可是不同人群的对电竞的持有的观念不一样,有的人以为电竞便是沉溺网络,持仇视心情,而有的人就比较附和。下面根据拜访者办法来描绘该场景。

2、场景图解

Java描绘规划方法(23):访问者方法

3、代码结束

public class C01_InScene {
public static void main(String[] args) {
DataSet dataSet = new DataSet() ;
dataSet.addCrowd(new Youth());
dataSet.addCrowd(new MiddleAge());
CrowdView crowdView = new Against() ;
dataSet.display(crowdView);
crowdView = new Approve() ;
dataSet.display(crowdView);
}
}
/**
* 双分配,不同人群处理
*/
abstract class Crowd {
abstract void accept(CrowdView action);
}
class Youth extends Crowd {
@Override
public void accept(CrowdView view) {
view.getYouthView(this);
}
}
class MiddleAge extends Crowd {
@Override
public void accept(CrowdView view) {
view.getMiddleAgeView (this);
}
}
/**
* 不同人群观念的处理
*/
abstract class CrowdView {
// 青年人观念
abstract void getYouthView (Youth youth);
// 中年人观念
abstract void getMiddleAgeView (MiddleAge middleAge);
}
class Approve extends CrowdView {
@Override
public void getYouthView(Youth youth) {
System.out.println("青年人附和电竞");
}
@Override
public void getMiddleAgeView(MiddleAge middleAge) {
System.out.println("中年人附和电竞");
}
}
class Against extends CrowdView {
@Override
public void getYouthView(Youth youth) {
System.out.println("青年人仇视电竞");
}
@Override
public void getMiddleAgeView(MiddleAge middleAge) {
System.out.println("中年人仇视电竞");
}
}
/**
* 供给一个数据集结
*/
class DataSet {
private List<Crowd> crowdList = new ArrayList<>();
public void addCrowd (Crowd crowd) {
crowdList.add(crowd);
}
public void display(CrowdView crowdView) {
for(Crowd crowd : crowdList) {
crowd.accept(crowdView);
}
}
}

二、拜访者办法

1、根底概念

拜访者办法是政策的行为办法,把作用于数据结构的各元素的操作封装,操作之间没有相关。能够在不改动数据结构的条件下界说作用于这些元素的不同的操作。主要将数据结构与数据操作别离,处理数据结构和操作耦合问题中心原理:被拜访的类里边加对外供给招待拜访者的接口。

2、办法图解

Java描绘规划方法(23):访问者方法

3、中心分子

  • 笼统拜访者人物

声明多个办法操作,详细拜访者人物需求结束的接口。

  • 详细拜访者人物

结束笼统拜访者所声明的接口,便是各个拜访操作。

  • 笼统节点人物

声明承受操作,承受拜访者政策作为参数。

  • 详细节点人物

结束笼统节点所规矩的详细操作。

  • 结构政策人物

能枚举结构中的悉数元素,能够供给一个高层的接口,用来容许拜访者政策拜访每一个元素。

4、源码结束

public class C02_Visitor {
public static void main(String[] args) {
ObjectStructure obs = new ObjectStructure();
obs.add(new NodeA());
obs.add(new NodeB());
Visitor visitor = new VisitorA();
obs.doAccept(visitor);
}
}
/**
* 笼统拜访者人物
*/
interface Visitor {
/**
* NodeA的拜访操作
*/
void visit(NodeA node);
/**
* NodeB的拜访操作
*/
void visit(NodeB node);
}
/**
* 详细拜访者人物
*/
class VisitorA implements Visitor {
@Override
public void visit(NodeA node) {
node.operationA() ;
}
@Override
public void visit(NodeB node) {
node.operationB() ;
}
}
class VisitorB implements Visitor {
@Override
public void visit(NodeA node) {
node.operationA() ;
}
@Override
public void visit(NodeB node) {
node.operationB() ;
}
}
/**
* 笼统节点人物
*/
abstract class Node {
/**
* 接纳拜访者
*/
abstract void accept(Visitor visitor);
}
/**
* 详细节点人物
*/
class NodeA extends Node{
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
public void operationA(){
System.out.println("NodeA.operationA");
}
}
class NodeB extends Node{
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
public void operationB(){
System.out.println("NodeB.operationB");
}
}
/**
* 结构政策人物类
*/
class ObjectStructure {
private List<Node> nodes = new ArrayList<>();
public void detach(Node node) {
nodes.remove(node);
}
public void add(Node node){
nodes.add(node);
}
public void doAccept(Visitor visitor){
for(Node node : nodes) {
node.accept(visitor);
}
}
}

三、Spring结构运用

1、Bean结构的拜访

BeanDefinitionVisitor类,遍历bean的各个特征;接口 BeanDefinition,界说Bean的各样信息,比方特征值、结构办法、参数等等。这儿封装操作bean结构的相关办法,但却没有改动bean的结构。

2、中心代码块

public class BeanDefinitionVisitor {
public void visitBeanDefinition(BeanDefinition beanDefinition) {
this.visitParentName(beanDefinition);
this.visitBeanClassName(beanDefinition);
this.visitFactoryBeanName(beanDefinition);
this.visitFactoryMethodName(beanDefinition);
this.visitScope(beanDefinition);
if (beanDefinition.hasPropertyValues()) {
this.visitPropertyValues(beanDefinition.getPropertyValues());
}
if (beanDefinition.hasConstructorArgumentValues()) {
ConstructorArgumentValues cas = beanDefinition.getConstructorArgumentValues();
this.visitIndexedArgumentValues(cas.getIndexedArgumentValues());
this.visitGenericArgumentValues(cas.getGenericArgumentValues());
}
}
}

四、办法总结

1、利益描绘

(1) 拜访者办法契合单一责任准则、使程序具有十分超卓的扩展性、灵活性;

(2) 拜访者办法适用与拦截器与过滤器等常见功用,数据结构相对安稳的场景;

2、缺陷描绘

(1) 拜访者重视其他类的内部细节,依托性强,违反迪米特规矩,这样导致详细元素更新费事;

(2) 拜访者依托详细元素,不是笼统元素,面向细节编程,违反依托倒转准则;

五、源代码地址

GitHub·地址
https://github.com/cicadasmile/model-arithmetic-parent
GitEE·地址
https://gitee.com/cicadasmile/model-arithmetic-parent