1. 程式人生 > 實用技巧 >13、Visitor 訪問者模式 訪問資料結構並處理資料 行為型設計模式

13、Visitor 訪問者模式 訪問資料結構並處理資料 行為型設計模式

1

Visitor使

Visitor

使使

2

Element

packagecn.design.behavior.visitor;

/**
*@authorlin
*@version1.0
*@date2020-07-2716:15
*@DescriptionTODO
*/
publicinterfaceElement{
voidaccept(Visitorvisitor);
}

Compute

packagecn.design.behavior.visitor;

importcn.design.create.abstractfactory.clone.User;

/**
*@authorlin
*@version1.0
*@date2020-07-2716:33
*@DescriptionTODO
*/
publicclassComputeimplementsElement{
Useruser=newUser();
intcpu=300;
intboard=150;
intmemory=50;

@Override
publicvoidaccept(Visitorvisitor){
visitor.visit(this);
}

/**
*
*/
publicvoidvisit(){
//
if(user.obj.equals("stu")){
this.cpu-=20;
this.board-=20;
this.memory-=20;
System.out.println("20,"+this.toString());
}elseif(user.obj.equals("adu")){
this.cpu-=10;
this.board-=10;
this.memory-=10;
System.out.println("10,"+this.toString());
}else{
this.cpu-=5;
this.board-=5;
this.memory-=5;
System.out.println("10,"+this.toString());
}
}

@Override
publicStringtoString(){
return"Compute{"+
"cpu="+cpu+
",board="+board+
",memory="+memory+
'}';
}

}

Visitor

packagecn.design.behavior.visitor;

/**
*@authorlin
*@version1.0
*@date2020-07-2716:18
*@DescriptionTODO
*/
publicinterfaceVisitor{

voidvisit(Computee);

}

StudentVisitor

packagecn.design.behavior.visitor;

/**
*@authorlin
*@version1.0
*@date2020-07-2716:24
*@Description
*/
publicclassStudentVisitorimplementsVisitor{
@Override
publicvoidvisit(Computeelement){
element.cpu-=20;
element.board-=20;
element.memory-=20;
System.out.println("20,"+element.toString());
}
}

AdultVisitor

packagecn.design.behavior.visitor;

/**
*@authorlin
*@version1.0
*@date2020-07-2716:25
*@Description
*/
publicclassAdultVisitorimplementsVisitor{
@Override
publicvoidvisit(Computeelement){

element.cpu-=10;
element.board-=10;
element.memory-=10;
System.out.println("10,"+element.toString());
}
}

VisitorMain

packagecn.design.behavior.visitor;


importcn.design.create.abstractfactory.clone.User;

/**
*@authorlin
*@version1.0
*@date2020-07-2714:40
*@DescriptionVJTe
*/
publicclassVisitorMain{
publicstaticvoidmain(String[]args){
Useruser=newUser("",15,"stu");
//1if
Computecompute=newCompute();
compute.user=user;
compute.visit();

//2
Computecompute2=newCompute();
compute2.user=user;
StudentVisitorv2=newStudentVisitor();
v2.visit(compute2);
AdultVisitorv3=newAdultVisitor();
Computecompute3=newCompute();
compute3.user=user;
v3.visit(compute3);
}
}

20,Compute{cpu=280,board=130,memory=30}
20,Compute{cpu=280,board=130,memory=30}
10,Compute{cpu=290,board=140,memory=40}

3asm

https://asm.org/

ASMVisitor

3.1 ASM

ClassReader

class class ClassReader Visitor

ClassVisitor

ClassReader 調 ClassReader#accept() ClassVisitor ClassReader 調 ClassVisitor visit() ClassVisitor visitMethod MethodVisitor 調visitField FieldVisitor 調 Visitor

ASM ClassVisitor ClassReader 使 ClassReader accept ClassVisitor

ClassWriter

ClassVisitor ClassVisitor ClassWriter

3.2 ASM

ClassReaderClassReader
ClassVisitorClassVisitorVisitor
調ClassReader#accept()ClassVisitorClassVisitorClassVisitor
調ClassWritervisitor

3.3ClassPrinter

packagecn.design.behavior.visitor;

importjdk.internal.org.objectweb.asm.ClassReader;
importjdk.internal.org.objectweb.asm.ClassVisitor;
importjdk.internal.org.objectweb.asm.FieldVisitor;
importjdk.internal.org.objectweb.asm.MethodVisitor;

importjava.io.IOException;
importjava.lang.reflect.Field;

importstaticjdk.internal.org.objectweb.asm.Opcodes.ASM4;

/**
*@authorlin
*@version1.0
*@date2020-07-2717:00
*@DescriptionTODO
*/
publicclassClassPrinterextendsClassVisitor{
publicClassPrinter(){
super(ASM4);
}

@Override
publicvoidvisit(intversion,intaccess,Stringname,Stringsignature,StringsuperName,String[]interfaces){
System.out.println(name+"extends"+superName+"{");
}

@Override
publicFieldVisitorvisitField(intaccess,Stringname,Stringdescriptor,Stringsignature,Objectvalue){
System.out.println(""+name);
returnnull;
}

@Override
publicMethodVisitorvisitMethod(intaccess,Stringname,Stringdescriptor,Stringsignature,String[]exceptions){
System.out.println(""+name+"()");
returnnull;
}

@Override
publicvoidvisitEnd(){
System.out.println("}");
}

publicstaticvoidmain(String[]args)throwsIOException{
ClassPrintercp=newClassPrinter();
//
ClassReadercr=newClassReader("java.lang.String");
//.class
ClassReadercr3=newClassReader(ClassPrinter.class.getClassLoader().getResourceAsStream("cn/design/behavior/visitor/Compute.class"));
cr.accept(cp,0);
cr3.accept(cp,0);
}

}

java/lang/Stringextends java/lang/Object{ value ....... valueOf () valueOf () intern () compareTo () <clinit> () }cn/design/behavior/visitor/Computeextends java/lang/Object{ user cpu board memory <init> () accept () visit () toString () }

,退0

4Visitor

accept Visitor accept visit accept Visitor visitor 19.4 Visitor

EvalVisitorv=newEvalVisitor();
t.accept(v);
intres=v.result;

visitor

publicabstractclassASTree{
publicabstractvoidaccept(Visitorv)throwsException;
}

publicclassNumberLiteralextendsASTree{
publicTokenvalue;
publicvoidaccept(Visitorv)throwsException{
v.visit(this);
}
}
publicclassBinaryExprextendsASTree{
publicTokenoperator;
publicASTreeleft,right;
publicvoidaccept(Visitorv)throwsException{
v.visit(this);
}
}

Visitor Visitor.java

publicinterfaceVisitor{
voidvisit(NumberLiteraln)throwsException;
voidvisit(BinaryExpre)throwsException;
}

EvalVisitor EvalVisitor.java

publicclassEvalVisitorimplementsVisitor{
publicintresult;
publicvoidvisit(NumberLiteralnum){
result=num.value.getNumber();
}
publicvoidvisit(BinaryExpre)throwsException{
Stringop=e.operator.getText();
e.left.accept(this);
intr1=result;
e.right.accept(this);
if("+".equals(op))
result=r1+result;
elseif("*".equals(op))
result=r1*result;
else
thrownewException("badoperator"+op);
}
}

publicinterfaceVisitor<R>{
Rvisit(NumberLiteraln)throwsException;
Rvisit(BinaryExpre)throwsException;
}
public<R>Raccept(Visitor<R>v)throwsException{
returnv.visit(this);
}
publicclassEvalVisitorimplementsVisitor<Integer>{...}

LookupVisitor LookupVisitor.java

publicclassLookuplVisitorimplementsVisitor{
privateSymbolssymbols;
publicLookuplVisitor(Symbolssyms){symbols=syms;}
publicvoidvisit(NumberLiteralnum){
symbols.put(num.value.getText());
}
publicvoidvisit(BinaryExpre)throwsException{
e.left.accept(this);
e.right.accept(this);
}
}

5

使Visitor

公眾號發哥講

這是一個稍偏基礎和偏技術的公眾號,甚至其中包括一些可能閱讀量很低的包含程式碼的技術文,不知道你是不是喜歡,期待你的關注。

如果你覺得文章還不錯,就請點選右上角選擇傳送給朋友或者轉發到朋友圈~

● 掃碼關注我們

據說看到好文章不推薦的人,伺服器容易宕機!

本文版權歸發哥講部落格園共有,原創文章,未經允許不得轉載,否則保留追究法律責任的權利。