版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
【移動(dò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對(duì)訪問者模式的描述:大多數(shù)情況下,你不需要使用訪問者模式,但是當(dāng)你一旦需要使用它時(shí),那你就是真的需要它了。訪問者模式的基本想法是,軟件系統(tǒng)中擁有一個(gè)由許多對(duì)象構(gòu)成的、比較穩(wěn)定的對(duì)象結(jié)構(gòu),這些對(duì)象的類都擁有一個(gè)accept方法用來接受訪問者對(duì)象的訪問。訪問者是一個(gè)接口,它擁有一個(gè)visit方法,這個(gè)方法對(duì)訪問到的對(duì)象結(jié)構(gòu)中不同類型的元素作出不同的處理。在對(duì)象結(jié)構(gòu)的一次訪問過程中,我們遍歷整個(gè)對(duì)象結(jié)構(gòu),對(duì)每一個(gè)元素都實(shí)施accept方法,在每一個(gè)元素的accept方法中會(huì)調(diào)用訪問者的visit方法,從而使訪問者得以處理對(duì)象結(jié)構(gòu)的每一個(gè)元素,我們可以針對(duì)對(duì)象結(jié)構(gòu)設(shè)計(jì)不同的訪問者類來完成不同的操作,達(dá)到區(qū)別對(duì)待的效果。二、定義封裝一些作用于某種數(shù)據(jù)結(jié)構(gòu)中的各元素的操作,它可以在不改變這個(gè)數(shù)據(jù)結(jié)構(gòu)的前提下定義作用于這些元素的新的操作。三、使用場(chǎng)景對(duì)象結(jié)構(gòu)比較穩(wěn)定,但經(jīng)常需要在此對(duì)象結(jié)構(gòu)上定義新的操作。需要對(duì)一個(gè)對(duì)象結(jié)構(gòu)中的對(duì)象進(jìn)行很多不同的并且不相關(guān)的操作,而需要避免這些操作”污染“這些對(duì)象的類,也不希望在增加新操作時(shí)修改這些類。四、訪問者模式的UML類圖UML類圖:角色介紹:Visitor:接口或抽象類,定義了對(duì)每一個(gè)元素的訪問行為,參數(shù)就是可訪問的元素,方法個(gè)數(shù)理論上是個(gè)元素個(gè)數(shù)一樣的。因此,訪問者模式要求被訪問的對(duì)象結(jié)構(gòu)要穩(wěn)定,如果經(jīng)常增刪元素,必然會(huì)導(dǎo)致頻繁修改Visitor接口,就不適合用訪問者模式了。ConcreteVisitor:具體的訪問者,定義具體的對(duì)每一個(gè)元素的具體訪問行為。Element:抽象的元素接口或抽象類,定義了一個(gè)接待訪問者的方法,讓每個(gè)元素都可以被訪問者訪問。ElementA,ElementB:具體的元素類,提供接收訪問方法的具體實(shí)現(xiàn)。這個(gè)具體實(shí)現(xiàn)通常是調(diào)用訪問者提供的訪問該元素的方法。ObjectStructure:定義對(duì)象結(jié)構(gòu),里面維護(hù)了一個(gè)元素的集合,并且迭代這些元素供訪問者訪問。五、簡(jiǎn)單示例情景:年終了,公司會(huì)給員工進(jìn)行業(yè)績(jī)考核。但是,不同領(lǐng)域的管理人員對(duì)于員工的評(píng)定標(biāo)準(zhǔn)不一樣?,F(xiàn)在員工有工程師和經(jīng)理,評(pí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方法來對(duì)不同的元素進(jìn)行不同的操作,從而達(dá)到數(shù)據(jù)對(duì)象與數(shù)據(jù)操作相分離的效果。如果不使用訪問者模式,而又想對(duì)不同元素進(jìn)行不同的操作,那么必定會(huì)使用if-else和類型轉(zhuǎn)換,這使得代碼難以升級(jí)維護(hù)。六、Android中的訪問者模式安卓中的著名開源庫(kù)ButterKnife、Dagger、Retrofit都是基于APT(AnnotationProcessingTools)實(shí)現(xiàn)。而編譯注解核心依賴APT。當(dāng)我們通過APT處理注解時(shí),最終會(huì)將獲取到的元素轉(zhuǎn)換為相應(yīng)的Element元素,以便獲取到它們對(duì)應(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等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025民間借款合同范本
- 2024年行政及后勤崗位合同樣本3篇
- 2024年食堂承包及餐后清潔服務(wù)合同范本2篇
- 專家數(shù)據(jù)庫(kù)數(shù)據(jù)項(xiàng)表
- 2024年酒店餐飲供應(yīng)合同
- 2024年銅陵住房短期租賃合同3篇
- 2024年科研單位研究借款合同
- 2024年醫(yī)院電梯及特種設(shè)備維護(hù)保養(yǎng)服務(wù)合同樣本3篇
- 2024房地產(chǎn)企業(yè)專屬沙盤模型制作合作合同一
- 2024年大棚租賃合同范本:高效大棚租賃與農(nóng)業(yè)物聯(lián)網(wǎng)技術(shù)應(yīng)用合同3篇
- 2021-2022學(xué)年山東省濟(jì)寧市高一上學(xué)期期末考試英語試題(解析版)(不含聽力音頻)
- T-PPAC 402-2022 企業(yè)專利密集型產(chǎn)品評(píng)價(jià)方法
- 配電自動(dòng)化終端運(yùn)行維護(hù)管理規(guī)定
- 監(jiān)護(hù)人考試試題
- 中醫(yī)醫(yī)療技術(shù)相關(guān)性感染預(yù)防與控制
- 2024年工貿(mào)重點(diǎn)企業(yè)有限空間作業(yè)專家指導(dǎo)服務(wù)專題培訓(xùn)
- 2024年注冊(cè)安全工程師考試題庫(kù)及參考答案【完整版】
- 第十二章 全等三角形 作業(yè)設(shè)計(jì)-2023-2024學(xué)年人教版八年級(jí)數(shù)學(xué)上冊(cè)
- 建筑結(jié)構(gòu)荷載規(guī)范DBJ-T 15-101-2022
- 制藥專業(yè)畢業(yè)設(shè)計(jì)開題報(bào)告
- 普通心理學(xué)智慧樹知到期末考試答案2024年
評(píng)論
0/150
提交評(píng)論