




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
【移动应用开发技术】Android中怎么实现访问者模式
本篇文章给大家分享的是有关Android中怎么实现访问者模式,在下觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着在下一起来看看吧。一、介绍访问者模式是一种将数据操作与数据结构分离的设计模式,它是《设计模式》中23种设计模式中最复杂的一个,但它的使用频率并不高,正如《设计模式》的作者GOF对访问者模式的描述:大多数情况下,你不需要使用访问者模式,但是当你一旦需要使用它时,那你就是真的需要它了。访问者模式的基本想法是,软件系统中拥有一个由许多对象构成的、比较稳定的对象结构,这些对象的类都拥有一个accept方法用来接受访问者对象的访问。访问者是一个接口,它拥有一个visit方法,这个方法对访问到的对象结构中不同类型的元素作出不同的处理。在对象结构的一次访问过程中,我们遍历整个对象结构,对每一个元素都实施accept方法,在每一个元素的accept方法中会调用访问者的visit方法,从而使访问者得以处理对象结构的每一个元素,我们可以针对对象结构设计不同的访问者类来完成不同的操作,达到区别对待的效果。二、定义封装一些作用于某种数据结构中的各元素的操作,它可以在不改变这个数据结构的前提下定义作用于这些元素的新的操作。三、使用场景对象结构比较稳定,但经常需要在此对象结构上定义新的操作。需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免这些操作”污染“这些对象的类,也不希望在增加新操作时修改这些类。四、访问者模式的UML类图UML类图:角色介绍:Visitor:接口或抽象类,定义了对每一个元素的访问行为,参数就是可访问的元素,方法个数理论上是个元素个数一样的。因此,访问者模式要求被访问的对象结构要稳定,如果经常增删元素,必然会导致频繁修改Visitor接口,就不适合用访问者模式了。ConcreteVisitor:具体的访问者,定义具体的对每一个元素的具体访问行为。Element:抽象的元素接口或抽象类,定义了一个接待访问者的方法,让每个元素都可以被访问者访问。ElementA,ElementB:具体的元素类,提供接收访问方法的具体实现。这个具体实现通常是调用访问者提供的访问该元素的方法。ObjectStructure:定义对象结构,里面维护了一个元素的集合,并且迭代这些元素供访问者访问。五、简单示例情景:年终了,公司会给员工进行业绩考核。但是,不同领域的管理人员对于员工的评定标准不一样。现在员工有工程师和经理,评定者有CEO和CTO,我们假定CTO只关注工程师的代码量、经理的新产品数量,而CEO关注的是工程师的KPI和经理的KPI以及新产品数量。员工基类:/**
*
员工基类(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;//代码数量
public
Engineer(String
name)
{
super(name);
codeLines
=
new
Random().nextInt(10
*
10000);
}
@Override
public
void
accept(Visitor
visitor)
{
visitor.visit(this);
}
//工程师这一年写的代码数量
public
int
getCodeLines(){
return
codeLines;
}
}经理:/**
*
经理
*/
public
class
Manager
extends
Staff{
private
int
products;//产品数量
public
Manager(String
name)
{
super(name);
products
=
new
Random().nextInt(10);
}
@Override
public
void
accept(Visitor
visitor)
{
visitor.visit(this);
}
//一年内做的产品数量
public
int
getProducts(){
return
products;
}
}Visitor类:public
interface
Visitor
{
/**
*
访问工程师类型
*/
public
void
visit(Engineer
engineer);
/**
*
访问经理类型
*/
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("经理:"
+
+
",
KPI:"
+
manager.kpi
+
",
新产品数量
:"
+
manager.getProducts());
}
}CTO访问者:public
class
CTOVisitor
implements
Visitor
{
@Override
public
void
visit(Engineer
engineer)
{
System.out.println("工程师:"
+
+
",
代码数量:"
+
engineer.getCodeLines());
}
@Override
public
void
visit(Manager
manager)
{
System.out.println("经理:"
+
+",
产品数量
:"
+
manager.getProducts());
}
}员工报表://员工业务报表类(ObjectStructure)
public
class
BusinessReport
{
List<Staff>
mStaffs
=
new
LinkedList<Staff>();
public
BusinessReport()
{
mStaffs.add(new
Manager("王经理"));
mStaffs.add(new
Engineer("工程师-A"));
mStaffs.add(new
Engineer("工程师-B"));
mStaffs.add(new
Manager("李经理"));
mStaffs.add(new
Engineer("工程师-C"));
}
/**
*
为访问者展示报表
*
@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)
{
//构建报表
BusinessReport
report
=
new
BusinessReport();
System.out.println("=====
给CEO看报表
=====");
//设置访问者CEO
report.showReport(new
CEOVisitor());
System.out.println("=====
给CTO看报表
=====");
//设置访问者CTO
report.showReport(new
CTOVisitor());
}
}结果:=====
给CEO看报表
=====
经理:王经理,
KPI:2,
新产品数量
:5
工程师:工程师-A,
KPI:5
工程师:工程师-B,
KPI:7
经理:李经理,
KPI:9,
新产品数量
:8
工程师:工程师-C,
KPI:1
=====
给CTO看报表
=====
经理:王经理,
产品数量
:5
工程师:工程师-A,
代码数量:26238
工程师:工程师-B,
代码数量:8282
经理:李经理,
产品数量
:8
工程师:工程师-C,
代码数量:47927从上面代码中可以看出,如果要增加一个访问者,你新创建一个实现了Visitor接口的类,然后实现两个visit方法来对不同的元素进行不同的操作,从而达到数据对象与数据操作相分离的效果。如果不使用访问者模式,而又想对不同元素进行不同的操作,那么必定会使用if-else和类型转换,这使得代码难以升级维护。六、Android中的访问者模式安卓中的著名开源库ButterKnife、Dagger、Retrofit都是基于APT(AnnotationProcessingTools)实现。而编译注解核心依赖APT。当我们通过APT处理注解时,最终会将获取到的元素转换为相应的Element元素,以便获取到它们对应信息。那么元素基类的源码如下:(路径: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. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2020-2025年中国纽甜行业发展趋势预测及投资战略咨询报告
- 中国IA服务器市场发展前景预测及投资战略研究报告
- 2023-2028年中国茯苓种植行业市场深度分析及投资策略咨询报告
- 中国直流无刷电机行业市场全景评估及发展战略研究报告
- 广东羟甲基丙烯酰胺 项目申请报告
- 中国实验柜行业市场发展现状及投资战略咨询报告
- 薄膜太阳能电池项目节能评估报告(节能专用)
- 2025年中国铁道及电车道枕木行业市场调查研究及投资前景预测报告
- 中国带底盆磨砂花盆行业市场发展前景及发展趋势与投资战略研究报告(2024-2030)
- 中国EDI超纯水系统行业市场调研及投资战略研究报告
- 疏通马桶下水道培训课件
- 大邑蓄水池清淤施工方案
- 2024-2025学年高中物理 第四章 光的折射 1 光的折射定律说课稿1 教科版选修3-4
- 2025年度尿素肥料采购合同范本及环保要求解析3篇
- 职业发展计划和个人成长
- 溶洞相关知识培训课件
- 材料设备进场计划及保证措施
- 【大学课件】道路工程测量2
- 机械加工价格表
- 新材料在绿色制造中的应用及发展趋势分析
- 医用耗材采购风险管理工作总结
评论
0/150
提交评论