zoukankan      html  css  js  c++  java
  • 访问者模式【行为模式】

    Represent an operation to be performed on the elements of an object structure.
    Visitor lets you define a new operation without changing the classes of the elements on which is operators.
    代表对一个结构化对象中的元素所执行的操作,访问者允许你定义一个作用于结构化对象中的元素的新操作,
    而不需要改变元素的类型。
    
    @Slf4j
    public class Visitor {
        /**
         * 访问者模式:
         * Represent an operation to be performed on the elements of an object structure.
         * Visitor lets you define a new operation without changing the classes of the elements on which is operators.
         * 代表对一个结构化对象中的元素所执行的操作,访问者允许你定义一个作用于结构化对象中的元素的新操作,而不需要改变元素的类型。
         */
        @Test
        public void all() {
            final Worker w1 = buildWorker("w1", 3000);
            final Worker w2 = buildWorker("w2", 4000);
    
            final Manager m1 = buildManager("m1", 10000);
            final Manager m2 = buildManager("m2", 20000);
    
            final List<Emp> list = List.of(w1, w2, m1, m2);
    
            final SumVisitor sumVisitor = SumVisitor.builder().build();
            list.forEach(emp -> emp.accept(sumVisitor));
            log.info("sum {}", sumVisitor.getSumSalary());
    
            final PlusSalary plusSalary = PlusSalary.builder().build();
            list.forEach(emp -> emp.accept(plusSalary));
            list.forEach(emp -> log.info("emp {}", emp));
        }
    
        private static Manager buildManager(String name, double salary) {
            final Manager manager = Manager.builder().build();
            manager.setName(name);
            manager.setSalary(salary);
    
            return manager;
        }
    
        private static Worker buildWorker(String name, double salary) {
            final Worker worker = Worker.builder().build();
            worker.setName(name);
            worker.setSalary(salary);
    
            return worker;
        }
    
    }
    
    /**
     * 1)访问者和目标元素的通信接口【需要访问的元素类型是确定的】
     */
    interface IVisitor {
        /**
         * 单个接口负责所有类型对象的访问,不符合单一职责原则,特化为以下两个接口
         * Java 执行重载方法调用时,参数类型匹配度越高的方法优先调用。
         */
        void visitor(Worker worker);
    
        void visitor(Manager manager);
    }
    
    /**
     * 2)某种类型的访问者:用于统计工资总和
     */
    @Data
    @Builder
    class SumVisitor implements IVisitor {
        private double sumSalary;
    
        @Override
        public void visitor(Worker worker) {
            sumSalary += worker.getSalary();
        }
    
        @Override
        public void visitor(Manager manager) {
            sumSalary += manager.getSalary();
        }
    }
    
    /**
     * 2)某种类型的访问者:用于给员工增加工资
     */
    @Builder
    class PlusSalary implements IVisitor {
        @Override
        public void visitor(Worker worker) {
            worker.setSalary(worker.getSalary() * 1.1);
        }
    
        @Override
        public void visitor(Manager manager) {
            manager.setSalary(manager.getSalary() * 1.5);
        }
    }
    
    /**
     * 2)实现被访问接口的抽象类,封装一些共用属性和方法
     */
    @Data
    abstract class Emp {
        private String name;
        private double salary;
    
        // 核心抽象方法,用于接受访问者
        abstract void accept(IVisitor visitor);
    }
    
    /**
     * 4)具体的被访问者类
     */
    @Builder
    class Worker extends Emp {
        @Override
        void accept(IVisitor visitor) {
            visitor.visitor(this);
        }
    }
    
    /**
     * 4)具体的被访问者类
     */
    @Builder
    class Manager extends Emp {
        @Override
        void accept(IVisitor visitor) {
            visitor.visitor(this);
        }
    }
    
  • 相关阅读:
    第四章例4-5
    第四章例4-4
    修改oracle 客户端PL/SQL 的路径问题
    解决div float后,父div高度无法自适应的问题
    include与jsp:include与s:action与s:include与iframe用法汇总
    解决js中onMouseOut事件冒泡的问题
    strut2配置action class 问题
    html块级元素与行内元素
    Tomcat 启动不了的问题
    oracle远程导入导出
  • 原文地址:https://www.cnblogs.com/zhuxudong/p/10165433.html
Copyright © 2011-2022 走看看