訪問者(Visitor)

cdta發表於2015-01-22

情景:男人和女人!

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

結構圖:

interface State {
	void GetMan(Man concreteElementA);
	void GetWoman(Woman concreteElementB);
}

public class Fail implements State{
	@Override
	public void GetMan(Man concreteElementA) {
		System.out.println(concreteElementA.getClass() + "said");
	}

	@Override
	public void GetWoman(Woman concreteElementB) {
		System.out.println(concreteElementB.getClass() +"cry");		
	}
}
public class Success implements State{
	@Override
	public void GetMan(Man concreteElementA) {
		System.out.println(concreteElementA.getClass() +" happy");
	}

	@Override
	public void GetWoman(Woman concreteElementB) {
		System.out.println(concreteElementB.getClass() +" cry");
	}
}

interface Person {
	void Accept(State visitor);
}

public class Man implements Person{
	@Override
	public void Accept(State visitor) {
		visitor.GetMan(this);
	}
}

public class Woman implements Person{
	@Override
	public void Accept(State visitor) {
		visitor.GetWoman(this);
	}	
}

public class ObjectStructure {
	private List<Person> list = new ArrayList<Person>();
	public void Attach(Person person){
		list.add(person);
	}
	public void Detach(Person person){
		list.remove(person);
	}
	public void Display(State visitor){
		for (Person e : list) {
			e.Accept(visitor);
		}
	}
}

public class Client {
	public static void main(String[] args) {
		ObjectStructure o = new ObjectStructure();
		o.Attach(new Man());
		o.Attach(new Man());
		o.Attach(new Woman());
		Success visitor = new Success();
		o.Display(visitor);
		Fail v2= new Fail();
		o.Display(v2);
	}
}
訪問者模式的幾個特點:
訪問者模式把資料結構和作用於結構上的操作解耦合,使得操作集合可相對自由地演化。
訪問者模式適用於資料結構相對穩定演算法又易變化的系統。因為訪問者模式使得演算法操作增加變得容易。若系統資料結構物件易於變化,經常有新的資料物件增加進來,則不適合使用訪問者模式。
訪問者模式的優點是增加操作很容易,因為增加操作意味著增加新的訪問者。訪問者模式將有關行為集中到一個訪問者物件中,其改變不影響系統資料結構。其缺點就是增加新的資料結構很困難。
適用情況 :
1) 一個物件結構包含很多類物件,它們有不同的介面,而你想對這些物件實施一些依賴於其具體類的操作。
2) 需要對一個物件結構中的物件進行很多不同的並且不相關的操作,而你想避免讓這些操作“汙染”這些物件的類。Visitor模式使得你可以將相關的操作集中起來 定義在一個類中。 
3) 當該物件結構被很多應用共享時,用Visitor模式讓每個應用僅包含需要用到的操作。 
4) 定義物件結構的類很少改變,但經常需要在此結構上定義新的操作。改變物件結構類需要重定義對所有訪問者的介面,這可能需要很大的代價。如果物件結構類經常改變,那麼可能還是在這些類中定義這些操作較好。

相關文章