訪問者模式的目的是封裝一些施加于某種數據結構元素之上的操作。一旦這些操作需要修改的話,接受這個操作的數據結構則可以保持不變。
訪問者模式適用于數據結構相對未定的系統,它把數據結構和作用于結構上的操作之間的耦合解脫開,使得操作集合可以相對自由地演化。
數據結構的每一個節點都可以接受一個訪問者的調用,此節點向訪問者對象傳入節點對象,而訪問者對象則反過來執行節點對象的操作。這樣的過程叫做"雙重分派"。節點調用訪問者,將它自己傳入,訪問者則將某算法針對此節點執行。
雙重分派意味著施加于節點之上的操作是基于訪問者和節點本身的數據類型,而不僅僅是其中的一者。
一,結構:
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
抽象訪問者(Visitor)角色 :聲明了一個或者多個訪問操作,形成所有的具體元素角色必須實現的接口。
具體訪問者(ConcreteVisitor)角色 :實現抽象訪問者角色所聲明的接口,也就是抽象訪問者所聲明的各個訪問操作。
抽象節點(Node)角色 :聲明一個接受操作,接受一個訪問者對象作為一個參量。
具體節點(Node)角色 :實現了抽象元素所規定的接受操作。
結構對象(ObiectStructure)角色 :有如下的一些責任,可以遍歷結構中的所有元素;如果需要,提供一個高層次的接口讓訪問者對象可以訪問每一個元素;如果需要,可以設計成一個復合對象或者一個聚集,如列(List)或集合(Set)。
二,示例代碼:
/** * 抽象訪問者(Visitor)角色 * @author Salmon * */ public interface Visitor { public void visitConcreteElementA(ConcreteElementA concreteElementA); public void visitConcreteElementB(ConcreteElementB concreteElementB); } /** * 具體訪問者(ConcreteVisitor)角色 * @author Salmon * */ public class ConcreteVisitor1 implements Visitor { public void visitConcreteElementA(ConcreteElementA concreteElementA) { System.out.println(""); } public void visitConcreteElementB(ConcreteElementB concreteElementB) { System.out.println(""); } } /** * 具體訪問者(ConcreteVisitor)角色 * @author user * */ public class ConcreteVisitor2 implements Visitor { public void visitConcreteElementA(ConcreteElementA concreteElementA) { // Console.WriteLine( "{0} visited by {1}", // concreteElementA, this ); } public void visitConcreteElementB(ConcreteElementB concreteElementB) { // Console.WriteLine( "{0} visited by {1}", // concreteElementB, this ); } } /** * 抽象節點(Node)角色 * @author Salmon * */ public interface Element { public void accept(Visitor visitor); } /** * 具體節點(Node)角色 * @author Salmon * */ public class ConcreteElementA implements Element { public void accept(Visitor visitor) { visitor.visitConcreteElementA(this); } public void OperationA() { } } /** * 具體節點(Node)角色 * @author Salmon * */ public class ConcreteElementB implements Element { public void accept(Visitor visitor) { visitor.visitConcreteElementB(this); } public void OperationB() { } } public class ObjectStructure { private ArrayList<Element> elements = new ArrayList<Element>(); public void attach(Element element) { elements.add(element); } public void detach(Element element) { elements.remove(element); } public void accept(Visitor visitor) { for (Element e : elements) e.accept(visitor); } } /** * 客戶端代碼 * @author Salmon * */ public class Client { public static void main(String[] args) { ObjectStructure o = new ObjectStructure(); o.attach(new ConcreteElementA()); o.attach(new ConcreteElementB()); ConcreteVisitor1 v1 = new ConcreteVisitor1(); ConcreteVisitor2 v2 = new ConcreteVisitor2(); o.accept(v1); o.accept(v2); } }
?
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
