設計模式-訪問者模式

訪問者模式(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 類圖(取自維基百科):

visitordiagram-svg
訪問者模式UML

visitor-pattern-animation

4 thoughts on “設計模式-訪問者模式

發表留言