操作複雜物件結構——訪問者模式(二)
26.2 訪問者模式概述
訪問者模式是一種較為複雜的行為型設計模式,它包含訪問者和被訪問元素兩個主要組成部分,這些被訪問的元素通常具有不同的型別,且不同的訪問者可以對它們進行不同的訪問操作。例如處方單中的各種藥品資訊就是被訪問的元素,而劃價人員和藥房工作人員就是訪問者。訪問者模式使得使用者可以在不修改現有系統的情況下擴充套件系統的功能,為這些不同型別的元素增加新的操作。
在使用訪問者模式時,被訪問元素通常不是單獨存在的,它們儲存在一個集合中,這個集合被稱為“物件結構”,訪問者通過遍歷物件結構實現對其中儲存的元素的逐個操作。
訪問者模式定義如下:
訪問者模式(Visitor Pattern):提供一個作用於某物件結構中的各元素的操作表示,它使我們可以在不改變各元素的類的前提下定義作用於這些元素的新操作。訪問者模式是一種物件行為型模式。 |
訪問者模式的結構較為複雜,其結構如圖26-2所示:
在訪問者模式結構圖中包含如下幾個角色:
●Vistor(抽象訪問者):抽象訪問者為物件結構中每一個具體元素類ConcreteElement宣告一個訪問操作,從這個操作的名稱或引數型別可以清楚知道需要訪問的具體元素的型別,具體訪問者需要實現這些操作方法,定義對這些元素的訪問操作。
●ConcreteVisitor(具體訪問者):具體訪問者實現了每個由抽象訪問者宣告的操作,每一個操作用於訪問物件結構中一種型別的元素。
●Element(抽象元素):抽象元素一般是抽象類或者介面,它定義一個accept()方法,該方法通常以一個抽象訪問者作為引數。【稍後將介紹為什麼要這樣設計。】
●ConcreteElement(具體元素):具體元素實現了accept()方法,在accept()方法中呼叫訪問者的訪問方法以便完成對一個元素的操作。
● ObjectStructure(物件結構):物件結構是一個元素的集合,它用於存放元素物件,並且提供了遍歷其內部元素的方法。它可以結合組合模式來實現,也可以是一個簡單的集合物件,如一個List物件或一個Set物件。
訪問者模式中物件結構儲存了不同型別的元素物件,以供不同訪問者訪問。訪問者模式包括兩個層次結構,一個是訪問者層次結構,提供了抽象訪問者和具體訪問者,一個是元素層次結構,提供了抽象元素和具體元素。相同的訪問者可以以不同的方式訪問不同的元素,相同的元素可以接受不同訪問者以不同訪問方式訪問。在訪問者模式中,增加新的訪問者無須修改原有系統,系統具有較好的可擴充套件性。
在訪問者模式中,抽象訪問者定義了訪問元素物件的方法,通常為每一種型別的元素物件都提供一個訪問方法,而具體訪問者可以實現這些訪問方法。這些訪問方法的命名一般有兩種方式:一種是直接在方法名中標明待訪問元素物件的具體型別,如visitElementA(ElementA elementA),還有一種是統一取名為visit(),通過引數型別的不同來定義一系列過載的visit()方法。當然,如果所有的訪問者對某一型別的元素的訪問操作都相同,則可以將操作程式碼移到抽象訪問者類中,其典型程式碼如下所示:
abstract class Visitor
{
public abstract void visit(ConcreteElementA elementA);
public abstract void visit(ConcreteElementB elementB);
public void visit(ConcreteElementC elementC)
{
//元素ConcreteElementC操作程式碼
}
}
在這裡使用了過載visit()方法的方式來定義多個方法用於操作不同型別的元素物件。在抽象訪問者Visitor類的子類ConcreteVisitor中實現了抽象的訪問方法,用於定義對不同型別元素物件的操作,具體訪問者類典型程式碼如下所示:
class ConcreteVisitor extends Visitor
{
public void visit(ConcreteElementA elementA)
{
//元素ConcreteElementA操作程式碼
}
public void visit(ConcreteElementB elementB)
{
//元素ConcreteElementB操作程式碼
}
}
對於元素類而言,在其中一般都定義了一個accept()方法,用於接受訪問者的訪問,典型的抽象元素類程式碼如下所示:
interface Element
{
public void accept(Visitor visitor);
}
需要注意的是該方法傳入了一個抽象訪問者Visitor型別的引數,即針對抽象訪問者進行程式設計,而不是具體訪問者,在程式執行時再確定具體訪問者的型別,並呼叫具體訪問者物件的visit()方法實現對元素物件的操作。在抽象元素類Element的子類中實現了accept()方法,用於接受訪問者的訪問,在具體元素類中還可以定義不同型別的元素所特有的業務方法,其典型程式碼如下所示:
class ConcreteElementA implements Element
{
public void accept(Visitor visitor)
{
visitor.visit(this);
}
public void operationA()
{
//業務方法
}
}
在具體元素類ConcreteElementA的accept()方法中,通過呼叫Visitor類的visit()方法實現對元素的訪問,並以當前物件作為visit()方法的引數。其具體執行過程如下:
(1) 呼叫具體元素類的accept(Visitor visitor)方法,並將Visitor子類物件作為其引數;
(2) 在具體元素類accept(Visitor visitor)方法內部呼叫傳入的Visitor物件的visit()方法,如visit(ConcreteElementA elementA),將當前具體元素類物件(this)作為引數,如visitor.visit(this);
(3) 執行Visitor物件的visit()方法,在其中還可以呼叫具體元素物件的業務方法。
這種呼叫機制也稱為“雙重分派”,正因為使用了雙重分派機制,使得增加新的訪問者無須修改現有類庫程式碼,只需將新的訪問者物件作為引數傳入具體元素物件的accept()方法,程式執行時將回撥在新增Visitor類中定義的visit()方法,從而增加新的元素訪問方式。
|
在訪問者模式中,物件結構是一個集合,它用於儲存元素物件並接受訪問者的訪問,其典型程式碼如下所示:
class ObjectStructure
{
private ArrayList<Element> list = new ArrayList<Element>(); //定義一個集合用於儲存元素物件
public void accept(Visitor visitor)
{
Iterator i=list.iterator();
while(i.hasNext())
{
((Element)i.next()).accept(visitor); //遍歷訪問集合中的每一個元素
}
}
public void addElement(Element element)
{
list.add(element);
}
public void removeElement(Element element)
{
list.remove(element);
}
}
在物件結構中可以使用迭代器對儲存在集合中的元素物件進行遍歷,並逐個呼叫每一個物件的accept()方法,實現對元素物件的訪問操作。
|
【作者:劉偉 http://blog.csdn.net/lovelion】
相關文章
- 如何使用建造者模式構造複雜物件?模式物件
- 極簡架構模式-資料訪問物件模式架構模式物件
- 物件解構與點操作訪問究竟誰快物件
- 訪問者模式模式
- 設計模式系列之建造者模式(Builder Pattern)——複雜物件的組裝與建立設計模式UI物件
- 行為模式-訪問者模式模式
- JVM裡物件的佈局和結構和訪問JVM物件
- python-訪問者模式Python模式
- 設計模式(十六)——訪問者模式設計模式
- 極簡設計模式-訪問者模式設計模式
- 深入淺出訪問者模式模式
- DesignPattern_訪問者模式_19模式
- 資料結構:時間複雜度資料結構時間複雜度
- 前端資料結構---複雜度分析前端資料結構複雜度
- 一、訪問物件屬性和方法的操作物件
- 設計模式 - ASM 中的訪問者模式設計模式ASM
- 設計模式學習之訪問者模式設計模式
- C#設計模式之訪問者模式C#設計模式
- 【趣味設計模式系列】之【訪問者模式】設計模式
- 代理模式-訪問物件的代理而非其本身模式物件
- 複雜的資料結構設計求解?資料結構
- Python3 解析複雜結構的 jsonPythonJSON
- 15.java設計模式之訪問者模式Java設計模式
- 設計模式(二十三)訪問者設計模式
- PHP設計模式-DAO (Data Access Objects) 資料訪問物件模式PHP設計模式Object物件
- Java進階篇設計模式之十 ---- 訪問者模式和中介者模式Java設計模式
- 物件導向設計的設計模式(二):結構型模式(附 Demo & UML類圖)物件設計模式
- 深入理解建造者模式 ——組裝複雜的例項模式
- 物件導向-設計模式-結構型物件設計模式
- 設計模式系列之代理模式(Proxy Pattern)——物件的間接訪問設計模式物件
- 重構複雜條件的規則設計模式 - levelup設計模式
- Android理解設計模式之組合模式、迭代器模式、訪問者模式Android設計模式
- 設計模式學習-使用go實現訪問者模式設計模式Go
- 「補課」進行時:設計模式(18)——訪問者模式設計模式
- 複雜連結串列的複製
- 資料結構複雜圖形儲存 PHP 版資料結構PHP
- 資料結構與演算法——複雜度分析資料結構演算法複雜度
- 複雜頁面架構架構
- 軟體設計模式系列之二十五——訪問者模式設計模式