訪問者模式(Visitor Pattern)
類型:行為相關
定義:定義一個能夠實行在一個物件結構中對於所有元素的操作。訪問者讓你可以定義一個新的操作,而不必更動到被操作元素的類別介面。
解釋:首先,你有許多個繼承於某個介面的實作類別,當你想要給這些子類別共同的新功能時,就需要去更動原本的介面。透過訪問者模式可以打穿這個介面,將新的方法實作在訪問者類別中,訪問者擁有各種子類別的新功能實作,而在子類別的上層介面中定義一個接收訪問者的函數。如此一來,子類別可以在接收訪問者的方法中呼叫訪問者上的新實作功能,以此完成新功能的實現。滿複雜的。
參與者有以下4個:
接收者介面(Acceptor ):定義接收者的外觀與接收訪問者的方法。
接收者實作類別(ConcreteAcceptor):實作接收者,你會在這裡實作要調用訪問者上對應的實做功能。
訪問者介面(Visitor):定義每個接收者實作類別的新功能,讓這些接收者自己來調用。
訪問者實作類別(ConcreteVisitor):實作各種新功能。
精神:外掛功能與介面穿透。
目的:為了不修改原有介面,將新功能外掛到一個觀察者中,透過讓訪問者巡覽各個物件,呼叫對應的功能。
使用時機:需要可以外掛新功能給一系列的類別時。
優點:遵守對接收者的開閉原則,把某些功能特別獨立出來,並容易改造這個功能。
缺點:增加新接收者困難,會違背訪問者的開閉原則。訪問者對接收者有很高的耦合性,也降低了接收者功能的內聚性。需要暴露資訊給訪問者以時做新功能,破壞了封裝。
簡易程式範例:
public interface Acceptor { void Accept(Visitor visitor); } public class ConcreteAcceptorA : Acceptor { public void Accept(Visitor visitor) { visitor.NewFunction(this); } } public class ConcreteAcceptorB : Acceptor { public void Accept(Visitor visitor) { visitor.NewFunction(this); } } public class ConcreteAcceptorC : Acceptor { public void Accept(Visitor visitor) { visitor.NewFunction(this); } } public interface Visitor { void NewFunction(ConcreteAcceptorA acceptor); void NewFunction(ConcreteAcceptorB acceptor); void NewFunction(ConcreteAcceptorC acceptor); } public class ConcreteVisitor : Visitor { public void NewFunction(ConcreteAcceptorA acceptor) { //實作ConcreteAcceptorA的新功能 } public void NewFunction(ConcreteAcceptorB acceptor) { //實作ConcreteAcceptorB的新功能 } public void NewFunction(ConcreteAcceptorC acceptor) { //實作ConcreteAcceptorC的新功能 } } //我把Main函數召喚出來演示一下怎麼用 static void Main(string[] args) { List<Acceptor> acceptors = new List<Acceptor> { new ConcreteAcceptorA(), new ConcreteAcceptorB(), new ConcreteAcceptorC() }; Visitor visitor = new ConcreteVisitor(); acceptors.ForEach(x => x.Accept(visitor)); }
UML 類圖(取自維基百科):
版主你好,可否借我轉發好文?
讚讚
可以
讚讚