读书笔记_java设计模式深入研究 第九章 访问者模式 Vistor
1,访问者模式的目的是封装一些施加于某种数据结构元素之上的操作,一旦这些操作需要修改的话,接受这个操作的数据结构可以保持不变。为不同类型的元素提供多种访问操作方式,且可以在不修改原有系统的情况下增加新的操作方式,这就是访问者模式的动机。
![]()
![]()
2,UML图:
3,访问者角色:
IElement:抽象的事物元素功能接口,定义了固定功能方法以及可变功能方法接口。
Element:具体功能的实现类。
IVisitor:访问者接口,为所有访问者对象声明一个visit方法,用来代表为对象结构添加的功能,原则上可以代表任意功能。
Visitor:具体访问实现类,实现要正真被添加到对象结构中的功能。
4,基本代码例子:
/**** @(#) IShape.java* @Package pattern.chp09.visitor.simple** Copyright © JING Corporation. All rights reserved.**/package pattern.chp09.visitor.simple;/*** 类描述:抽象需求接口** @author: Jing* @version $Id: Exp$** History: Dec 29, 2014 2:40:16 PM Jing Created.**/public interface IShape {/**** 方法说明:获取图形面积** Author: Jing* Create Date: Dec 29, 2014 2:40:41 PM** @return* @return float*/float getArea();/**** 方法说明:获取周长** Author: Jing* Create Date: Dec 29, 2014 2:41:04 PM** @return* @return float*/float getLength();/**** 方法说明:传入访问者对象和方法名** Author: Jing* Create Date: Dec 29, 2014 2:43:17 PM** @param v* @return* @return Object*/Object accept(IVisitor v);}
/**** @(#) Triangle.java* @Package pattern.chp09.visitor.simple** Copyright © JING Corporation. All rights reserved.**/package pattern.chp09.visitor.simple;/*** 类描述:三角形** @author: Jing* @version $Id: Exp$** History: Dec 29, 2014 2:45:54 PM Jing Created.**/public class Triangle implements IShape {float x1, y1, x2, y2, x3, y3;// 三角形三点坐标public Triangle(float x1, float y1, float x2, float y2, float x3, float y3) {this.x1 = x1;this.y1 = y1;this.x2 = x2;this.y2 = y2;this.x3 = x3;this.y3 = y3;}public Object accept(IVisitor v) {return v.visit(this);}public float getArea() {float a = getDist(x1, y1, x2, y2);float b = getDist(x1, y1, x3, y3);float c = getDist(x2, y2, x3, y3);float s = (a + b + c) / 2;return (float) Math.sqrt(s * (s - a) * (s - b) * (s - c));}public float getLength() {float a = getDist(x1, y1, x2, y2);float b = getDist(x1, y1, x3, y3);float c = getDist(x2, y2, x3, y3);return a + b + c;}/**** 方法说明:求任意两点距离** Author: Jing Create Date: Dec 29, 2014 2:49:51 PM** @param u1* @param v1* @param u2* @param v2* @return* @return float*/public float getDist(float u1, float v1, float u2, float v2) {return (float) Math.sqrt((u1 - u2) * (u1 - u2) + (v1 - v2) * (v1 - v2));}}
/**** @(#) IVisitor.java* @Package pattern.chp09.visitor.simple** Copyright © JING Corporation. All rights reserved.**/package pattern.chp09.visitor.simple;/*** 类描述:访问者接口** @author: Jing* @version $Id: Exp$** History: Dec 29, 2014 2:42:28 PM Jing Created.**/public interface IVisitor {/**** 方法说明:访问方法** Author: Jing* Create Date: Dec 29, 2014 2:46:48 PM** @param t* @return* @return Object*/Object visit(Triangle t);}
/**** @(#) Point.java* @Package pattern.chp09.visitor.simple** Copyright © JING Corporation. All rights reserved.**/package pattern.chp09.visitor.simple;/*** 类描述:重心类坐标** @author: Jing* @version $Id: Exp$** History: Dec 29, 2014 3:06:50 PM Jing Created.**/public class Point {float x, y;}
/**** @(#) CenterVisitor.java* @Package pattern.chp09.visitor.simple** Copyright © JING Corporation. All rights reserved.**/package pattern.chp09.visitor.simple;/*** 类描述:重心坐标实现** @author: Jing* @version $Id: Exp$** History: Dec 29, 2014 3:07:37 PM Jing Created.**/public class CenterVisitor implements IVisitor {public Object visit(Triangle t) {Point pt = new Point();pt.x = (t.x1 + t.x2 + t.x3) / 3;pt.y = (t.y1 + t.y2 + t.y3) / 3;return pt;}}
/**** @(#) Test.java* @Package pattern.chp09.visitor.simple** Copyright © JING Corporation. All rights reserved.**/package pattern.chp09.visitor.simple;/*** 类描述:** @author: Jing* @version $Id: Exp$** History: Dec 29, 2014 3:09:31 PM Jing Created.**/public class Test {public static void main(String[] args) {IVisitor v = new CenterVisitor();// 定义重心具体访问者对象Triangle t = new Triangle(0, 0, 2, 0, 0, 2);Point pt = (Point) t.accept(v);System.out.println(pt.x + ", " + pt.y);//输出重心System.out.println(t.getArea());//输出面积}}
5,深入理解访问者模式:如上的代码,如果三角形需要增加n个功能,则必须定义n个具体访问者类,使用反射可以更新代码,对Visitor接口和子类进行修改即可:
package pattern.chp09.visitor.deep;/*** 类描述:访问者接口** @author: Jing* @version $Id: Exp$** History: Dec 29, 2014 3:32:50 PM Jing Created.**/public interface IVisitor {/**** 方法说明:访问对象对应的方法** Author: Jing Create Date: Dec 29, 2014 3:34:58 PM** @param t* @param method* @return* @return Object*/Object visit(Triangle t, String method);}
package pattern.chp09.visitor.deep;import java.lang.reflect.Method;import pattern.chp09.visitor.simple.Point;/*** 类描述:图形类** @author: Jing* @version $Id: Exp$** History: Dec 29, 2014 3:40:25 PM Jing Created.**/public class ShapVisitor implements IVisitor {/**** 方法说明:获取重心坐标** Author: Jing Create Date: Dec 29, 2014 3:41:05 PM** @param t* @return* @return Object*/public Object getCenter(Triangle t) {Point p = new Point();p.x = (t.x1 + t.x2 + t.x3) / 3;p.y = (t.y1 + t.y2 + t.y3) / 3;return p;}/**** 方法说明:内切圆半径** Author: Jing Create Date: Dec 29, 2014 3:46:09 PM** @param t* @return* @return Float*/public Float getInnerCircleR(Triangle t) {float area = t.getArea();float len = t.getLength();return new Float(2.0F * area / len);}public Object visit(Triangle t, String method) {Object result = null;try {Class<?> clazz = this.getClass();Method m = clazz.getMethod(method, Triangle.class);result = m.invoke(this, new Object[] { t });} catch (Exception e) {e.printStackTrace();}return result;}}
/*** 类描述:** @author: Jing* @version $Id: Exp$** History: Dec 29, 2014 4:02:35 PM Jing Created.**/public class Test {public static void main(String[] args) {IVisitor v = new ShapVisitor();Triangle t = new Triangle(0,0,2,0,0,2);Point p = (Point) t.accept(v, "getCenter");System.out.println(p.x + ", " + p.y);Float f = (Float) t.accept(v, "getInnerCircleR");System.out.println(f.floatValue());}}
6,构建集合对象自适应功能框架:
完成一个对应银行和存单管理的例子。
package pattern.chp09.visitor.bank;/*** 类描述:银行存单管理** @author: Jing* @version $Id: Exp$** History: Dec 29, 2014 5:06:27 PM Jing Created.**/public abstract class Bank {public void accept(IVisitor<Bank> v){v.visit(this);}/**** 方法说明:执行存折** Author: Jing* Create Date: Dec 29, 2014 5:09:40 PM** @param visit* @return void*/public abstract void process(IVisitor<Sheet> visit);}
package pattern.chp09.visitor.bank;/*** 类描述:存单** @author: Jing* @version $Id: Exp$** History: Dec 29, 2014 4:34:10 PM Jing Created.**/public abstract class Sheet {String account;// 帐号String name;// 姓名float money;// 余额String startDate;// 存款日期int range;// 期限public Sheet(String account, String name, float money, String startDate, int range) {this.account = account;this.name = name;this.money = money;this.startDate = startDate;this.range = range;}/**** 方法说明:访问对象方法** Author: Jing* Create Date:package pattern.chp09.visitor.bank;/*** 类描述:泛型访问者接口** @author: Jing* @version $Id: Exp$** History: Dec 29, 2014 4:31:53 PM Jing Created.**/public interface IVisitor<T> {/**** 方法说明:访问方法** Author: Jing* Create Date: Dec 29, 2014 4:33:26 PM** @param s* @return void*/void visit(T s);}Dec 29, 2014 4:39:44 PM** @param v* @return void*/public void accept(IVisitor<Sheet> v) {v.visit(this);}}
package pattern.chp09.visitor.bank;import java.util.Vector;/*** 类描述:农行** @author: Jing* @version $Id: Exp$** History: Dec 29, 2014 5:10:52 PM Jing Created.**/public class ABCBank extends Bank {Vector<ABCSheet> v = new Vector<ABCSheet>();/**** 方法说明:增加存单** Author: Jing* Create Date: Dec 29, 2014 5:11:37 PM** @param s* @return void*/void add(ABCSheet s){v.add(s);}@Overridepublic void process(IVisitor<Sheet> visit) {for(int i = 0; i <v.size();i++){v.get(i).accept(visit);}}}
package pattern.chp09.visitor.bank;/*** 类描述:农行** @author: Jing* @version $Id: Exp$** History: Dec 29, 2014 5:06:05 PM Jing Created.**/public class ABCSheet extends Sheet {public ABCSheet(String account, String name, float money, String startDate, int range) {super(account, name, money, startDate, range);}}
package pattern.chp09.visitor.bank;import java.util.Vector;/*** 类描述:工行** @author: Jing* @version $Id: Exp$** History: Dec 29, 2014 5:15:17 PM Jing Created.**/public class ICBCBank extends Bank {Vector<ICBCsheet> v = new Vector<ICBCsheet>();@Overridepublic void process(IVisitor<Sheet> visit) {for (int i = 0; i < v.size(); i++) {v.get(i).accept(visit);}}/**** 方法说明:增加存单** Author: Jing* Create Date: Dec 29, 2014 5:16:16 PM** @param s* @return void*/void add(ICBCsheet s){v.add(s);}}
package pattern.chp09.visitor.bank;/*** 类描述:工行存单子类** @author: Jing* @version $Id: Exp$** History: Dec 29, 2014 5:03:41 PM Jing Created.**/public class ICBCsheet extends Sheet {public ICBCsheet(String account, String name, float money, String startDate, int range) {super(account, name, money, startDate, range);}}
package pattern.chp09.visitor.bank;import java.util.Vector;/*** 类描述:银行组存单管理** @author: Jing* @version $Id: Exp$** History: Dec 29, 2014 5:18:01 PM Jing Created.**/public class BankGroup {Vector<Bank> v = new Vector<Bank>();/**** 方法说明:增加银行** Author: Jing* Create Date: Dec 29, 2014 5:20:57 PM** @param bank* @return void*/void add(Bank bank){v.add(bank);}public void accept(IVisitor<BankGroup> v){v.visit(this);}public void process(IVisitor<Bank> visit){for(Bank bg: v){bg.accept(visit);}}}
package pattern.chp09.visitor.bank;/*** 类描述:存单** @author: Jing* @version $Id: Exp$** History: Dec 29, 2014 4:34:10 PM Jing Created.**/public abstract class Sheet {String account;// 帐号String name;// 姓名float money;// 余额String startDate;// 存款日期int range;// 期限public Sheet(String account, String name, float money, String startDate, int range) {this.account = account;this.name = name;this.money = money;this.startDate = startDate;this.range = range;}/**** 方法说明:访问对象方法** Author: Jing* Create Date: Dec 29, 2014 4:39:44 PM** @param v* @return void*/public void accept(IVisitor<Sheet> v) {v.visit(this);}}
定义一个存单访问者以及一个银行访问者。
package pattern.chp09.visitor.bank;/*** 类描述:账单访问类** @author: Jing* @version $Id: Exp$** History: Dec 29, 2014 5:38:42 PM Jing Created.**/public class SheetVisitor implements IVisitor<Sheet> {private void ABCProc(ABCSheet s){System.out.println("ABCSheet process");}private void ICBCProc(ICBCsheet s){System.out.println("ICBCSheet process");}public void visit(Sheet s) {if (s instanceof ABCSheet) {ABCProc((ABCSheet)s);}if (s instanceof ICBCsheet) {ICBCProc((ICBCsheet)s);}}}
package pattern.chp09.visitor.bank;/*** 类描述:银行访问者** @author: Jing* @version $Id: Exp$** History: Dec 29, 2014 5:45:45 PM Jing Created.**/public class BankVisitor implements IVisitor<Bank> {private void ABCProc(ABCBank b) {System.out.println("ABCBank process");}private void ICBCProc(ICBCBank b) {System.out.println("ICBCBank process");}public void visit(Bank s) {if (s instanceof ABCBank) {ABCProc((ABCBank) s);}if (s instanceof ICBCBank) {ICBCProc((ICBCBank) s);}}}
package pattern.chp09.visitor.bank;/*** 类描述:** @author: Jing* @version $Id: Exp$** History: Dec 30, 2014 10:28:23 AM Jing Created.**/public class Test {public static void main(String[] args) {ICBCsheet s = new ICBCsheet("1000", "liu", 100, "2014-1-1", 3);IVisitor v = new SheetVisitor();s.accept(v);ICBCBank manage = new ICBCBank();manage.add(s);manage.process(v);}}
欢迎转载,但转载请注明原文链接[博客园: http://www.cnblogs.com/jingLongJun/]
[CSDN博客:http://blog.csdn.net/mergades]。
如相关博文涉及到版权问题,请联系本人。
[CSDN博客:http://blog.csdn.net/mergades]。
如相关博文涉及到版权问题,请联系本人。

浙公网安备 33010602011771号