我们用商品计算价格来举例,我们先建 net.haicoder.visitor
包。先建抽象元素接口 Goods.java
,再定义具体实现类 Cigarette.java
和 Pig.java
Wine.java
。
建立抽象的访问者类 Visitor.java
,具体访问者实现类 VisitorImpl.java
,购物车类 ShoppingCart.java
和测试类 TestMain.java
。文件创建完毕,具体目录结构如下:
Goods.java
代码如下:
package net.haicoder.visitor;
/**
* 抽象元素
*/
public interface Goods {
double accept(Visitor visitor);
}
Cigarette.java
代码如下:
package net.haicoder.visitor;
public class Cigarette implements Goods {
@Override
public double accept(Visitor visitor) {
return visitor.visit(this);
}
public double accountByPack() {
System.out.println("烟按包计价,购买的数量为:" + getCount() + "瓶,购买的单价为:" + getPrice() + ",总价为:" + getCount() * getPrice());
return getCount() * getPrice();
}
private int count;
private float price;
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
}
Pig.java
代码如下:
package net.haicoder.visitor;
public class Pig implements Goods {
private float price;
private Float count;
@Override
public double accept(Visitor visitor) {
return visitor.visit(this);
}
public double accountByUnit() {
System.out.println("猪肉按斤计价,购买的数量为:" + getCount() + "斤,购买的单价为:" + getPrice() + ",总价为:" + getCount() * getPrice());
return getCount() * getPrice();
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
public Float getCount() {
return count;
}
public void setCount(Float count) {
this.count = count;
}
}
Wine.java
代码如下:
package net.haicoder.visitor;
public class Wine implements Goods {
@Override
public double accept(Visitor visitor) {
return visitor.visit(this);
}
public double accountByBottle() {
System.out.println("酒按瓶计价,购买的数量为:" + getCount() + "瓶,购买的单价为:" + getPrice() + ",总价为:" + getCount() * getPrice());
return getCount() * getPrice();
}
private int count;
private float price;
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
}
Visitor.java
代码如下:
package net.haicoder.visitor;
public interface Visitor {
double visit(Wine wine);
double visit(Pig pig);
double visit(Cigarette cigarette);
}
VisitorImpl.java
代码如下:
package net.haicoder.visitor;
public class VisitorImpl implements Visitor {
@Override
public double visit(Wine wine) {
return wine.accountByBottle();
}
@Override
public double visit(Pig pig) {
return pig.accountByUnit();
}
@Override
public double visit(Cigarette cigarette) {
return cigarette.accountByPack();
}
}
ShoppingCart.java
代码如下:
package net.haicoder.visitor;
import java.util.ArrayList;
import java.util.List;
public class ShoppingCart {
private List list = new ArrayList<>();
public void add(Object object) {
list.add(object);
}
public void remove(Object object) {
list.remove(object);
}
public List getList() {
return list;
}
}
TestMain.java
代码如下:
package net.haicoder.visitor;
public class TestMain {
public static void main(String[] args) {
System.out.println("嗨客网(www.haicoder.net)");
Wine wine = new Wine();
wine.setCount(10);
wine.setPrice(20f);
Pig pig = new Pig();
pig.setCount(10f);
pig.setPrice(35f);
Cigarette cigarette = new Cigarette();
cigarette.setCount(1);
cigarette.setPrice(20f);
ShoppingCart shoppingCart = new ShoppingCart();
shoppingCart.add(wine);
shoppingCart.add(pig);
shoppingCart.add(cigarette);
double amt = 0;
Visitor visitor = new VisitorImpl();
for (int i = 0; i < shoppingCart.getList().size(); i++) {
amt += ((Goods) shoppingCart.getList().get(i)).accept(visitor);
}
System.out.println("本次购物车内所有物品的总价为:" + amt);
}
}
代码运行结果如下图:
将作用于某种数据结构中的各元素的操作分离出来封装成独立的类,使其在不改变数据结构的前提下可以添加作用于这些元素的新的操作,为数据结构中的每个元素提供多种访问方式。将数据结构和数据的操作相分离。