• 设计模式——访问者模式


    访问者模式是一种行为模式,一般用于封装操作的变化,即对于一组对象(或一个对象)数据结构相对固定,但操作方法上有很多变化,这时候可以使用此设计模式;

    角色:抽象的访问者角色,定义访问者针对此组对象需要实现的方法约束;

            具体访问者角色,实现抽象访问者的约束

        抽象被访问者角色,主要定义需要接受访问者的约束,一般是 void accept(Abstractvisitor visitor)

           具体的被访问者角色。

    访问者模式将数据结构和作用在数据结构上的操作解耦和;

    下面看个示例;

    /*
     * Copyright (c) 2017. panteng.Co.Ltd All rights reserved
     */
    
    package com.pt.visitor;
    
    /**
     * @description 抽象元素角色(被访问者角色)
     *      定义元素需要实现的接受访问者的方法
     * @author panteng
     * @date 17-3-6.
     */
    public interface Element {
        void accept(Visitor visitor);
    }
    抽象元素类
    /*
     * Copyright (c) 2017. Xiaomi.Co.Ltd All rights reserved
     */
    
    package com.pt.visitor;
    
    /**
     * @description
     * @author panteng
     * @date 17-3-6.
     */
    public class Number implements Element {
        double a;
        double b;
    
        public Number(){
        }
    
        public Number(double a, double b){
            this.a = a;
            this.b = b;
        }
    
        public void accept(Visitor visitor){
            visitor.visit(this);
        }
        public double getA(){
            return a;
        }
        public void setA(double a){
            this.a = a;
        }
        public double getB(){
            return b;
        }
        public void setB(double b){
            this.b = b;
        }
    }
    元素1
    /*
     * Copyright (c) 2017. Xiaomi.Co.Ltd All rights reserved
     */
    
    package com.pt.visitor;
    
    import java.util.List;
    
    /**
     * @description
     * @author panteng
     * @date 17-3-6.
     */
    public class MyCollection implements Element {
        List<Object> list1;
        List<Object> list2;
    
        public MyCollection(){
        }
        public MyCollection(List<Object> list1, List<Object> list2){
            this.list1 = list1;
            this.list2 = list2;
        }
    
        public void accept(Visitor visitor){
            visitor.visit(this);
        }
    
        public List<Object> getList1(){
            return list1;
        }
        public void setList1(List<Object> list1){
            this.list1 = list1;
        }
        public List<Object> getList2(){
            return list2;
        }
        public void setList2(List<Object> list2){
            this.list2 = list2;
        }
    }
    元素2
    /*
     * Copyright (c) 2017. Xiaomi.Co.Ltd All rights reserved
     */
    
    package com.pt.visitor;
    
    /**
     * @description 抽象访问者,定义访问操作接口
     * @author panteng
     * @date 17-3-6.
     */
    public interface Visitor {
        void visit(Number num);
        void visit(MyCollection set);
    }
    抽象操作类
    /*
     * Copyright (c) 2017. Xiaomi.Co.Ltd All rights reserved
     */
    
    package com.pt.visitor;
    
    /**
     * @description
     * @author panteng
     * @date 17-3-6.
     */
    public class Add implements Visitor {
        public void visit(MyCollection set){
            System.out.print(set.getList1() + " + " + set.getList2() + " = ");
            set.getList1().addAll(set.getList2());
            System.out.println(set.getList1());
        }
        public void visit(Number num){
            System.out.println(num.getA() + " + " + num.getB() + " = " + (num.getA() + num.getB()));
        }
    }
    操作类1
    /*
     * Copyright (c) 2017. Xiaomi.Co.Ltd All rights reserved
     */
    
    package com.pt.visitor;
    
    /**
     * @description
     * @author panteng
     * @date 17-3-6.
     */
    public class Sub implements Visitor {
        public void visit(MyCollection set){
            System.out.print(set.getList1() + " - " + set.getList2() + " = ");
            set.getList1().removeAll(set.getList2());
            System.out.println(set.getList1());
        }
        public void visit(Number num){
            System.out.println(num.getA() + " - " + num.getB() + " = " + (num.getA() - num.getB()));
        }
    }
    操作类2
    /*
     * Copyright (c) 2017. Xiaomi.Co.Ltd All rights reserved
     */
    
    package com.pt.visitor;
    
    import org.junit.Test;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * @description
     * @author panteng
     * @date 17-3-6.
     */
    public class VisitorTest {
        @Test
        public void visitorTest(){
            Visitor addVisitor = new Add();
            Visitor subVisitor = new Sub();
            Number number = new Number(3, 9);
    
            List<Object> list1 = new ArrayList<Object>();
            list1.add(1);
            list1.add(2);
            list1.add(3);
            List<Object> list2 = new ArrayList<Object>();
            list2.add(3);
            list2.add(4);
            list2.add(5);
            MyCollection set = new MyCollection(list1, list2);
    
            number.accept(addVisitor);
            set.accept(addVisitor);
    
            number.accept(subVisitor);
            set.accept(subVisitor);
        }
    }
    测试

    此设计模式有其优势,但也有一定的不足,假如想增加一个除法操作类,对于集合并没除法操作,但操作类必须实现除法操作(空函数,或友情提示没有此操作)!似乎违反了接口最小化原则

    ===========================设计模式系列文章=========================

    简单工厂模式

    工厂方法模式

    抽象工厂模式

    建造者模式

    原型模式

    适配器模式

    桥接模式

    装饰模式

    代理模式

    组合模式

    门面模式

    享元模式

    责任链模式

    命令模式

    中介者模式

    备忘录模式

    观察者模式

    状态模式

    策略模式

    模板方法模式

    访问者模式

  • 相关阅读:
    阿里MaxCompute(原ODPS)如何修改列字段数据类型
    解决SQL语句在Dapper执行超时比Query慢的问题
    IIS部署FLASK网站
    如何在vscode中调试python scrapy爬虫
    [转]阿拉伯数字转一二三和壹贰叁
    第三册复习
    不知道的口语
    跟小丸子学基础口语21-25
    跟小丸子学基础口语16-20
    跟小丸子学基础口语11-15
  • 原文地址:https://www.cnblogs.com/tengpan-cn/p/6504404.html
Copyright © 2020-2023  润新知