設計模式-訪問者模式

什麼是訪問者模式

什麼叫做訪問,如果大家學過數據結構,對於這點就很清晰了,遍歷就是訪問的一般形式,單獨讀取一個元素進行相應的處理也叫作訪問,讀取到想要查看的內容+對其進行處理就叫做訪問,那麼我們平常是怎麼訪問的,基本上就是直接拿著需要訪問的地址(引用)來讀寫內存就可以了。

最複雜的設計模式,並且使用頻率不高,《設計模式》的作者評價為:大多情況下,你不需要使用訪問者模式,但是一旦需要使用它時,那就真的需要使用了。

訪問者模式是一種將數據操作和數據結構分離的設計模式。(覺得太抽象,可以看下面的例子)。

訪問者模式解決了什麼問題

為什麼還要有一個訪問者模式呢,這就要放到OOP之中了,在面向對象編程的思想中,我們使用類來組織屬性,以及對屬性的操作,那麼我們理所當然的將訪問操作放到了類的內部,這樣看起來沒問題,但是當我們想要使用另一種遍歷方式要怎麼辦呢,我們必須將這個類進行修改,這在設計模式中是大忌,在設計模式中就要保證,對擴展開放,對修改關閉的開閉原則。

訪問者模式的使用場景

  1. 對象結構比較穩定,但經常需要在此對象結構上定義新的操作。
  2. 需要對一個對象結構中的對象進行很多不同的並且不相關的操作,而需要避免這些操作“汙染”這些對象的類,也不希望在增加新操作時修改這些類。

訪問者模式的UML類圖


設計模式-訪問者模式

訪問者模式

角色描述

  • Visitor:接口或者抽象類,定義了對每個 Element 訪問的行為,它的參數就是被訪問的元素,它的方法個數理論上與元素的個數是一樣的,因此,訪問者模式要求元素的類型要穩定,如果經常添加、移除元素類,必然會導致頻繁地修改 Visitor 接口,如果出現這種情況,則說明不適合使用訪問者模式。
  • ConcreteVisitor:具體的訪問者,它需要給出對每一個元素類訪問時所產生的具體行為。
  • Element:元素接口或者抽象類,它定義了一個接受訪問者(accept)的方法,其意義是指每一個元素都要可以被訪問者訪問。
  • ElementA、ElementB:具體的元素類,它提供接受訪問的具體實現,而這個具體的實現,通常情況下是使用訪問者提供的訪問該元素類的方法。
  • ObjectStructure:定義當中所提到的對象結構,對象結構是一個抽象表述,它內部管理了元素集合,並且可以迭代這些元素提供訪問者訪問。

如何使用訪問者模式

調用

package com.company;
public class Main {
public static void main(String[] args) {
// write your code here
Host host = new HostManager();
host.accept(new VisitorOne());
}
}

訪問者接口

package com.company;
public interface Visitor {
void visit(HostManager manager);
void visit(HostOne one);
void visit(HostTwo two);
void visit(HostThree three);
}

訪問者

package com.company;
public class VisitorOne implements Visitor {
@Override
public void visit(HostManager manager) {
System.out.println("現在訪問的是管家");

}
@Override
public void visit(HostOne one) {
System.out.println("現在訪問的是Host1");
}
@Override
public void visit(HostTwo two) {
System.out.println("現在訪問的是Host2");
}
@Override
public void visit(HostThree three) {
System.out.println("現在訪問的是Host3");
}
}





東道主接口
package com.company;
public interface Host {
void accept(Visitor visitor);
}
東道主管家
package com.company;
public class HostManager implements Host {
private Host hosts[];
public HostManager() {
this.hosts = new Host[]{new HostOne(),new HostTwo(),new HostThree()};
}
@Override
public void accept(Visitor visitor) {
for (int index = 0;index < this.hosts.length;index++) {
this.hosts[index].accept(visitor);
}
visitor.visit(this);
}
}

東道主1

package com.company;
public class HostOne implements Host {

@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}

東道主2

package com.company;
public class HostTwo implements Host {
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}

東道主3

package com.company;
public class HostThree implements Host {
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}


分享到:


相關文章: