Visitor设计模式
程序员文章站
2023-12-22 23:22:58
...
visitor只适合结构固定的程序设计,当程序由增加删除组件的操作时,visitor设计模式是不适合的。所以Visitor会被使用在编译器和语法分析中。
下面通过实例来了解这个设计模式的具体的作用。
需求:在一些电子商城会有一些卖组装电脑的,电脑组装使用不同的元件,每个元件的价格不一样,而且卖家也会根据买家的身份不同而给予不同的折扣,下面,考虑使用程序来实现这个买家买元件进行组装并被卖家给与打折优惠的过程。
接下来我们考虑如何使用Java面向对象编程将这个事情使用代码的方式将它实现出来。
首先,我们可以想到:将接待客户的行为抽象为方法,写入到每个电脑组件中,在方法中使用判断语句判断买家的身份,然后根据买家身份给予相应的折扣。
class CPU {
void accept(Visitor v) {
}
double getPrice() {
return 500;
}
}
但是这种方法比较繁琐,因为电脑组件的数量很多,买家的身份也很多,如果一个个的写if语句进行判断,那样代码会很多,整个程序就会显得非常的繁琐。
考虑到Visitor模式在不改变程序结构情况下动态的进行编程,所以我们抽象出一个电脑组件类,并且让所有的电脑组件继承这个电脑组件类。
abstract class ComputerPart {
abstract void accept(Visitor v);
abstract double getPrice();
}
将前面电脑组件对不同客户进行打折的行为设计为一个接口,将电脑组件对不同客户进行打折的行为写入到这个接口中。
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;
}
}
接下来,我们将整理好的思路整合起来,完成整个符合需求的程序。
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);
abstract double getPrice();
}
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; }
}
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接口中,再由类去实现接口中的方法。当然这个操作的重要前提是程序的结构不变,如果程序的结构需要变化,这种设计模式显然是不适合的。
接下来给出图片来讲明传统编程模式与Visitor的区别。