設計模式學習之訪問者模式

2021-07-27 05:51:06 字數 4022 閱讀 4485

訪問者模式在設計模式中應該算是比較複雜的了,但也不能成為我們不學習的理由。

定義:封裝某些作用於某種資料結構中各元素的操作,它可以在不改變資料結構的前提下定義作用於這些元素的新的操作。

聽起來就很繞,首先看資料結構這四個關鍵字,這就是不變的部分。比如說世界上只有男人和女人,當然(其他的忽略吧),這個就是很穩定的。如果是資料結構頻繁變化的是不太適合用這個模式的。

那麼變化的部分呢?

資料結構各個原色的操作,也就說變的是操作。

下面我舉個例子,這也是我**裡面的例子。

我們現在的教育體系,從我們上學開始一直到大學結束,還是相對來說比較穩定的,為了方便寫(其實是偷懶),我假設只有三種學校,而不是我們從幼兒園到初中,高中,大學的節奏。

而每乙個階段,都有要學習的相同科目。

比如說語文,從小學到大學可是都有的吧。

那麼這個語文就是所說的操作

當然,在這個例子裡面其實有乙個問題,學科其實也是很穩定的,但是我們假設學科是不穩定的,我現在只想到這個適應場景。

最開始,只有乙個語文學科,但是每個階段學習的語文都是不一樣的,小學你可能只是認識字,初中高中你應該會造句寫作文了閱讀文章,大學可能學的是更加偏應用的應用文。

話不多說,我們上**。

首先是抽象的學校類

public

abstract

class school

public

void

setname(string name)

public

abstract

void

acceptteach(subject subject);

}

接下來就是我們繼承學校類的

小學類

public

class

primaryschool

extends

school

@override

public

void

acceptteach(subject subject)

}

中學類

public

class

middleschool

extends

school

@override

public

void

acceptteach(subject subject)

}

大學類

public

class

highschool

extends

school

@override

public

void

acceptteach(subject subject)

}

我們發現累在抽象的父類裡面有乙個抽象的方法acceptteach,接受乙個學科

這裡我把這個寫成了介面,至於具體是介面還是抽象類各位根據實際情況判斷。

所以學科類來了

public

inte***ce subject

現在我們來寫實現類

public

class

chinese

implements

subject

@override

public

void

middleteach(school school)

@override

public

void

highteach(school school)

}

現在我們寫乙個測試類

public

class testvisitor

}

我們現在看到,結果是什麼呢?

xiao xue:一 二 三

zhong xue:誰知盤中餐

da xue:楊柳岸曉風殘月

看到這裡,大家有沒有發現什麼呢?

我們應該知道有乙個設計原則

類應該對修改關閉,而對擴充套件開放。

我們現在想想,如果我們現在的學校需要增加了新的課程,比如說 數學。

那麼我們需要做什麼呢?

我們現在只需要增加乙個實現學科類的數學類,並且實現介面裡面的方法就好了

public

class

math

implements

subject

@override

public

void

middleteach(school school)

@override

public

void

highteach(school school)

}

而其他的類呢?

什麼都不用改變!

看看我們的測試結果

public

class testvisitor

}

xiao xue:1+1

zhong xue:log(2)

da xue:csc x (sec x)

說了這麼多,我們學習所謂訪問者那麼在這裡面誰是訪問者呢?

class a   

public

void

method2(b b)

} class b

}

我們主要來看一下在類a中,方法method1和方法method2的區別在**,方法method1很簡單,就是列印出一句「我是a」;方法method2稍微複雜一點,使用類b作為引數,並呼叫類b的showa方法。再來看一下類b的showa方法,showa方法使用類a作為引數,然後呼叫類a的method1方法,可以看到,method2方法繞來繞去,無非就是呼叫了一下自己的method1方法而已,它的執行結果應該也是「我是a

所以上面的例子我們也就看出來了 誰是訪問者呢?

那麼就是所有的操作類 也就是訪問者,語文會訪問所有的元素,所有的學校類

數學也會訪問所有的元素累

而其實一般來說,操作累應該還有乙個遍歷的方法

就是把所有的元素都放在乙個集合或者容器裡面

訪問者模式中物件結構儲存了不同型別的元素物件,以供不同訪問者訪問。

我的例子只是用到了乙個,沒有這麼寫

其實這是一種雙重抽象,

訪問者模式包括兩個層次結構,乙個是訪問者層次結構,提供了抽象訪問者和具體訪問者,乙個是元素層次結構,提供了抽象元素和具體元素。

相同的訪問者可以以不同的方式訪問不同的元素,相同的元素可以接受不同訪問者以不同訪問方式訪問。在訪問者模式中,增加新的操作無須修改原有系統,系統具有較好的可擴充套件性

訪問者模式並不是那麼完美,它也有著致命的缺陷:增加新的元素模擬較困難。通過訪問者模式的**可以看到,在訪問者類中,每乙個元素類都有它對應的處理方法,也就是說,每增加乙個元素類都需要修改訪問者類(也包括訪問者類的子類或者實現類),修改起來相當麻煩。也就是說,在元素類數目不確定的情況下,應該慎用訪問者模式。所以,訪問者模式比較適用於對已有功能的重構,比如說,乙個專案的基本功能已經確定下來,元素類的資料已經基本確定下來不會變了,會變的只是這些元素內的相關操作,這時候,我們可以使用訪問者模式對原有的**進行重構一遍,這樣一來,就可以在不修改各個元素類的情況下,對原有功能進行修改。

設計模式之訪問者模式

先看一下下面這段 class person public string getaction public void setaction string action public void getconclusion else if action exciting else if action gri...

設計模式之訪問者模式

我們去銀行櫃檯辦業務,一般情況下會開幾個個人業務櫃檯的,你去其中任何乙個櫃檯辦理都是可以的。我們的訪問者模式可以很好付諸在這個場景中 對於銀行櫃檯來說,他們是不用變化的,就是說今天和明天提供個人業務的櫃檯是不需要有變化的。而我們作為訪問者,今天來銀行可能是取消費流水,明天來銀行可能是去辦理手機銀行業...

設計模式之訪問者模式

定義 表示一介作用於某個物件結構中的各元素的操作。它使你可以在不改變各元素的類的前提下定義作用於這些元素的新操作。結構圖 示例 public inte ce vistor public class concretevisitor1 implements vistor override public ...