码迷,mamicode.com
首页 > 其他好文 > 详细

访问者模式【行为模式】

时间:2018-12-23 22:07:09      阅读:119      评论:0      收藏:0      [点我收藏+]

标签:增加   err   vat   name   which   bst   访问者   结构化   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);
    }
}

访问者模式【行为模式】

标签:增加   err   vat   name   which   bst   访问者   结构化   java   

原文地址:https://www.cnblogs.com/zhuxudong/p/10165433.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!