1. 程式人生 > >24】之訪問者模式(Visitor)

24】之訪問者模式(Visitor)

1      模式簡介

訪問者模式的定義:

訪問者模式將資料結構與資料操作進行了分離,解決了穩定的資料結構和易變的資料操作的耦合問題。

訪問者模式的優點:

1)        符合單一職責原則;

2)        優秀的擴充套件性;

3)        靈活性。

訪問者模式的缺點:

1)        具體元素對訪問者公佈細節,違反了迪米特原則;

2)        具體元素變更比較困難;

3)        違反了依賴倒置原則,依賴了具體類,沒有依賴抽象。

訪問者模式的適用場景:

1)        物件結構中物件對應的類很少改變,但經常需要在此物件結構上定義新的操作;

2)        需要對一個物件結構中的物件進行很多不同的並且不相關的操作,而需要避免讓這些操作"汙染"這些物件的類,也不希望在增加新操作時修改這些類。

2      案例

在這個例子中,我們通過訪問者模式,將電腦元件和呼叫電腦元件的方法進行解耦合。

具體程式碼如下:

電腦組成部分的介面ComputerPart中的程式碼:

public interface ComputerPart {
	public void accept(ComputerPartVisitor computerPartVisitor);
}
實現這個介面的有鍵盤類Keyboard、顯示器類Monitor和滑鼠類Mouse,這裡貼出鍵盤類Keyboard中的程式碼:
public class Keyboard implements ComputerPart {

	@Override
	public void accept(ComputerPartVisitor computerPartVisitor) {
		computerPartVisitor.visit(this);
	}
}

電腦實體類Computer中的程式碼:

public class Computer {
	ComputerPart[] parts;

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

	public void accept(ComputerPartVisitor computerPartVisitor) {
		for (int i = 0; i < parts.length; i++) {
			parts[i].accept(computerPartVisitor);
		}
		computerPartVisitor.visit(this);
	}
}
電腦元件訪問介面ComputerPartVisitor中的程式碼:
public interface ComputerPartVisitor {
	public void visit(Computer computer);

	public void visit(Mouse mouse);

	public void visit(Keyboard keyboard);

	public void visit(Monitor monitor);
}
電腦元件訪問介面的實現類ComputerPartDisplayVisitor中的程式碼:
public class ComputerPartDisplayVisitor implements ComputerPartVisitor {

	@Override
	public void visit(Computer computer) {
		System.out.println("Displaying Computer.");
	}

	@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.");
	}
}
測試類Test中的程式碼:
public class Test {
	public static void main(String[] args) {
		Computer computer = new Computer();
		computer.accept(new ComputerPartDisplayVisitor());
	}
}
執行結果如下圖所示: