【移动应用开发技术】Android中怎么实现访问者模式_第1页
【移动应用开发技术】Android中怎么实现访问者模式_第2页
【移动应用开发技术】Android中怎么实现访问者模式_第3页
【移动应用开发技术】Android中怎么实现访问者模式_第4页
【移动应用开发技术】Android中怎么实现访问者模式_第5页
已阅读5页,还剩6页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

【移动应用开发技术】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. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论