1、基本介绍
- 电脑组成:可打折组件、不可打折组件
- 不同的人群有不同的折扣
- 由特定人群的客户,获取对应的价格
2、类图
- Part:可打折配件的接口
- 定义 accept(Visitor visitor) ,接收一个访问者参数,返回该配件的最终价格(原价 * 相应的折扣率)
- 配件子类方法内:visitor.visit(this),调用 visitor 方法,把自已传给 visitor ,计算最终价格的逻辑由 visitor 完成,把最终价格再返给 accept 方法
- 折扣率在访问者中定义,与访问者对应,与配件分离;当增加新的访问者,或者改变折扣率时,不会改变配件;在访问者维度方便扩展
- CPU、Memory、Board:配件子类
- Visitor:访问者接口
- 接口内定义了每一个配件的 visit() 方法,内含折扣率,返回配件的最终价格
- Student、Worker、Enterprise:具体访问者
- Computer:电脑;包含可打折组件、不可打折组件
- Client:测试客户端
3、源码
- 可打折配件接口
package visitor.computer.part;
import visitor.computer.visitor.Visitor;
/**
* @author 土味儿
* Date 2021/8/3
* @version 1.0
* 电脑中可以打折的配件
* 被访问者
*/
public interface Part {
/**
* 部件价格
* 单位:分
* @return
*/
public int getPrice();
/**
* 设置价格
* @param yuan 元
* @param fen 分
*/
public void setPrice(int yuan,int fen);
/**
* 接受访问者
* 返回值为该部件的费用
* 交给访问者去计算
* @param visitor
* @return
*/
public int accept(Visitor visitor);
}
- 可打折配件抽象类
package visitor.computer.part;
import visitor.computer.visitor.Visitor;
/**
* @author 土味儿
* Date 2021/8/3
* @version 1.0
* 电脑中可以打折的配件
* 抽象类
*/
public abstract class AbstractPart implements Part{
// 价格 单位:分
private int price;
/**
* 构造器
* @param yuan 价格:元
* @param fen 价格:分
*/
public AbstractPart(int yuan, int fen) {
this.price = yuan * 100 + fen;
}
@Override
public int getPrice() {
return price;
}
@Override
public void setPrice(int yuan, int fen) {
this.price = yuan * 100 + fen;
}
@Override
public abstract int accept(Visitor visitor);
}
- 具体可打折配件
public class CPU extends AbstractPart {
/**
* 构造器
*
* @param yuan 价格:元
* @param fen 价格:分
*/
public CPU(int yuan, int fen) {
super(yuan, fen);
}
@Override
public int accept(Visitor visitor) {
return visitor.visit(this);
}
}
public class Memory extends AbstractPart{
/**
* 构造器
*
* @param yuan 价格:元
* @param fen 价格:分
*/
public Memory(int yuan, int fen) {
super(yuan, fen);
}
@Override
public int accept(Visitor visitor) {
return visitor.visit(this);
}
}
public class Board extends AbstractPart{
/**
* 构造器
*
* @param yuan 价格:元
* @param fen 价格:分
*/
public Board(int yuan, int fen) {
super(yuan, fen);
}
@Override
public int accept(Visitor visitor) {
return visitor.visit(this);
}
}
- 访问者接口
package visitor.computer.visitor;
import visitor.computer.part.Board;
import visitor.computer.part.CPU;
import visitor.computer.part.Memory;
/**
* @author 土味儿
* Date 2021/8/3
* @version 1.0
* 访问者
*/
public interface Visitor {
/**
* 返回CPU的费用
* @param cpu
* @return
*/
public int visit(CPU cpu);
/**
* 返回内存的费用
* @param memory
* @return
*/
public int visit(Memory memory);
/**
* 返回主板的费用
* @param board
* @return
*/
public int visit(Board board);
}
- 具体访问者
public class Student implements Visitor {
// 折扣
private int discount = 100;
@Override
public int visit(CPU cpu) {
// 折扣
discount = 85;
int sum = cpu.getPrice() * discount / 100;
System.out.println("\tCPU(" + PriceUtil.fenToYuan(cpu.getPrice()) + ")\t学生" + discount + "折\t\t" + PriceUtil.fenToYuan(sum));
return sum;
}
@Override
public int visit(Memory memory) {
// 折扣
discount = 78;
int sum = memory.getPrice() * discount / 100;
System.out.println("\t内存(" + PriceUtil.fenToYuan(memory.getPrice()) + ")\t学生" + discount + "折\t\t" + PriceUtil.fenToYuan(sum));
return sum;
}
@Override
public int visit(Board board) {
// 折扣
discount = 80;
int sum = board.getPrice() * discount / 100;
System.out.println("\t主板(" + PriceUtil.fenToYuan(board.getPrice()) + ")\t学生" + discount + "折\t\t" + PriceUtil.fenToYuan(sum));
return sum;
}
}
public class Worker implements Visitor{
// 折扣
private int discount = 100;
@Override
public int visit(CPU cpu) {
// 折扣
discount = 95;
int sum = cpu.getPrice() * discount / 100;
System.out.println("\tCPU(" + PriceUtil.fenToYuan(cpu.getPrice()) + ")\t职员" + discount + "折\t\t" + PriceUtil.fenToYuan(sum));
return sum;
}
@Override
public int visit(Memory memory) {
// 折扣
discount = 90;
int sum = memory.getPrice() * discount / 100;
System.out.println("\t内存(" + PriceUtil.fenToYuan(memory.getPrice()) + ")\t职员" + discount + "折\t\t" + PriceUtil.fenToYuan(sum));
return sum;
}
@Override
public int visit(Board board) {
// 折扣
discount = 93;
int sum = board.getPrice() * discount / 100;
System.out.println("\t主板(" + PriceUtil.fenToYuan(board.getPrice()) + ")\t职员" + discount + "折\t\t" + PriceUtil.fenToYuan(sum));
return sum;
}
}
public class Enterprise implements Visitor{
// 折扣
int discount = 100;
@Override
public int visit(CPU cpu) {
// 折扣
discount = 99;
int sum = cpu.getPrice() * discount / 100;
System.out.println("\tCPU(" + PriceUtil.fenToYuan(cpu.getPrice()) + ")\t企业" + discount + "折\t\t" + PriceUtil.fenToYuan(sum));
return sum;
}
@Override
public int visit(Memory memory) {
// 折扣
discount = 98;
int sum = memory.getPrice() * discount / 100;
System.out.println("\t内存(" + PriceUtil.fenToYuan(memory.getPrice()) + ")\t企业" + discount + "折\t\t" + PriceUtil.fenToYuan(sum));
return sum;
}
@Override
public int visit(Board board) {
// 折扣
discount = 97;
int sum = board.getPrice() * discount / 100;
System.out.println("\t主板(" + PriceUtil.fenToYuan(board.getPrice()) + ")\t企业" + discount + "折\t\t" + PriceUtil.fenToYuan(sum));
return sum;
}
}
- 电脑
package visitor.computer;
import visitor.computer.part.Board;
import visitor.computer.part.CPU;
import visitor.computer.part.Memory;
import visitor.computer.part.Part;
import visitor.computer.util.PriceUtil;
import visitor.computer.visitor.Visitor;
import java.util.ArrayList;
import java.util.List;
/**
* @author 土味儿
* Date 2021/8/3
* @version 1.0
* 电脑
*/
public class Computer {
// 电脑可打折组件集合
private static final List<Part> parts = new ArrayList<>();
static {
parts.add(new CPU(1200, 56));
parts.add(new Memory(408, 32));
parts.add(new Board(672, 78));
}
// 电脑不可打折组件价格 单位:分
private static final int otherPrice = 1326 * 100 + 45;
// 访问者
private Visitor visitor;
/**
* 构造器
*
* @param visitor
*/
public Computer(Visitor visitor) {
this.visitor = visitor;
}
/**
* 得到价格
*/
public void getPrice() {
// 未打折部分费用
int sum = otherPrice;
System.out.println("不打折部分价格:\t\t\t\t\t" + PriceUtil.fenToYuan(otherPrice));
System.out.println("---------------------------------------");
System.out.println("打折部分价格:");
System.out.println("---------------------------------------");
// 打折部分费用
for (Part part : parts) {
sum = sum + part.accept(visitor);
}
System.out.println("---------------------------------------");
System.out.println("合计:\t\t\t\t\t\t\t" + PriceUtil.fenToYuan(sum) + "\n\n\n");
}
/**
* 设置访问者
*
* @param visitor
*/
public void setVisitor(Visitor visitor) {
this.visitor = visitor;
}
}
- 测试客户端
package visitor.computer;
import visitor.computer.visitor.*;
/**
* @author 土味儿
* Date 2021/8/3
* @version 1.0
* 测试客户端
*/
public class Client {
public static void main(String[] args) {
// 创建访问者
System.out.println("================= 学生 =================\n");
Visitor student = new Student();
// 创建电脑
Computer computer = new Computer(student);
computer.getPrice();
// 创建访问者
System.out.println("================= 职员 =================\n");
Worker worker = new Worker();
computer.setVisitor(worker);
computer.getPrice();
// 创建访问者
System.out.println("================= 企业 =================\n");
Enterprise enterprise = new Enterprise();
computer.setVisitor(enterprise);
computer.getPrice();
}
}
- 工具类
public class PriceUtil {
/**
* 把金额中的 分 转为 元
*
* @param fen
* @return
*/
public static String fenToYuan(int fen) {
int i = fen % 100;
return (int) Math.floor(fen / 100) + "." + (i < 10 ? i + "0元" : i + "元");
}
}
运行结果
================= 学生 =================
不打折部分价格: 1326.45元
---------------------------------------
打折部分价格:
---------------------------------------
CPU(1200.56元) 学生85折 1020.47元
内存(408.32元) 学生78折 318.48元
主板(672.78元) 学生80折 538.22元
---------------------------------------
合计: 3203.62元
================= 职员 =================
不打折部分价格: 1326.45元
---------------------------------------
打折部分价格:
---------------------------------------
CPU(1200.56元) 职员95折 1140.53元
内存(408.32元) 职员90折 367.48元
主板(672.78元) 职员93折 625.68元
---------------------------------------
合计: 3460.14元
================= 企业 =================
不打折部分价格: 1326.45元
---------------------------------------
打折部分价格:
---------------------------------------
CPU(1200.56元) 企业99折 1188.55元
内存(408.32元) 企业98折 400.15元
主板(672.78元) 企业97折 652.59元
---------------------------------------
合计: 3567.74元