Visitor 訪問者模式

模式簡介:

將做用於某種數據結構中的各元素的操做分離出來封裝成獨立的類,使其在不改變數據結構的前提下能夠添加做用於這些元素的新的操做,爲數據結構中的每一個元素提供多種訪問方式。它將對數據的操做與數據結構進行分離,是行爲類模式中最複雜的一種模式。數據結構

在現實生活中,有些集合對象存在多種不一樣的元素,且每種元素也存在多種不一樣的訪問者和處理方式。例如,咱們假如一臺電腦由CPU,內存,主板構成,去電腦城配電腦,店家須要根據不一樣的顧客對這三個商品打折,好比我的配電腦(CPU九折,內存八折,主板七折)、企業批量購買電腦(CPU,內存,主板統統七折);又好比這個訪問者模式在Java生成動態代理(ASM)中的應用比較普遍,這個呢我是個菜菜,就不細究了ide

那麼這些被處理的元素相對穩定而訪問方式多種多樣,若是用「訪問者模式」來處理比較方便。訪問者模式能把處理方法從數據結構中分離出來,並能夠根據須要增長新的處理方法,且不用修改原來的程序代碼,這提升了程序的擴展性和靈活性。this

使用場景:

一個結構當中的元素多樣而且比較穩定,每一種元素的訪問方式多種多樣spa

模式結構:

image

訪問者模式包含如下主要角色。代理

  1. 抽象訪問者(Visitor)角色:定義一個訪問具體元素的接口,爲每一個具體元素類對應一個訪問操做 visit() ,該操做中的參數類型標識了被訪問的具體元素。
  2. 具體訪問者(PersonelVisitor、CorpVisitor)角色:實現抽象訪問者角色中聲明的各個訪問操做,肯定訪問者訪問一個元素時該作什麼。
  3. 抽象元素(ComputerPart)角色:聲明一個包含接受操做 accept() 的接口,被接受的訪問者對象做爲 accept() 方法的參數。
  4. 具體元素(CPU、Memory、Board)角色:實現抽象元素角色提供的 accept() 操做,其方法體一般都是 visitor.visit(this) ,另外具體元素中可能還包含自己業務邏輯的相關操做。
  5. 對象結構(Computer)角色:是一個包含元素角色的容器,提供讓訪問者對象遍歷容器中的全部元素的方法

模式實例:

1. 抽象訪問者Visitor

interface Visitor{
    void visitCpu(CPU cpu);
 void visitMemory(Memory memory);
 void visitBoard(Board board);
}

2. 具體訪問者PersonelVisitor、CorpVisitor

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;
 }
}

3. 抽象元素ComputerPart

abstract class ComputerPart{
    abstract void accept(Visitor v);
 abstract double getPrice();
}

4. 具體元素CPU、Memory、Board

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;
 }
}

5. 對象結構Computer

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);
 }
}
相關文章
相關標籤/搜索