• 读书笔记_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);
    }
     
    @Override
    public 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>();
     
    @Override
    public 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]。
    如相关博文涉及到版权问题,请联系本人。
  • 相关阅读:
    收款 借贷
    Oracle Contracts Core Tables
    mtl_material_transactions.logical_transaction
    OM订单登记不了的处理办法
    子库存转移和物料搬运单区别
    WPF中使用DataGridView创建报表控件
    vi编辑器命令
    成绩管理系统中的成绩报表SQL
    ASP.Net中传递参数的常见方法
    MySQL的SET字段类型
  • 原文地址:https://www.cnblogs.com/jingLongJun/p/4491067.html
Copyright © 2020-2023  润新知