-
訪問者模式
鎖定
定義(源於GoF《Design Pattern》):表示一個作用於某對象結構中的各元素的操作。它使你可以在不改變各元素類的前提下定義作用於這些元素的新操作。
從定義可以看出結構對象是使用訪問者模式必備條件,而且這個結構對象必須存在遍歷自身各個對象的方法。這便類似於Java語言當中的collection概念了。
- 中文名
- 訪問者模式
- 外文名
- Visitor Pattern
- 提出者
- GoF
- 類 型
- 行為類模式
訪問者模式涉及角色
1.Visitor 抽象訪問者角色,為該對象結構中具體元素角色聲明一個訪問操作接口。該操作接口的名字和參數標識了發送訪問請求給具體訪問者的具體元素角色,這樣訪問者就可以通過該元素角色的特定接口直接訪問它。
2.ConcreteVisitor.具體訪問者角色,實現Visitor聲明的接口。
3.Element 定義一個接受訪問操作(accept()),它以一個訪問者(Visitor)作為參數。
4.ConcreteElement 具體元素,實現了抽象元素(Element)所定義的接受操作接口。
5.ObjectStructure 結構對象角色,這是使用訪問者模式必備的角色。它具備以下特性:能枚舉它的元素;可以提供一個高層接口以允許訪問者訪問它的元素;如有需要,可以設計成一個複合對象或者一個聚集(如一個列表或無序集合)。
訪問者模式通用代碼實現
[java]
abstract class Element { public abstract void accept(IVisitor visitor); public abstract void doSomething(); } class ConcreteElement1 extends Element{ public void doSomething(){ System.out.println("這是元素1"); } public void accept(IVisitor visitor){ visitor.visit(this); } } class ConcreteElement2 extends Element{ public void doSomething(){ System.out.println("這是元素2"); } public void accept(IVisitor visitor){ visitor.visit(this); } } interface IVisitor{ public void visit(ConcreteElement1 el1); public void visit(ConcreteElement2 el2); } class Visitor implements IVisitor{ public void visit(ConcreteElement1 el1){ el1.doSomething(); } public void visit(ConcreteElement2 el2){ el2.doSomething(); } } class ObjectStruture{ public static List<Element> getList(){ List<Element>list = new ArrayList<Element>(); Random ran = newRandom(); for(int i = 0 ; i < 10 ; i ++){ int a=ran.nextInt(100); if(a>50){ list.add (newConcreteElement1()); }else{ list.add (newConcreteElement2()); } } return list; } } public class Client{ public static void main (String[]args){ List<Element> list = ObjectStruture.getList(); for(Elemente e:list){ e.accept(new Visitor()); } } }
訪問者模式模式特點
訪問者模式適用於數據結構相對穩定算法又易變化的系統。因為訪問者模式使得算法操作增加變得容易。若系統數據結構對象易於變化,經常有新的數據對象增加進來,則不適合使用訪問者模式。
訪問者模式的優點是增加操作很容易,因為增加操作意味着增加新的訪問者。訪問者模式將有關行為集中到一個訪問者對象中,其改變不影響系統數據結構。其缺點就是增加新的數據結構很困難。
訪問者模式優點
1、符合單一職責原則:凡是適用訪問者模式的場景中,元素類中需要封裝在訪問者中的操作必定是與元素類本身關係不大且是易變的操作,使用訪問者模式一方面符合單一職責原則,另一方面,因為被封裝的操作通常來説都是易變的,所以當發生變化時,就可以在不改變元素類本身的前提下,實現對變化部分的擴展。
2、擴展性良好:元素類可以通過接受不同的訪問者來實現對不同操作的擴展。
訪問者模式適用情況
2、 需要對一個對象結構中的對象進行很多不同的並且不相關的操作,而你想避免讓這些操作“污染”這些對象的類。Visitor模式使得你可以將相關的操作集中起來 定義在一個類中。
3、 當該對象結構被很多應用共享時,用Visitor模式讓每個應用僅包含需要用到的操作。
4、定義對象結構的類很少改變,但經常需要在此結構上定義新的操作。改變對象結構類需要重定義對所有訪問者的接口,這可能需要很大的代價。如果對象結構類經常改變,那麼可能還是在這些類中定義這些操作較好。
[1]
- 參考資料
-
- 1. java命名規範 .博客園.2015-03-12[引用日期2019-04-17]