访问者模式行为模式

Posted zhuxudong

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了访问者模式行为模式相关的知识,希望对你有一定的参考价值。

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);
    }
}

以上是关于访问者模式行为模式的主要内容,如果未能解决你的问题,请参考以下文章

设计模式 行为型模式 -- 观察者模式(发布-订阅(Publish/Subscribe)模式)

Python 设计模式 — 行为型模式 — 访问者模式

Python 设计模式 — 行为型模式 — 访问者模式

设计模式 行为型模式 -- 访问者模式 拓展:双分派

JAVA SCRIPT设计模式--行为型--设计模式之Vistor访问者(23)

JAVA SCRIPT设计模式--行为型--设计模式之Vistor访问者(23)