1. 程式人生 > >【設計模式】訪問者模式

【設計模式】訪問者模式

模式定義

訪問者模式表示一個作用於某物件結構中的各元素的操作。它使你可以在不改變各元素類的前提下定義作用於這些元素的新操作。

下圖是該模式的類圖:
訪問者模式類圖

一個生動的例子

Element介面:
public interface ComputerPart {
	public void accept(ComputerPartVisitor computerPartVisitor);
}

Element實體類:
class Keyboard implements ComputerPart {
	@Override
	public void accept(ComputerPartVisitor computerPartVisitor)
{ computerPartVisitor.visit(this); } } Element實體類: class Monitor implements ComputerPart { @Override public void accept(ComputerPartVisitor computerPartVisitor) { computerPartVisitor.visit(this); System.out.println(this.getClass()); } } Element實體類: class Mouse implements ComputerPart { @Override
public void accept(ComputerPartVisitor computerPartVisitor) { computerPartVisitor.visit(this); } }
Visitor介面:
public interface ComputerPartVisitor {
	void visit(Mouse mouse);

	void visit(Keyboard keyboard);

	void visit(Monitor monitor);
}

Visitor實體類:
class ComputerPartDisplayVisitor implements
ComputerPartVisitor { @Override public void visit(Mouse mouse) { System.out.println("Displaying Mouse."); } @Override public void visit(Keyboard keyboard) { System.out.println("Displaying Keyboard."); } @Override public void visit(Monitor monitor) { System.out.println("Displaying Monitor."); } }
ObjectStructure類:
public class Computer {
	private ComputerPart[] parts;

	public Computer() {
		parts = new ComputerPart[] { new Mouse(), new Keyboard(), new Monitor() };
	}

	public void show(ComputerPartVisitor computerPartVisitor) {
		for (int i = 0; i < parts.length; i++) {
			parts[i].accept(computerPartVisitor);
		}
	}
}
測試類/客戶端類:
public class VisitorTest {
	public static void main(String[] args) {
		Computer computer = new Computer();
		computer.show(new ComputerPartDisplayVisitor());
	}
}

這是一個彩蛋

parts[i].accept(computerPartVisitor);這句話如果寫成computerPartVisitor.visit(parts[i]);,那麼ComputerPart類的accept方法就都不用寫了,直接這樣呼叫就好了。

你可以改改試試,首先computerPartVisitor.visit(parts[i]);是錯的,因為computerPartVisitor的visit函式中沒有引數是ComputerPart型別的,這是靜態分配,這樣的話你就必須要把parts[i]強轉成一種具體型別,這樣是肯定不可能的。

那為什麼parts[i].accept(computerPartVisitor);這樣就行了呢?首先根據動態分配會呼叫具體的accept方法,然後accept方法中呼叫computerPartVisitor.visit(this);,這個時候this代表的就是實際型別

參考

  1. Head First 設計模式[書籍]
  2. 百度百科之訪問者模式
  3. oodesign之訪問者模式
  4. 菜鳥教程之訪問者模式
  5. csdn之訪問者模式
  6. 簡書之訪問者模式