1.什么是訪問(wèn)者模式?
比如我有一個(gè)賬單浸踩,賬單有收入叔汁,支出兩個(gè)固定方法。但是訪問(wèn)賬單的人不確定,有可能是一個(gè)或者多個(gè)据块。
2.訪問(wèn)者模式有兩個(gè)特點(diǎn)
一般被訪問(wèn)的東西所持有的方法是固定的码邻,就像賬單只有收入和支出兩個(gè)功能。而訪問(wèn)者是不固定的瑰钮。
數(shù)據(jù)操作與數(shù)據(jù)結(jié)構(gòu)相分離:頻繁的更改數(shù)據(jù)冒滩,但不結(jié)構(gòu)不變。比如:雖然每一天賬單的數(shù)據(jù)都會(huì)變化(數(shù)據(jù)變化)浪谴,但是只有兩類數(shù)據(jù),就是支出和收入(結(jié)構(gòu)不變)因苹。
簡(jiǎn)化如下圖:
例子:
import java.util.ArrayList;
import java.util.List;
/**
* 創(chuàng)建一個(gè)賬單接口苟耻,有接收訪問(wèn)者的功能
*
* @author hgx
*
*/
interface Bill {
void accept(AccountBookView viewer);
}
/**
* 消費(fèi)單子
*
* @author hgx
*
*/
class ConsumerBill implements Bill {
private String item;
private double amount;
public ConsumerBill(String item, double amount) {
this.item = item;
this.amount = amount;
}
public void accept(AccountBookView viewer) {
viewer.view(this);
}
public String getItem() {
return item;
}
public double getAmount() {
return amount;
}
}
/**
* 收入單子
*
* @author hgx
*
*/
class IncomeBill implements Bill {
private String item;
private double amount;
public IncomeBill(String item, double amount) {
this.item = item;
this.amount = amount;
}
public void accept(AccountBookView viewer) {
viewer.view(this);
}
public String getItem() {
return item;
}
public double getAmount() {
return amount;
}
}
/**
* 訪問(wèn)者接口
*
* @author hgx
*
*/
interface AccountBookView {
// 查看消費(fèi)的單子
void view(ConsumerBill consumerBill);
// 查看收入單子
void view(IncomeBill incomeBill);
}
// 老板類:訪問(wèn)者是老板,主要查看總支出和總收入
class Boss implements AccountBookView {
private double totalConsumer;
private double totalIncome;
// 查看消費(fèi)的單子
public void view(ConsumerBill consumerBill) {
totalConsumer = totalConsumer + consumerBill.getAmount();
}
// 查看收入單子
public void view(IncomeBill incomeBill) {
totalIncome = totalIncome + incomeBill.getAmount();
}
public void getTotalConsumer() {
System.out.println("老板一共消費(fèi)了" + totalConsumer);
}
public void getTotalIncome() {
System.out.println("老板一共收入了" + totalIncome);
}
}
/**
* 會(huì)計(jì)類:訪問(wèn)者是會(huì)計(jì)扶檐,主要記錄每筆單子
*
* @author hgx
*
*/
class CPA implements AccountBookView {
int count = 0;
// 查看消費(fèi)的單子
public void view(ConsumerBill consumerBill) {
count++;
if (consumerBill.getItem().equals("消費(fèi)")) {
System.out.println("第" + count + "個(gè)單子消費(fèi)了:" + consumerBill.getAmount());
}
}
// 查看收入單子
public void view(IncomeBill incomeBill) {
if (incomeBill.getItem().equals("收入")) {
System.out.println("第" + count + "個(gè)單子收入了:" + incomeBill.getAmount());
}
}
}
/**
* 賬單類:用于添加賬單凶杖,和為每一個(gè)賬單添加訪問(wèn)者
*
* @author hgx
*
*/
class AccountBook {
private List<Bill> listBill = new ArrayList<Bill>();
// 添加單子
public void add(Bill bill) {
listBill.add(bill);
}
// 為每個(gè)賬單添加訪問(wèn)者
public void show(AccountBookView viewer) {
for (Bill b : listBill) {
b.accept(viewer);
}
}
}
/*
*測(cè)試類
*/
public class Test {
public static void main(String[] args) {
// 創(chuàng)建消費(fèi)和收入單子
Bill consumerBill = new ConsumerBill("消費(fèi)", 3000);
Bill incomeBill = new IncomeBill("收入", 5000);
Bill consumerBill2 = new ConsumerBill("消費(fèi)", 4000);
Bill incomeBill2 = new IncomeBill("收入", 8000);
// 添加單子
AccountBook accountBook = new AccountBook();
accountBook.add(consumerBill);
accountBook.add(incomeBill);
accountBook.add(consumerBill2);
accountBook.add(incomeBill2);
// 創(chuàng)建訪問(wèn)者
Boss boss = new Boss();
CPA cpa = new CPA();
// 接受訪問(wèn)者
accountBook.show(boss);
accountBook.show(cpa);
// boss查看總收入和總消費(fèi)
boss.getTotalConsumer();
boss.getTotalIncome();
}
}
測(cè)試結(jié)果:
第1個(gè)單子消費(fèi)了:3000.0
第1個(gè)單子收入了:5000.0
第2個(gè)單子消費(fèi)了:4000.0
第2個(gè)單子收入了:8000.0
老板一共消費(fèi)了:7000.0
老板一共收入了:13000.0
本文按照個(gè)人理解,全部通俗化解釋款筑,如有錯(cuò)誤希望指出 智蝠。