访问者(Visitor)

Intent

为一个对象结构(比如组合结构)增加新能力。

Class Diagram

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

设计模式 - 访问者 - 图1

Implementation

  1. public interface Element {
  2. void accept(Visitor visitor);
  3. }
  1. class CustomerGroup {
  2. private List<Customer> 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 class Customer implements Element {
  2. private String name;
  3. private List<Order> orders = new ArrayList<>();
  4. Customer(String name) {
  5. this.name = name;
  6. }
  7. String getName() {
  8. return name;
  9. }
  10. void addOrder(Order order) {
  11. orders.add(order);
  12. }
  13. public void accept(Visitor visitor) {
  14. visitor.visit(this);
  15. for (Order order : orders) {
  16. order.accept(visitor);
  17. }
  18. }
  19. }
  1. public class Order implements Element {
  2. private String name;
  3. private List<Item> items = new ArrayList();
  4. Order(String name) {
  5. this.name = name;
  6. }
  7. Order(String name, String itemName) {
  8. this.name = name;
  9. this.addItem(new Item(itemName));
  10. }
  11. String getName() {
  12. return name;
  13. }
  14. void addItem(Item item) {
  15. items.add(item);
  16. }
  17. public void accept(Visitor visitor) {
  18. visitor.visit(this);
  19. for (Item item : items) {
  20. item.accept(visitor);
  21. }
  22. }
  23. }
  1. public class Item implements Element {
  2. private String name;
  3. Item(String name) {
  4. this.name = name;
  5. }
  6. String getName() {
  7. return name;
  8. }
  9. public void accept(Visitor visitor) {
  10. visitor.visit(this);
  11. }
  12. }
  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

JDK

  • javax.lang.model.element.Element and javax.lang.model.element.ElementVisitor
  • javax.lang.model.type.TypeMirror and javax.lang.model.type.TypeVisitor

设计模式 - 访问者 - 图2