gpt4 book ai didi

java - 访问者模式用法

转载 作者:行者123 更新时间:2023-11-29 09:49:59 25 4
gpt4 key购买 nike

https://stackoverflow.com/questions/9239445/sample-of-using-visitor-patternbefore-and-after

我是否正确理解访问者模式的主要目的?据我了解:

1 之前

public class Main {

public static void main(String[] args) {
List<CompanyItem> items = new ArrayList<CompanyItem>();
items.add(new Employee(10));
items.add(new Employee(10.6));
items.add(new Employee(15.9));
items.add(new Manager(20.1));
items.add(new Boss(30));

double totalSalary = 0;
for(CompanyItem i:items){
if (i instanceof Employee) {
totalSalary += ((Employee) i).getSalary();
} else if (i instanceof Manager) {
totalSalary += ((Manager) i).getSalary();
totalSalary += ((Manager) i).getBonusses();
}else if (i instanceof Boss) {
totalSalary += ((Boss) i).getSalary();
totalSalary += ((Boss) i).getAdditionalSalary();
}
}
System.out.println(totalSalary);
}

interface CompanyItem {
}

static class Employee implements CompanyItem {
double salary;

public Employee(double salary) {
this.salary = salary;
}

public double getSalary() {
return salary;
}
}

static class Manager implements CompanyItem {
double salary, bonusses;

public Manager(double salary) {
this.salary = salary;
this.bonusses = 1.5 * salary;
}

public double getSalary() {
return salary;
}

public double getBonusses() {
return bonusses;
}
}

static class Boss implements CompanyItem {
double salary, addSalary;

public Boss(double salary) {
this.salary = salary;
this.addSalary = 3 * salary;
}

public double getSalary() {
return salary;
}

public double getAdditionalSalary() {
return addSalary;
}
}
}

2 之前

public class Main3 {

public static void main(String[] args) {
List<CompanyItem> items = new ArrayList<CompanyItem>();
items.add(new Employee(10));
items.add(new Employee(10.6));
items.add(new Employee(15.9));
items.add(new Manager(20.1));
items.add(new Boss(30));

double totalSalary = 0;
for(CompanyItem i:items){
totalSalary+=i.getSalary();
totalSalary+=i.getBonusses();
totalSalary+=i.getAdditionalSalary();
}
System.out.println(totalSalary);
}

interface CompanyItem {
public double getSalary();
public double getBonusses();
public double getAdditionalSalary();
}

static class Employee implements CompanyItem {
double salary;

public Employee(double salary) {
this.salary = salary;
}

public double getSalary() {
return salary;
}

@Override
public double getBonusses() {
return 0;
}

@Override
public double getAdditionalSalary() {
return 0;
}
}

static class Manager implements CompanyItem {
double salary, bonusses;

public Manager(double salary) {
this.salary = salary;
this.bonusses = 1.5 * salary;
}

public double getSalary() {
return salary;
}

public double getBonusses() {
return bonusses;
}

@Override
public double getAdditionalSalary() {
return 0;
}
}

static class Boss implements CompanyItem {
double salary, addSalary;

public Boss(double salary) {
this.salary = salary;
this.addSalary = 3 * salary;
}

public double getSalary() {
return salary;
}

public double getAdditionalSalary() {
return addSalary;
}

@Override
public double getBonusses() {
return 0;
}
}
}

之后(使用访问者模式 ???)

public class Main1 {

public static void main(String[] args) {
List<CompanyItem> items = new ArrayList<CompanyItem>();
items.add(new Employee(10));
items.add(new Employee(10.6));
items.add(new Employee(15.9));
items.add(new Manager(20.1));
items.add(new Boss(30));

SalaryVisitor visitor = new SalaryVisitor();
for(CompanyItem i:items){
i.accept(visitor);
}
System.out.println(visitor.getTotalSalary());
}

interface CompanyItem {
public void accept(Visitor v);
}

static class Employee implements CompanyItem {
double salary;

public Employee(double salary) {
this.salary = salary;
}

public double getSalary() {
return salary;
}

@Override
public void accept(Visitor v) {
v.visit(this);
}
}

static class Manager implements CompanyItem {
double salary,bonusses;

public Manager(double salary) {
this.salary = salary;
this.bonusses = 1.5 * salary;
}

public double getSalary() {
return salary;
}

public double getBonusses(){
return bonusses;
}

@Override
public void accept(Visitor v) {
v.visit(this);
}
}

static class Boss implements CompanyItem {
double salary, addSalary;

public Boss(double salary) {
this.salary = salary;
this.addSalary = 3 * salary;
}

public double getSalary() {
return salary;
}
public double getAdditionalSalary(){
return addSalary;
}

@Override
public void accept(Visitor v) {
v.visit(this);
}
}

interface Visitor {
public void visit(Employee e);
public void visit(Manager m);
public void visit(Boss b);
}

static class SalaryVisitor implements Visitor {
double totalSalary;

public SalaryVisitor() {
totalSalary = 0;
}

public double getTotalSalary(){
return totalSalary;
}

@Override
public void visit(Employee e) {
totalSalary += e.getSalary();
}

@Override
public void visit(Manager m) {
totalSalary += (m.getSalary()+m.getBonusses());
}

@Override
public void visit(Boss b) {
totalSalary += (b.getSalary()+b.getAdditionalSalary());
}
}
}

我说得对吗?

最佳答案

从技术上讲,该示例很好地实现了访问者模式。但是这个例子并没有提升访问者的优势。要点是:如果您希望多个独立的算法在同一数据结构上工作 - 而无需更改数据结构,则实现访问者模式开销。

为了增强您的示例,我建议进行以下更改:将简单的奖金系统替换为一个系统,该系统在所有 经理根据每个经理拥有的一些奖励积分。如果有两个经理,一个有 140 分,另一个有 60 分,那么第一个得到 70k$,第二个得到 30k$。

这允许您有多个访问者:

  • 一个总结所有经理的所有奖励积分
  • 一个使用上一步的总和在经理之间分配奖金 (100k$)。将这个计算出的个人奖金设置到 Manager
  • 中的一个字段中
  • 第三位访问者 (PaydayVisitor) 为员工、老板和经理打印支票,并返回所有已完成付款的总和。

编辑 在代码中,这看起来像这样(仅为了简洁起见省略了 getter/setter):

import java.util.ArrayList;
import java.util.List;

public class VisitorExample {
public static void main(String[] args) {
List<CompanyItem> items = new ArrayList<CompanyItem>();
items.add(new Employee(10));
items.add(new Employee(10.6));
items.add(new Employee(15.9));
items.add(new Manager(20.1, 140));
items.add(new Manager(42.1, 70));
items.add(new Boss(30, 10));

// sum up all bonus points of all Managers
BonusPointVisitor bonusPointVisitor = new BonusPointVisitor();
for(CompanyItem i: items)
i.accept(bonusPointVisitor);

// distribute given bonus sum among the managers
BonusDistributorVisitor bonusDistributorVisitor =
new BonusDistributorVisitor(bonusPointVisitor.totalBonusPoints, 100.0);
for(CompanyItem i: items)
i.accept(bonusDistributorVisitor);

// PayDay - print all checks
PrintCheckVisitor printCheckVisitor = new PrintCheckVisitor();
for(CompanyItem i: items)
i.accept(printCheckVisitor);
System.out.println("total money spent this month: "+printCheckVisitor.totalPayments);
}

interface CompanyItem {
public void accept(Visitor v);
}

interface Visitor {
public void visit(Employee e);
public void visit(Manager m);
public void visit(Boss b);
}

static class Employee implements CompanyItem {
double salary;

public Employee(double salary) {
this.salary = salary;
}

@Override
public void accept(Visitor v) {
v.visit(this);
}
}

static class Manager implements CompanyItem {
double salary, bonusPoints, bonus;

public Manager(double salary, double bonusPoints) {
this.salary = salary;
this.bonusPoints = bonusPoints;
this.bonus = 0;
}

@Override
public void accept(Visitor v) {
v.visit(this);
}
}

static class Boss implements CompanyItem {
double salary, addSalary;

public Boss(double salary, double addSalary) {
this.salary = salary;
this.addSalary = addSalary;
}

@Override
public void accept(Visitor v) {
v.visit(this);
}
}

static class BonusPointVisitor implements Visitor {
double totalBonusPoints = 0d;

@Override
public void visit(Employee e) {
}

@Override
public void visit(Manager m) {
totalBonusPoints += m.bonusPoints;
}

@Override
public void visit(Boss b) {
}
}


static class BonusDistributorVisitor implements Visitor {
double totalBonusPoints, totalBonus;

public BonusDistributorVisitor(double totalBonusPoints, double totalBonus) {
this.totalBonusPoints = totalBonusPoints;
this.totalBonus = totalBonus;
}

@Override
public void visit(Employee e) {
}

@Override
public void visit(Manager m) {
m.bonus = (m.bonusPoints / totalBonusPoints) * totalBonus;
}

@Override
public void visit(Boss b) {
}
}

static class PrintCheckVisitor implements Visitor {
double totalPayments = 0;

@Override
public void visit(Employee e) {
advisePayment(e.salary);
}

@Override
public void visit(Manager m) {
advisePayment(m.salary + m.bonus);
}

@Override
public void visit(Boss b) {
advisePayment(b.salary + b.addSalary);
}

private void advisePayment(double amount){
System.out.println("pay "+amount+" credits");
totalPayments += amount;
}
}
}

剩下要做的事情:给每个项目一些可打印的名称,以便在 advisePayment 中使用。

关于java - 访问者模式用法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9240551/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com