1. 概念
表示一个作用于某对象结构中的各元素的操作,它使我们可以在不改变元素的类的前提下定义作用于这些元素的新操作。
2. 适用场景
对于存储在一个集合中的对象,它们可能具有不同的类型(即使有一个公共的接口),对于该集合中的对象,可以接受一类称为访问者的对象来访问,不同的访问者其访问的方式也有所不同。
工作中很少适用到
3. 代码分析
屏幕快照 2021-01-20 下午2.32.50.png故事原型是这样的:在中关村攒电脑,假如组装一台电脑所需的部件有{cpu, 内存, 主板}三部分组成,而针对不同的团体时,电脑的不同的零部件优惠力度有所不同。
- ComputerPart - 电脑的各部件抽象:
abstract class ComputerPart {
// 每个部件接收来访者
abstract void accept(Visitor v);
// 各部件的定价
abstract double getPrice();
}
- Visitor - 各阶层的访问者,对各部件的不同操作抽象:
interface Visitor {
void visitCpu(CPU cpu);
void visitMemory(Memory memory);
void visitBoard(Board board);
}
- CPU/Memory/Board - 各部件:
class CPU extends ComputerPart {
@Override
void accept(Visitor v) {
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;
}
}
- PersonelVisitor - 个人访问者对各部件的操作:
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;
}
}
- Computer - 成品电脑:
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);
}
代码分析:使用访问模式组织代码后,避免了各部件中根据不同的团体if else的判断,来区分不同的优惠力度。而是通过实现Visitor接口,从而将不同阶层的人员对各部件的操作抽取出来。Computer与实现各ComputerPart的类结构就固定下来。
如果子结构(部件)的数量不确定,那么此模式不适合。
4. 总结
- 此模式适合子结构数量确定的情况
- 主要用于编译器的设计
————————————————————
坐标帝都,白天上班族,晚上是知识的分享者
如果读完觉得有收获的话,欢迎点赞加关注
网友评论