在结构不变的情况下动态改变对于内部元素的动作 专业的设计模式(工作中很少用) 编译器的例子:抽象语法树—->语法分析—->visitor模式
情景引入
中关村装机 一台机器三部分组成:cpu、内存、主板 针对不同的客户(学生、社畜、批发)给出不同德折扣
UML类图

实现
accept()方法:接待不同客户(if实现不好,不光要耦合到accept中去,而且新的客户来要修改的太多) cpu等组件去接待来访者,但接待策略让来访者自己实现策略 visitor.visitCpu();实现不同的折扣并计算总价 accept(v)方法是一个固定模式v.visit(); 好处:电脑那个类就不用变了 格式、内部结构固定的情况下用visitor 电脑内部组件不断增加的情况下visitor模式就不适合了(不适用) visitor模式访问的是结构固定的,定死的结构 思想:将不同组件中的if-else抽取到一个类中,通过多态决定具体的业务处理逻辑 将if-else的变化抽象出来,抽象到一个单独的visitor接口中
package com.mashibing.dp.visitor;public class Computer {// 组合/聚合ComputerPart cpu = new CPU();ComputerPart memory = new Memory();ComputerPart board = new Board();public void acccept(Visitor v) {this.cpu.accept(v);this.memory.accept(v);this.board.accept(v);}public static void main(String[] args) {PersonelVisitor p = new PersonelVisitor();new Computer().acccept(p);System.out.println(p.totalPrice);}}abstract class ComputerPart {abstract void accept(Visitor v);//some other operations eg:getName getBrandabstract double getPrice();}class CPU extends ComputerPart {@Overridevoid accept(Visitor v) {// 将this作为参数传到方法中// 这里的this指cpu对象,传进去后就能够进行相应的处理(获取价钱、测试性能、体验之类的……)v.visitCpu(this);}@Overridedouble getPrice() {return 500;}}class Memory extends ComputerPart {@Overridevoid accept(Visitor v) {v.visitMemory(this);}@Overridedouble getPrice() {return 300;}}class Board extends ComputerPart {@Overridevoid accept(Visitor v) {v.visitBoard(this);}@Overridedouble getPrice() {return 200;}}interface Visitor {void visitCpu(CPU cpu);void visitMemory(Memory memory);void visitBoard(Board board);}class PersonelVisitor implements Visitor {double totalPrice = 0.0;@Overridepublic void visitCpu(CPU cpu) {totalPrice += cpu.getPrice()*0.9;}@Overridepublic void visitMemory(Memory memory) {totalPrice += memory.getPrice()*0.85;}@Overridepublic void visitBoard(Board board) {totalPrice += board.getPrice()*0.95;}}class CorpVisitor implements Visitor {double totalPrice = 0.0;@Overridepublic void visitCpu(CPU cpu) {totalPrice += cpu.getPrice()*0.6;}@Overridepublic void visitMemory(Memory memory) {totalPrice += memory.getPrice()*0.75;}@Overridepublic void visitBoard(Board board) {totalPrice += board.getPrice()*0.75;}}
编译器专业领域
传统结构

visitor模式

每个Node可以accept一个或者一堆的visitor
Visitor模式的应用:asm字节码二进制处理工具(java的汇编—->分析字节码文件中的语法分析树) ===> 详见下一篇ASM入门
🤏随想
- 建议去读gof的设计模式:可复用的设计
- operator操作符 operand操作数

