




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
【移動應(yīng)用開發(fā)技術(shù)】Android中怎么實(shí)現(xiàn)訪問者模式
本篇文章給大家分享的是有關(guān)Android中怎么實(shí)現(xiàn)訪問者模式,在下覺得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著在下一起來看看吧。一、介紹訪問者模式是一種將數(shù)據(jù)操作與數(shù)據(jù)結(jié)構(gòu)分離的設(shè)計(jì)模式,它是《設(shè)計(jì)模式》中23種設(shè)計(jì)模式中最復(fù)雜的一個(gè),但它的使用頻率并不高,正如《設(shè)計(jì)模式》的作者GOF對訪問者模式的描述:大多數(shù)情況下,你不需要使用訪問者模式,但是當(dāng)你一旦需要使用它時(shí),那你就是真的需要它了。訪問者模式的基本想法是,軟件系統(tǒng)中擁有一個(gè)由許多對象構(gòu)成的、比較穩(wěn)定的對象結(jié)構(gòu),這些對象的類都擁有一個(gè)accept方法用來接受訪問者對象的訪問。訪問者是一個(gè)接口,它擁有一個(gè)visit方法,這個(gè)方法對訪問到的對象結(jié)構(gòu)中不同類型的元素作出不同的處理。在對象結(jié)構(gòu)的一次訪問過程中,我們遍歷整個(gè)對象結(jié)構(gòu),對每一個(gè)元素都實(shí)施accept方法,在每一個(gè)元素的accept方法中會調(diào)用訪問者的visit方法,從而使訪問者得以處理對象結(jié)構(gòu)的每一個(gè)元素,我們可以針對對象結(jié)構(gòu)設(shè)計(jì)不同的訪問者類來完成不同的操作,達(dá)到區(qū)別對待的效果。二、定義封裝一些作用于某種數(shù)據(jù)結(jié)構(gòu)中的各元素的操作,它可以在不改變這個(gè)數(shù)據(jù)結(jié)構(gòu)的前提下定義作用于這些元素的新的操作。三、使用場景對象結(jié)構(gòu)比較穩(wěn)定,但經(jīng)常需要在此對象結(jié)構(gòu)上定義新的操作。需要對一個(gè)對象結(jié)構(gòu)中的對象進(jìn)行很多不同的并且不相關(guān)的操作,而需要避免這些操作”污染“這些對象的類,也不希望在增加新操作時(shí)修改這些類。四、訪問者模式的UML類圖UML類圖:角色介紹:Visitor:接口或抽象類,定義了對每一個(gè)元素的訪問行為,參數(shù)就是可訪問的元素,方法個(gè)數(shù)理論上是個(gè)元素個(gè)數(shù)一樣的。因此,訪問者模式要求被訪問的對象結(jié)構(gòu)要穩(wěn)定,如果經(jīng)常增刪元素,必然會導(dǎo)致頻繁修改Visitor接口,就不適合用訪問者模式了。ConcreteVisitor:具體的訪問者,定義具體的對每一個(gè)元素的具體訪問行為。Element:抽象的元素接口或抽象類,定義了一個(gè)接待訪問者的方法,讓每個(gè)元素都可以被訪問者訪問。ElementA,ElementB:具體的元素類,提供接收訪問方法的具體實(shí)現(xiàn)。這個(gè)具體實(shí)現(xiàn)通常是調(diào)用訪問者提供的訪問該元素的方法。ObjectStructure:定義對象結(jié)構(gòu),里面維護(hù)了一個(gè)元素的集合,并且迭代這些元素供訪問者訪問。五、簡單示例情景:年終了,公司會給員工進(jìn)行業(yè)績考核。但是,不同領(lǐng)域的管理人員對于員工的評定標(biāo)準(zhǔn)不一樣?,F(xiàn)在員工有工程師和經(jīng)理,評定者有CEO和CTO,我們假定CTO只關(guān)注工程師的代碼量、經(jīng)理的新產(chǎn)品數(shù)量,而CEO關(guān)注的是工程師的KPI和經(jīng)理的KPI以及新產(chǎn)品數(shù)量。員工基類:/**
*
員工基類(Element)
*/
public
abstract
class
Staff
{
//員工姓名
public
String
name;
//員工KPI
public
int
kpi;
public
Staff(String
name)
{
super();
=
name;
this.kpi
=
new
Random().nextInt(10);
}
//接受Visitor的訪問
public
abstract
void
accept(Visitor
visitor);
}工程師:/**
*
工程師
*/
public
class
Engineer
extends
Staff{
private
int
codeLines;//代碼數(shù)量
public
Engineer(String
name)
{
super(name);
codeLines
=
new
Random().nextInt(10
*
10000);
}
@Override
public
void
accept(Visitor
visitor)
{
visitor.visit(this);
}
//工程師這一年寫的代碼數(shù)量
public
int
getCodeLines(){
return
codeLines;
}
}經(jīng)理:/**
*
經(jīng)理
*/
public
class
Manager
extends
Staff{
private
int
products;//產(chǎn)品數(shù)量
public
Manager(String
name)
{
super(name);
products
=
new
Random().nextInt(10);
}
@Override
public
void
accept(Visitor
visitor)
{
visitor.visit(this);
}
//一年內(nèi)做的產(chǎn)品數(shù)量
public
int
getProducts(){
return
products;
}
}Visitor類:public
interface
Visitor
{
/**
*
訪問工程師類型
*/
public
void
visit(Engineer
engineer);
/**
*
訪問經(jīng)理類型
*/
public
void
visit(Manager
manager);
}CEO訪問者:public
class
CEOVisitor
implements
Visitor
{
@Override
public
void
visit(Engineer
engineer)
{
System.out.println("工程師:"
+
+
",
KPI:"
+
engineer.kpi);
}
@Override
public
void
visit(Manager
manager)
{
System.out.println("經(jīng)理:"
+
+
",
KPI:"
+
manager.kpi
+
",
新產(chǎn)品數(shù)量
:"
+
manager.getProducts());
}
}CTO訪問者:public
class
CTOVisitor
implements
Visitor
{
@Override
public
void
visit(Engineer
engineer)
{
System.out.println("工程師:"
+
+
",
代碼數(shù)量:"
+
engineer.getCodeLines());
}
@Override
public
void
visit(Manager
manager)
{
System.out.println("經(jīng)理:"
+
+",
產(chǎn)品數(shù)量
:"
+
manager.getProducts());
}
}員工報(bào)表://員工業(yè)務(wù)報(bào)表類(ObjectStructure)
public
class
BusinessReport
{
List<Staff>
mStaffs
=
new
LinkedList<Staff>();
public
BusinessReport()
{
mStaffs.add(new
Manager("王經(jīng)理"));
mStaffs.add(new
Engineer("工程師-A"));
mStaffs.add(new
Engineer("工程師-B"));
mStaffs.add(new
Manager("李經(jīng)理"));
mStaffs.add(new
Engineer("工程師-C"));
}
/**
*
為訪問者展示報(bào)表
*
@param
visitor
如CEO、CTO
*/
public
void
showReport(Visitor
visitor){
for(Staff
staff
:
mStaffs){
staff.accept(visitor);
}
}
}Client訪問:public
class
Client
{
public
static
void
main(String[]
args)
{
//構(gòu)建報(bào)表
BusinessReport
report
=
new
BusinessReport();
System.out.println("=====
給CEO看報(bào)表
=====");
//設(shè)置訪問者CEO
report.showReport(new
CEOVisitor());
System.out.println("=====
給CTO看報(bào)表
=====");
//設(shè)置訪問者CTO
report.showReport(new
CTOVisitor());
}
}結(jié)果:=====
給CEO看報(bào)表
=====
經(jīng)理:王經(jīng)理,
KPI:2,
新產(chǎn)品數(shù)量
:5
工程師:工程師-A,
KPI:5
工程師:工程師-B,
KPI:7
經(jīng)理:李經(jīng)理,
KPI:9,
新產(chǎn)品數(shù)量
:8
工程師:工程師-C,
KPI:1
=====
給CTO看報(bào)表
=====
經(jīng)理:王經(jīng)理,
產(chǎn)品數(shù)量
:5
工程師:工程師-A,
代碼數(shù)量:26238
工程師:工程師-B,
代碼數(shù)量:8282
經(jīng)理:李經(jīng)理,
產(chǎn)品數(shù)量
:8
工程師:工程師-C,
代碼數(shù)量:47927從上面代碼中可以看出,如果要增加一個(gè)訪問者,你新創(chuàng)建一個(gè)實(shí)現(xiàn)了Visitor接口的類,然后實(shí)現(xiàn)兩個(gè)visit方法來對不同的元素進(jìn)行不同的操作,從而達(dá)到數(shù)據(jù)對象與數(shù)據(jù)操作相分離的效果。如果不使用訪問者模式,而又想對不同元素進(jìn)行不同的操作,那么必定會使用if-else和類型轉(zhuǎn)換,這使得代碼難以升級維護(hù)。六、Android中的訪問者模式安卓中的著名開源庫ButterKnife、Dagger、Retrofit都是基于APT(AnnotationProcessingTools)實(shí)現(xiàn)。而編譯注解核心依賴APT。當(dāng)我們通過APT處理注解時(shí),最終會將獲取到的元素轉(zhuǎn)換為相應(yīng)的Element元素,以便獲取到它們對應(yīng)信息。那么元素基類的源碼如下:(路徑:javax.lang.model.element.Element)public
interface
Element
extends
javax.lang.model.AnnotatedConstruct
{
/**
*
Returns
the
{@code
kind}
of
this
element.
*
*
@return
the
kind
of
this
element
*/
ElementKind
getKind();//獲取元素類型
//代碼省略
/**
*
Applies
a
visitor
to
this
element.
*
*
@param
<R>
the
return
type
of
the
visitor's
methods
*
@param
<P>
the
type
of
the
additional
parameter
to
the
visitor's
methods
*
@param
v
the
visitor
operating
on
this
element
*
@param
p
additional
parameter
to
the
visitor
*
@return
a
visitor-specified
result
*/
<R,
P>
R
accept(ElementVisitor<R,
P>
v,
P
p);//接受訪問者的訪問
}ElementVisitor就是訪問者類型,ElementVisitor源碼如下:public
interface
ElementVisitor<R,
P>
{
/**
*
Visits
an
element.
*
@param
e
the
element
to
visit
*
@param
p
a
visitor-specified
parameter
*
@return
a
visitor-specified
result
*/
R
visit(Element
e,
P
p);
/**
*
A
convenience
method
equivalent
to
{@code
v.visit(e,
null)}.
*
@param
e
the
element
to
visit
*
@return
a
visitor-specified
result
*/
R
visit(Element
e);
/**
*
Visits
a
package
element.
*
@param
e
the
element
to
visit
*
@param
p
a
visitor-specified
parameter
*
@return
a
visitor-specified
result
*/
R
visitPackage(PackageElement
e,
P
p);
/**
*
Visits
a
type
element.
*
@param
e
the
element
to
visit
*
@param
p
a
visitor-specified
parameter
*
@return
a
visitor-specified
result
*/
R
visitType(TypeElement
e,
P
p);
/**
*
Visits
a
variable
element.
*
@param
e
the
element
to
visit
*
@param
p
a
visitor-specified
parameter
*
@return
a
visitor-specified
result
*/
R
visitVariable(VariableElement
e,
P
p);
/**
*
Visits
an
executable
element.
*
@param
e
the
element
to
visit
*
@param
p
a
visitor-specified
parameter
*
@return
a
visitor-specified
result
*/
R
visitExecutable(ExecutableElement
e,
P
p);
/**
*
Visits
a
type
parameter
element.
*
@param
e
the
element
to
visit
*
@param
p
a
visitor-specified
parameter
*
@return
a
visitor-specified
result
*/
R
visitTypeParameter(TypeParameterElement
e,
P
p);
/**
*
Visits
an
unknown
kind
of
element.
*
This
can
occur
if
the
language
evolves
an
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 倉庫貨物入庫流程分析計(jì)劃
- 第11課《送東陽馬生序》教學(xué)設(shè)計(jì)-2023-2024學(xué)年統(tǒng)編版語文九年級下冊
- 《甕福(集團(tuán))有限責(zé)任公司對門坡磷礦(變更)礦產(chǎn)資源綠色開發(fā)利用方案(三合一)》評審意見
- 《貴州省安龍縣戈塘金礦(整合)(變更)礦產(chǎn)資源綠色開發(fā)利用方案(三合一)》專家組評審意見
- 銀行信貸知識培訓(xùn)課件
- 酒吧衛(wèi)生知識培訓(xùn)課件
- 老年護(hù)理皮腫
- 供應(yīng)鏈金融管理科學(xué)與工程
- 統(tǒng)編版小學(xué)語文二年級下冊《語文園地七》精美課件
- 2025年海南貨運(yùn)資格考試答案
- deepseek在智慧城市建設(shè)中的應(yīng)用前景
- 2025年九江職業(yè)大學(xué)高職單招職業(yè)技能測試近5年??及鎱⒖碱}庫含答案解析
- 石塑復(fù)合木地板施工方案
- 《智能網(wǎng)聯(lián)汽車 自動駕駛系統(tǒng)要求及測試方法 第1部分:高速公路及城市快速路》
- 中儲糧招聘考試題庫
- 《GNSS接收機(jī)矢量跟蹤算法研究》
- 2024年立體卷鐵心變壓器市場調(diào)查報(bào)告
- DB14-T 1123-2024 紅小豆、玉米間作技術(shù)規(guī)程
- 人工智能:AIGC基礎(chǔ)與應(yīng)用 課件 02模塊二AIGC 提示詞與提示工程
- 【課件】溶質(zhì)的質(zhì)量分?jǐn)?shù)(第1課時(shí))九年級化學(xué)人教版(2024)下冊
- 2025高考數(shù)學(xué)專項(xiàng)復(fù)習(xí):導(dǎo)數(shù)的27個(gè)模塊專練(含答案)
評論
0/150
提交評論