訪問者模式(Visitor)定義:表示一個做用於某對象結構中的各元素的操做。它使你能夠在不改變現有各元素的類的前提下定義做用於這些元素的新操做。
java
類型:行爲型模式(Behavioral)git
順口溜: 中訪策備迭 觀模命狀職解github
package com.amosli.dp.behavior.visitor; /** * VISITOR PATTERN * * @author amosli * */ public class Client { public static void main(String[] args) { ObjectStructure obj = new ObjectStructure(); obj.attach(new ConcreteElementA()); obj.attach(new ConcreteElementB()); obj.accept(new ConcreteVisitorA()); obj.accept(new ConcreteVisitorB()); } } package com.amosli.dp.behavior.visitor; public abstract class Element { public abstract void accept(Visitor visitor); } package com.amosli.dp.behavior.visitor; public abstract class Visitor { public abstract void visitConcreteElementA(ConcreteElementA elementA); public abstract void visitConcreteElementB(ConcreteElementB elementB); } package com.amosli.dp.behavior.visitor; import java.util.ArrayList; import java.util.List; public class ObjectStructure { private List<Element> list = new ArrayList<Element>(); public void attach(Element element) { list.add(element); } public void detach(Element element) { list.remove(element); } public void accept(Visitor visitor){ for (Element element : list) { element.accept(visitor); } } } package com.amosli.dp.behavior.visitor; public class ConcreteElementA extends Element { @Override public void accept(Visitor visitor) { visitor.visitConcreteElementA(this); } public void methodA() { } } package com.amosli.dp.behavior.visitor; public class ConcreteElementB extends Element { @Override public void accept(Visitor visitor) { visitor.visitConcreteElementB(this); } public void methodB() { } } package com.amosli.dp.behavior.visitor; public class ConcreteVisitorA extends Visitor { @Override public void visitConcreteElementA(ConcreteElementA elementA) { System.out.println(elementA.getClass().getName() + "被" + this.getClass().getName()+" 調用"); } @Override public void visitConcreteElementB(ConcreteElementB elementB) { System.out.println(elementB.getClass().getName() + "被" + this.getClass().getName()+" 調用"); } } package com.amosli.dp.behavior.visitor; public class ConcreteVisitorB extends Visitor{ @Override public void visitConcreteElementA(ConcreteElementA elementA) { System.out.println(elementA.getClass().getName() + "被" + this.getClass().getName()+" 調用"); } @Override public void visitConcreteElementB(ConcreteElementB elementB) { System.out.println(elementB.getClass().getName() + "被" + this.getClass().getName()+" 調用"); } }
根據對象的類型而對方法進行的選擇,就是分派(Dispatch),分派(Dispatch)又分爲兩種,即靜態分派和動態分派。shell
靜態分派(Static Dispatch)發生在編譯時期,分派根據靜態類型信息發生。靜態分派對於咱們來講並不陌生,方法重載就是靜態分派。ide
動態分派(Dynamic Dispatch)發生在運行時期,動態分派動態地置換掉某個方法。this
一、 一個對象結構包含不少類對象,它們有不一樣的接口,而你想對這些對象實施一些依賴於其具體類的操做。spa
二、 須要對一個對象結構中的對象進行不少不一樣的而且不相關的操做,而你想避免讓這些操做「污染」這些對象的類。Visitor模式使得你能夠將相關的操做集中起來 定義在一個類中。code
三、 當該對象結構被不少應用共享時,用Visitor模式讓每一個應用僅包含須要用到的操做。orm
四、定義對象結構的類不多改變,但常常須要在此結構上定義新的操做。改變對象結構類須要重定義對全部訪問者的接口,這可能須要很大的代價。若是對象結構類常常改變,那麼可能仍是在這些類中定義這些操做較好。對象
本系列文章源碼地址,https://github.com/amosli/dp 歡迎Fork & Star !!