• 设计模式 - 访问者模式


    目录

    一. 前言

    二. 实现

    三. 优缺点


    一. 前言

        访问者模式,即在不改变聚合对象内元素的前提下,为聚合对象内每个元素提供多种访问方式,即聚合对象内的每个元素都有多个访问者对象。访问者模式主要解决稳定的数据结构和易变元素的操作之间的耦合问题。

    二. 实现

    Visitor:访问者,为每一个 ConcreteElement 声明一个 visit 操作。
    ConcreteVisitor:具体访问者,存储遍历过程中的累计结果。
    ObjectStructure:对象结构,可以是组合结构,或者是一个集合。

    1. public interface Element {
    2. void accept(Visitor visitor);
    3. }
    4. public class Customer implements Element {
    5. private String name;
    6. private List orders = new ArrayList<>();
    7. Customer(String name) {
    8. this.name = name;
    9. }
    10. String getName() {
    11. return name;
    12. }
    13. void addOrder(Order order) {
    14. orders.add(order);
    15. }
    16. public void accept(Visitor visitor) {
    17. visitor.visit(this);
    18. for (Order order : orders) {
    19. order.accept(visitor);
    20. }
    21. }
    22. }
    23. public class Order implements Element {
    24. private String name;
    25. private List items = new ArrayList();
    26. Order(String name) {
    27. this.name = name;
    28. }
    29. Order(String name, String itemName) {
    30. this.name = name;
    31. this.addItem(new Item(itemName));
    32. }
    33. String getName() {
    34. return name;
    35. }
    36. void addItem(Item item) {
    37. items.add(item);
    38. }
    39. public void accept(Visitor visitor) {
    40. visitor.visit(this);
    41. for (Item item : items) {
    42. item.accept(visitor);
    43. }
    44. }
    45. }
    46. public class Item implements Element {
    47. private String name;
    48. Item(String name) {
    49. this.name = name;
    50. }
    51. String getName() {
    52. return name;
    53. }
    54. public void accept(Visitor visitor) {
    55. visitor.visit(this);
    56. }
    57. }
    1. class CustomerGroup {
    2. private List customers = new ArrayList<>();
    3. void accept(Visitor visitor) {
    4. for (Customer customer : customers) {
    5. customer.accept(visitor);
    6. }
    7. }
    8. void addCustomer(Customer customer) {
    9. customers.add(customer);
    10. }
    11. }
    1. public interface Visitor {
    2. void visit(Customer customer);
    3. void visit(Order order);
    4. void visit(Item item);
    5. }
    1. public class GeneralReport implements Visitor {
    2. private int customersNo;
    3. private int ordersNo;
    4. private int itemsNo;
    5. public void visit(Customer customer) {
    6. System.out.println(customer.getName());
    7. customersNo++;
    8. }
    9. public void visit(Order order) {
    10. System.out.println(order.getName());
    11. ordersNo++;
    12. }
    13. public void visit(Item item) {
    14. System.out.println(item.getName());
    15. itemsNo++;
    16. }
    17. public void displayResults() {
    18. System.out.println("Number of customers: " + customersNo);
    19. System.out.println("Number of orders: " + ordersNo);
    20. System.out.println("Number of items: " + itemsNo);
    21. }
    22. }
    1. public class Client {
    2. public static void main(String[] args) {
    3. Customer customer1 = new Customer("customer1");
    4. customer1.addOrder(new Order("order1", "item1"));
    5. customer1.addOrder(new Order("order2", "item1"));
    6. customer1.addOrder(new Order("order3", "item1"));
    7. Order order = new Order("order_a");
    8. order.addItem(new Item("item_a1"));
    9. order.addItem(new Item("item_a2"));
    10. order.addItem(new Item("item_a3"));
    11. Customer customer2 = new Customer("customer2");
    12. customer2.addOrder(order);
    13. CustomerGroup customers = new CustomerGroup();
    14. customers.addCustomer(customer1);
    15. customers.addCustomer(customer2);
    16. GeneralReport visitor = new GeneralReport();
    17. customers.accept(visitor);
    18. visitor.displayResults();
    19. }
    20. }
    1. customer1
    2. order1
    3. item1
    4. order2
    5. item1
    6. order3
    7. item1
    8. customer2
    9. order_a
    10. item_a1
    11. item_a2
    12. item_a3
    13. Number of customers: 2
    14. Number of orders: 4
    15. Number of items: 6

    三. 优缺点

    优点
    1. 符合单一职责原则,即数据的存储和操作分别由对象结构类和访问者类实现。
    2. 优秀的扩展性和灵活性。
    缺点
    1. 具体元素对访问者公布了其细节,违反了迪米特法则。
    2. 具体元素的增加将导致访问者类的修改,违反了开闭原则。
    3. 访问者类依赖了具体类而不是抽象,违反了依赖倒置原则。

    JDK中的访问者模式
    javax.lang.model.element.Element and javax.lang.model.element.ElementVisitor
    javax.lang.model.type.TypeMirror and javax.lang.model.type.TypeVisitor

  • 相关阅读:
    华为OD机考算法题:篮球比赛
    Android的本地数据
    MySQL高级4-索引的使用规则
    机器学习算法(一):1. numpy从零实现线性回归
    图像超分——Real-ESRGAN快速上手
    CSS选择器总结
    【华为OD题库-028】数据分类-java
    19.单目测距原理介绍
    手拉手一起学HTML(下)——表格标签和列表标签,表单标签
    vue使用百度地图实现地点查询
  • 原文地址:https://blog.csdn.net/mrluo735/article/details/133686048