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


    访问者模式是什么?

    表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作

    访问者模式解决什么问题?

    男女在不同情境下表现的不同

    abstract class Person {
        protected String action;
    
        public String getAction() {
            return action;
        }
    
        public void setAction(String action) {
            this.action = action;
        }
    
        public abstract void getConclusion();
    }
    
    class Man extends Person {
    
        @Override
        public void getConclusion() {
            if ("逛街".equals(action)) {
                System.out.println(this.getClass().getSimpleName() + action + "买完就走");
            } else if ("吃饭".equals(action)) {
                System.out.println(this.getClass().getSimpleName() + action + "狼吞虎咽");
            }
        }
    }
    
    class Woman extends Person {
    
        @Override
        public void getConclusion() {
            if ("逛街".equals(action)) {
                System.out.println(this.getClass().getSimpleName() + action + "到处乱逛");
            } else if ("吃饭".equals(action)) {
                System.out.println(this.getClass().getSimpleName() + action + "细嚼慢咽");
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    使用时

    List personList = new ArrayList<>();
    
    Man man = new Man();
    man.setAction("逛街");
    personList.add(man);
    
    Woman woMan = new Woman();
    woMan.setAction("逛街");
    personList.add(woMan);
    
    for (Person person : personList) {
        person.getConclusion();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    当要新增新的Action时,要修改两者的代码

    访问者模式实现

    创建不同的表现

    abstract class Action {
        abstract void getManConclusion(Man concreteElementA);
    
        abstract void getWomanConclusion(Woman concreteElementB);
    }
    
    class Shopping extends Action {
        @Override
        void getManConclusion(Man concreteElementA) {
            System.out.println(concreteElementA.getClass().getSimpleName() + " " + getClass().getSimpleName() + "买完就走");
        }
    
        @Override
        void getWomanConclusion(Woman concreteElementB) {
            System.out.println(concreteElementB.getClass().getSimpleName() + " " + getClass().getSimpleName() + "到处乱逛");
        }
    }
    
    class eat extends Action {
    
        @Override
        void getManConclusion(Man concreteElementA) {
            System.out.println(concreteElementA.getClass().getSimpleName() + " " + getClass().getSimpleName() + "狼吞虎咽");
        }
    
        @Override
        void getWomanConclusion(Woman concreteElementB) {
            System.out.println(concreteElementB.getClass().getSimpleName() + " " + getClass().getSimpleName() + "细嚼慢咽");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    创建男女,这里采用双分派,先将Action作为传递参数给男/女,再将男/女作为参数传入给Action,意味着执行结果取决于两个调用者的类型

    abstract class Person {
        abstract void accept(Action visitor);
    }
    
    class Man extends Person {
    
        @Override
        void accept(Action visitor) {
            visitor.getManConclusion(this);
        }
    }
    
    class Woman extends Person {
        @Override
        void accept(Action visitor) {
            visitor.getWomanConclusion(this);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    创建对象结构统一管理和遍历

    class ObjStructure {
        private List mPersonList = new ArrayList<>();
    
        public void attach(Person person) {
            mPersonList.add(person);
        }
    
        public void detach(Person person) {
            mPersonList.remove(person);
        }
    
        public void display(Action visitor) {
            for (Person person : mPersonList) {
                person.accept(visitor);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    调用时

     ObjStructure objStructure = new ObjStructure();
     objStructure.attach(new Man());
     objStructure.attach(new Woman());
     
     objStructure.display(new Shopping());
     objStructure.display(new eat());
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 当要增加Action时,只需要新增一个类和修改上面的代码
    • 但是如果新增一个外星人的话,就要在每个Action中新增对应方法,故访问者模式适用于数据结构稳定但算法易变化的情况
  • 相关阅读:
    RHCE---时间服务器
    数据可视化:让数据讲述故事
    SpringCloud进阶-Eureka的集群搭建
    微信小程序动态添加表单模块
    JAVA赋值不使用引用的办法
    卷积神经网络激活层作用,卷积神经网络激活函数
    第20天:信息打点-红蓝队自动化项目&资产侦察&企查产权&武器库部署&网络空间
    通过删除字母匹配到字典里最长单词
    Map.get、Map.set、Map.has方法
    Java实现堆算法
  • 原文地址:https://blog.csdn.net/qq_35258036/article/details/133094656