zoukankan      html  css  js  c++  java
  • 设计模式——访问者模式

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

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

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

        抽象被访问者角色,主要定义需要接受访问者的约束,一般是 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);
        }
    }
    测试

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

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

    简单工厂模式

    工厂方法模式

    抽象工厂模式

    建造者模式

    原型模式

    适配器模式

    桥接模式

    装饰模式

    代理模式

    组合模式

    门面模式

    享元模式

    责任链模式

    命令模式

    中介者模式

    备忘录模式

    观察者模式

    状态模式

    策略模式

    模板方法模式

    访问者模式

  • 相关阅读:
    pip list报警告DEPRECATION
    JMeter使用ServerAgent监控阿里云服务器连接不上处理方法
    mysql:查询排名
    jmeter教程(二十):性能测试执行及结果分析
    jmeter(二十一)jmeter常用插件介绍
    Jmeter第三方插件Jmeter Plugins
    jmeter 03Jmeter常用插件——梯度加压、响应时间、TPS
    Jenkins 定时任务触发时间表达式 与 cron表达式详解(两者相似但有差异)
    前端语言之JavaScript
    前端语言之CSS样式
  • 原文地址:https://www.cnblogs.com/tengpan-cn/p/6504404.html
Copyright © 2011-2022 走看看