您的位置:首页 > 编程语言 > Java开发

读书笔记_java设计模式深入研究 第九章 访问者模式 Vistor

2015-01-04 17:30 671 查看
1,访问者模式的目的是封装一些施加于某种数据结构元素之上的操作,一旦这些操作需要修改的话,接受这个操作的数据结构可以保持不变。为不同类型的元素提供多种访问操作方式,且可以在不修改原有系统的情况下增加新的操作方式,这就是访问者模式的动机。

2,UML图:





3,访问者角色:

IElement:抽象的事物元素功能接口,定义了固定功能方法以及可变功能方法接口。

Element:具体功能的实现类。

IVisitor:访问者接口,为所有访问者对象声明一个visit方法,用来代表为对象结构添加的功能,原则上可以代表任意功能。

Visitor:具体访问实现类,实现要正真被添加到对象结构中的功能。

4,基本代码例子:

/**
*
*@(#)IShape.java
*@Packagepattern.chp09.visitor.simple
*
*Copyright©JINGCorporation.Allrightsreserved.
*
*/
packagepattern.chp09.visitor.simple;
/**
*类描述:抽象需求接口
*
*@author:Jing
*@version$Id:Exp$
*
*History:Dec29,20142:40:16PMJingCreated.
*
*/
publicinterfaceIShape{
/**
*
*方法说明:获取图形面积
*
*Author:Jing
*CreateDate:Dec29,20142:40:41PM
*
*@return
*@returnfloat
*/
floatgetArea();
/**
*
*方法说明:获取周长
*
*Author:Jing
*CreateDate:Dec29,20142:41:04PM
*
*@return
*@returnfloat
*/
floatgetLength();
/**
*
*方法说明:传入访问者对象和方法名
*
*Author:Jing
*CreateDate:Dec29,20142:43:17PM
*
*@paramv
*@return
*@returnObject
*/
Objectaccept(IVisitorv);
}
[/code]

/**
*
*@(#)Triangle.java
*@Packagepattern.chp09.visitor.simple
*
*Copyright©JINGCorporation.Allrightsreserved.
*
*/
packagepattern.chp09.visitor.simple;
/**
*类描述:三角形
*
*@author:Jing
*@version$Id:Exp$
*
*History:Dec29,20142:45:54PMJingCreated.
*
*/
publicclassTriangleimplementsIShape{
floatx1,y1,x2,y2,x3,y3;//三角形三点坐标
publicTriangle(floatx1,floaty1,floatx2,floaty2,floatx3,floaty3){
this.x1=x1;
this.y1=y1;
this.x2=x2;
this.y2=y2;
this.x3=x3;
this.y3=y3;
}
publicObjectaccept(IVisitorv){
returnv.visit(this);
}
publicfloatgetArea(){
floata=getDist(x1,y1,x2,y2);
floatb=getDist(x1,y1,x3,y3);
floatc=getDist(x2,y2,x3,y3);
floats=(a+b+c)/2;
return(float)Math.sqrt(s*(s-a)*(s-b)*(s-c));
}
publicfloatgetLength(){
floata=getDist(x1,y1,x2,y2);
floatb=getDist(x1,y1,x3,y3);
floatc=getDist(x2,y2,x3,y3);
returna+b+c;
}
/**
*
*方法说明:求任意两点距离
*
*Author:JingCreateDate:Dec29,20142:49:51PM
*
*@paramu1
*@paramv1
*@paramu2
*@paramv2
*@return
*@returnfloat
*/
publicfloatgetDist(floatu1,floatv1,floatu2,floatv2){
return(float)Math.sqrt((u1-u2)*(u1-u2)+(v1-v2)*(v1-v2));
}
}
[/code]

/**
*
*@(#)IVisitor.java
*@Packagepattern.chp09.visitor.simple
*
*Copyright©JINGCorporation.Allrightsreserved.
*
*/
packagepattern.chp09.visitor.simple;
/**
*类描述:访问者接口
*
*@author:Jing
*@version$Id:Exp$
*
*History:Dec29,20142:42:28PMJingCreated.
*
*/
publicinterfaceIVisitor{
/**
*
*方法说明:访问方法
*
*Author:Jing
*CreateDate:Dec29,20142:46:48PM
*
*@paramt
*@return
*@returnObject
*/
Objectvisit(Trianglet);
}
[/code]

/**
*
*@(#)Point.java
*@Packagepattern.chp09.visitor.simple
*
*Copyright©JINGCorporation.Allrightsreserved.
*
*/
packagepattern.chp09.visitor.simple;
/**
*类描述:重心类坐标
*
*@author:Jing
*@version$Id:Exp$
*
*History:Dec29,20143:06:50PMJingCreated.
*
*/
publicclassPoint{
floatx,y;
}
[/code]

/**
*
*@(#)CenterVisitor.java
*@Packagepattern.chp09.visitor.simple
*
*Copyright©JINGCorporation.Allrightsreserved.
*
*/
packagepattern.chp09.visitor.simple;
/**
*类描述:重心坐标实现
*
*@author:Jing
*@version$Id:Exp$
*
*History:Dec29,20143:07:37PMJingCreated.
*
*/
publicclassCenterVisitorimplementsIVisitor{
publicObjectvisit(Trianglet){
Pointpt=newPoint();
pt.x=(t.x1+t.x2+t.x3)/3;
pt.y=(t.y1+t.y2+t.y3)/3;
returnpt;
}
}
[/code]

/**
*
*@(#)Test.java
*@Packagepattern.chp09.visitor.simple
*
*Copyright©JINGCorporation.Allrightsreserved.
*
*/
packagepattern.chp09.visitor.simple;
/**
*类描述:
*
*@author:Jing
*@version$Id:Exp$
*
*History:Dec29,20143:09:31PMJingCreated.
*
*/
publicclassTest{
publicstaticvoidmain(String[]args){
IVisitorv=newCenterVisitor();//定义重心具体访问者对象
Trianglet=newTriangle(0,0,2,0,0,2);
Pointpt=(Point)t.accept(v);
System.out.println(pt.x+","+pt.y);//输出重心
System.out.println(t.getArea());//输出面积
}
}
[/code]

5,深入理解访问者模式:如上的代码,如果三角形需要增加n个功能,则必须定义n个具体访问者类,使用反射可以更新代码,对Visitor接口和子类进行修改即可:

packagepattern.chp09.visitor.deep;
/**
*类描述:访问者接口
*
*@author:Jing
*@version$Id:Exp$
*
*History:Dec29,20143:32:50PMJingCreated.
*
*/
publicinterfaceIVisitor{
/**
*
*方法说明:访问对象对应的方法
*
*Author:JingCreateDate:Dec29,20143:34:58PM
*
*@paramt
*@parammethod
*@return
*@returnObject
*/
Objectvisit(Trianglet,Stringmethod);
}
[/code]

packagepattern.chp09.visitor.deep;
importjava.lang.reflect.Method;
importpattern.chp09.visitor.simple.Point;
/**
*类描述:图形类
*
*@author:Jing
*@version$Id:Exp$
*
*History:Dec29,20143:40:25PMJingCreated.
*
*/
publicclassShapVisitorimplementsIVisitor{
/**
*
*方法说明:获取重心坐标
*
*Author:JingCreateDate:Dec29,20143:41:05PM
*
*@paramt
*@return
*@returnObject
*/
publicObjectgetCenter(Trianglet){
Pointp=newPoint();
p.x=(t.x1+t.x2+t.x3)/3;
p.y=(t.y1+t.y2+t.y3)/3;
returnp;
}
/**
*
*方法说明:内切圆半径
*
*Author:JingCreateDate:Dec29,20143:46:09PM
*
*@paramt
*@return
*@returnFloat
*/
publicFloatgetInnerCircleR(Trianglet){
floatarea=t.getArea();
floatlen=t.getLength();
returnnewFloat(2.0F*area/len);
}
publicObjectvisit(Trianglet,Stringmethod){
Objectresult=null;
try{
Class<?>clazz=this.getClass();
Methodm=clazz.getMethod(method,Triangle.class);
result=m.invoke(this,newObject[]{t});
}catch(Exceptione){
e.printStackTrace();
}
returnresult;
}
}
[/code]

/**
*类描述:
*
*@author:Jing
*@version$Id:Exp$
*
*History:Dec29,20144:02:35PMJingCreated.
*
*/
publicclassTest{
publicstaticvoidmain(String[]args){
IVisitorv=newShapVisitor();
Trianglet=newTriangle(0,0,2,0,0,2);
Pointp=(Point)t.accept(v,"getCenter");
System.out.println(p.x+","+p.y);
Floatf=(Float)t.accept(v,"getInnerCircleR");
System.out.println(f.floatValue());
}
}
[/code]

6,构建集合对象自适应功能框架:

完成一个对应银行和存单管理的例子。

packagepattern.chp09.visitor.bank;
/**
*类描述:银行存单管理
*
*@author:Jing
*@version$Id:Exp$
*
*History:Dec29,20145:06:27PMJingCreated.
*
*/
publicabstractclassBank{
publicvoidaccept(IVisitor<Bank>v){
v.visit(this);
}
/**
*
*方法说明:执行存折
*
*Author:Jing
*CreateDate:Dec29,20145:09:40PM
*
*@paramvisit
*@returnvoid
*/
publicabstractvoidprocess(IVisitor<Sheet>visit);
}
[/code]

packagepattern.chp09.visitor.bank;
/**
*类描述:存单
*
*@author:Jing
*@version$Id:Exp$
*
*History:Dec29,20144:34:10PMJingCreated.
*
*/
publicabstractclassSheet{
Stringaccount;//帐号
Stringname;//姓名
floatmoney;//余额
StringstartDate;//存款日期
intrange;//期限
publicSheet(Stringaccount,Stringname,floatmoney,StringstartDate,intrange){
this.account=account;
this.name=name;
this.money=money;
this.startDate=startDate;
this.range=range;
}
/**
*
*方法说明:访问对象方法
*
*Author:Jing
*CreateDate:
packagepattern.chp09.visitor.bank;
/**
*类描述:泛型访问者接口
*
*@author:Jing
*@version$Id:Exp$
*
*History:Dec29,20144:31:53PMJingCreated.
*
*/
publicinterfaceIVisitor<T>{
/**
*
*方法说明:访问方法
*
*Author:Jing
*CreateDate:Dec29,20144:33:26PM
*
*@params
*@returnvoid
*/
voidvisit(Ts);
}
[/code]
Dec29,20144:39:44PM
*
*@paramv
*@returnvoid
*/
publicvoidaccept(IVisitor<Sheet>v){
v.visit(this);
}
}


packagepattern.chp09.visitor.bank;
importjava.util.Vector;
/**
*类描述:农行
*
*@author:Jing
*@version$Id:Exp$
*
*History:Dec29,20145:10:52PMJingCreated.
*
*/
publicclassABCBankextendsBank{
Vector<ABCSheet>v=newVector<ABCSheet>();
/**
*
*方法说明:增加存单
*
*Author:Jing
*CreateDate:Dec29,20145:11:37PM
*
*@params
*@returnvoid
*/
voidadd(ABCSheets){
v.add(s);
}
@Override
publicvoidprocess(IVisitor<Sheet>visit){
for(inti=0;i<v.size();i++){
v.get(i).accept(visit);
}
}
}
[/code]

packagepattern.chp09.visitor.bank;
/**
*类描述:农行
*
*@author:Jing
*@version$Id:Exp$
*
*History:Dec29,20145:06:05PMJingCreated.
*
*/
publicclassABCSheetextendsSheet{
publicABCSheet(Stringaccount,Stringname,floatmoney,StringstartDate,intrange){
super(account,name,money,startDate,range);
}
}
[/code]

packagepattern.chp09.visitor.bank;
importjava.util.Vector;
/**
*类描述:工行
*
*@author:Jing
*@version$Id:Exp$
*
*History:Dec29,20145:15:17PMJingCreated.
*
*/
publicclassICBCBankextendsBank{
Vector<ICBCsheet>v=newVector<ICBCsheet>();
@Override
publicvoidprocess(IVisitor<Sheet>visit){
for(inti=0;i<v.size();i++){
v.get(i).accept(visit);
}
}
/**
*
*方法说明:增加存单
*
*Author:Jing
*CreateDate:Dec29,20145:16:16PM
*
*@params
*@returnvoid
*/
voidadd(ICBCsheets){
v.add(s);
}
}
[/code]

packagepattern.chp09.visitor.bank;
/**
*类描述:工行存单子类
*
*@author:Jing
*@version$Id:Exp$
*
*History:Dec29,20145:03:41PMJingCreated.
*
*/
publicclassICBCsheetextendsSheet{
publicICBCsheet(Stringaccount,Stringname,floatmoney,StringstartDate,intrange){
super(account,name,money,startDate,range);
}
}
[/code]

packagepattern.chp09.visitor.bank;
importjava.util.Vector;
/**
*类描述:银行组存单管理
*
*@author:Jing
*@version$Id:Exp$
*
*History:Dec29,20145:18:01PMJingCreated.
*
*/
publicclassBankGroup{
Vector<Bank>v=newVector<Bank>();
/**
*
*方法说明:增加银行
*
*Author:Jing
*CreateDate:Dec29,20145:20:57PM
*
*@parambank
*@returnvoid
*/
voidadd(Bankbank){
v.add(bank);
}
publicvoidaccept(IVisitor<BankGroup>v){
v.visit(this);
}
publicvoidprocess(IVisitor<Bank>visit){
for(Bankbg:v){
bg.accept(visit);
}
}
}
[/code]

packagepattern.chp09.visitor.bank;
/**
*类描述:存单
*
*@author:Jing
*@version$Id:Exp$
*
*History:Dec29,20144:34:10PMJingCreated.
*
*/
publicabstractclassSheet{
Stringaccount;//帐号
Stringname;//姓名
floatmoney;//余额
StringstartDate;//存款日期
intrange;//期限
publicSheet(Stringaccount,Stringname,floatmoney,StringstartDate,intrange){
this.account=account;
this.name=name;
this.money=money;
this.startDate=startDate;
this.range=range;
}
/**
*
*方法说明:访问对象方法
*
*Author:Jing
*CreateDate:Dec29,20144:39:44PM
*
*@paramv
*@returnvoid
*/
publicvoidaccept(IVisitor<Sheet>v){
v.visit(this);
}
}
[/code]

定义一个存单访问者以及一个银行访问者。

packagepattern.chp09.visitor.bank;
/**
*类描述:账单访问类
*
*@author:Jing
*@version$Id:Exp$
*
*History:Dec29,20145:38:42PMJingCreated.
*
*/
publicclassSheetVisitorimplementsIVisitor<Sheet>{
privatevoidABCProc(ABCSheets){
System.out.println("ABCSheetprocess");
}
privatevoidICBCProc(ICBCsheets){
System.out.println("ICBCSheetprocess");
}
publicvoidvisit(Sheets){
if(sinstanceofABCSheet){
ABCProc((ABCSheet)s);
}
if(sinstanceofICBCsheet){
ICBCProc((ICBCsheet)s);
}
}
}
[/code]

packagepattern.chp09.visitor.bank;
/**
*类描述:银行访问者
*
*@author:Jing
*@version$Id:Exp$
*
*History:Dec29,20145:45:45PMJingCreated.
*
*/
publicclassBankVisitorimplementsIVisitor<Bank>{
privatevoidABCProc(ABCBankb){
System.out.println("ABCBankprocess");
}
privatevoidICBCProc(ICBCBankb){
System.out.println("ICBCBankprocess");
}
publicvoidvisit(Banks){
if(sinstanceofABCBank){
ABCProc((ABCBank)s);
}
if(sinstanceofICBCBank){
ICBCProc((ICBCBank)s);
}
}
}
[/code]

packagepattern.chp09.visitor.bank;
/**
*类描述:
*
*@author:Jing
*@version$Id:Exp$
*
*History:Dec30,201410:28:23AMJingCreated.
*
*/
publicclassTest{
publicstaticvoidmain(String[]args){
ICBCsheets=newICBCsheet("1000","liu",100,"2014-1-1",3);
IVisitorv=newSheetVisitor();
s.accept(v);
ICBCBankmanage=newICBCBank();
manage.add(s);
manage.process(v);
}
}
[/code]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: