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


    访问者模式是什么?

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

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

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

    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中新增对应方法,故访问者模式适用于数据结构稳定但算法易变化的情况
  • 相关阅读:
    别用==比较包装类
    npm 执行命令时报错npm ERR! code ERESOLVE npm ERR! ERESOLVE could not resolve
    283. Move Zeroes
    程序公司分红及退出机制设计(1)
    anr和crash文件分析,特征码提取
    【一致性】redis+DB一致性如何保证? 从Cache Expiry到Double Delete双重删除
    JavaScript基础-简单易懂总结
    MySQL binlog时间异常分析
    ChatGPT怎么运用在文学分析和文化研究中?
    阿里P8架构师进阶心得:分布式数据库架构MyCat学习笔记送给你
  • 原文地址:https://blog.csdn.net/qq_35258036/article/details/133094656