在结构不变的情况下动态改变对于内部元素的动作 专业的设计模式(工作中很少用) 编译器的例子:抽象语法树—->语法分析—->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 getBrand
abstract double getPrice();
}
class CPU extends ComputerPart {
@Override
void accept(Visitor v) {
// 将this作为参数传到方法中
// 这里的this指cpu对象,传进去后就能够进行相应的处理(获取价钱、测试性能、体验之类的……)
v.visitCpu(this);
}
@Override
double getPrice() {
return 500;
}
}
class Memory extends ComputerPart {
@Override
void accept(Visitor v) {
v.visitMemory(this);
}
@Override
double getPrice() {
return 300;
}
}
class Board extends ComputerPart {
@Override
void accept(Visitor v) {
v.visitBoard(this);
}
@Override
double 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;
@Override
public void visitCpu(CPU cpu) {
totalPrice += cpu.getPrice()*0.9;
}
@Override
public void visitMemory(Memory memory) {
totalPrice += memory.getPrice()*0.85;
}
@Override
public void visitBoard(Board board) {
totalPrice += board.getPrice()*0.95;
}
}
class CorpVisitor implements Visitor {
double totalPrice = 0.0;
@Override
public void visitCpu(CPU cpu) {
totalPrice += cpu.getPrice()*0.6;
}
@Override
public void visitMemory(Memory memory) {
totalPrice += memory.getPrice()*0.75;
}
@Override
public void visitBoard(Board board) {
totalPrice += board.getPrice()*0.75;
}
}
编译器专业领域
传统结构
visitor模式
每个Node可以accept一个或者一堆的visitor
Visitor模式的应用:asm字节码二进制处理工具(java的汇编—->分析字节码文件中的语法分析树) ===> 详见下一篇ASM入门
🤏随想
- 建议去读gof的设计模式:可复用的设计
- operator操作符 operand操作数