將做用於某種數據結構中的各元素的操做分離出來封裝成獨立的類,使其在不改變數據結構的前提下能夠添加做用於這些元素的新的操做,爲數據結構中的每一個元素提供多種訪問方式。它將對數據的操做與數據結構進行分離,是行爲類模式中最複雜的一種模式。數據結構
在現實生活中,有些集合對象存在多種不一樣的元素,且每種元素也存在多種不一樣的訪問者和處理方式。例如,咱們假如一臺電腦由CPU,內存,主板構成,去電腦城配電腦,店家須要根據不一樣的顧客對這三個商品打折,好比我的配電腦(CPU九折,內存八折,主板七折)、企業批量購買電腦(CPU,內存,主板統統七折);又好比這個訪問者模式在Java生成動態代理(ASM)中的應用比較普遍,這個呢我是個菜菜,就不細究了ide
那麼這些被處理的元素相對穩定而訪問方式多種多樣,若是用「訪問者模式」來處理比較方便。訪問者模式能把處理方法從數據結構中分離出來,並能夠根據須要增長新的處理方法,且不用修改原來的程序代碼,這提升了程序的擴展性和靈活性。this
一個結構當中的元素多樣而且比較穩定,每一種元素的訪問方式多種多樣spa
訪問者模式包含如下主要角色。代理
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; } }
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; } }
public class Computer { ComputerPart cpu = new CPU(); ComputerPart memory = new Memory(); ComputerPart board = new Board(); public void accept(Visitor v){ this.cpu.accept(v); this.memory.accept(v); this.board.accept(v); } public static void main(String[] args) { //CorpVisitor p = new CorpVisitor(); PersonelVisitor p = new PersonelVisitor(); new Computer().accept(p); System.out.println(p.totalPrice); } }