diff --git a/notes/设计模式.md b/notes/设计模式.md index 35bddad5..dc075cf7 100644 --- a/notes/设计模式.md +++ b/notes/设计模式.md @@ -2012,9 +2012,203 @@ Tea.addCondiments ### 意图 -提供便捷的维护方式来操作一组对象。它使你在不改变操作对象的前提下,可以修改或扩展对象的行为。 +为一个对象结构(比如组合结构)增加新能力。 -例如集合,它可以包含不同类型的元素,访问者模式允许在不知道具体元素类型的前提下对集合元素进行一些操作。 +### 类图 + +- Visitor:访问者,为每一个 ConcreteElement 声明一个 visit 操作 +- ConcreteVisitor:具体访问者,存储遍历过程中的累计结果 +- ObjectStructure:对象结构,可以是组合结构,或者是一个集合。 + +

+ +### 实现 + +```java +public interface Element { + void accept(Visitor visitor); +} +``` + +```java +class CustomerGroup { + + private List customers = new ArrayList<>(); + + void accept(Visitor visitor) { + for (Customer customer : customers) { + customer.accept(visitor); + } + } + + void addCustomer(Customer customer) { + customers.add(customer); + } +} +``` + +```java +public class Customer implements Element { + + private String name; + private List orders = new ArrayList<>(); + + Customer(String name) { + this.name = name; + } + + String getName() { + return name; + } + + void addOrder(Order order) { + orders.add(order); + } + + public void accept(Visitor visitor) { + visitor.visit(this); + for (Order order : orders) { + order.accept(visitor); + } + } +} +``` + +```java +public class Order implements Element { + + private String name; + private List items = new ArrayList(); + + Order(String name) { + this.name = name; + } + + Order(String name, String itemName) { + this.name = name; + this.addItem(new Item(itemName)); + } + + String getName() { + return name; + } + + void addItem(Item item) { + items.add(item); + } + + public void accept(Visitor visitor) { + visitor.visit(this); + + for (Item item : items) { + item.accept(visitor); + } + } +} +``` + +```java +public class Item implements Element { + + private String name; + + Item(String name) { + this.name = name; + } + + String getName() { + return name; + } + + public void accept(Visitor visitor) { + visitor.visit(this); + } +} +``` + +```java +public interface Visitor { + void visit(Customer customer); + + void visit(Order order); + + void visit(Item item); +} +``` + +```java +public class GeneralReport implements Visitor { + + private int customersNo; + private int ordersNo; + private int itemsNo; + + public void visit(Customer customer) { + System.out.println(customer.getName()); + customersNo++; + } + + public void visit(Order order) { + System.out.println(order.getName()); + ordersNo++; + } + + public void visit(Item item) { + System.out.println(item.getName()); + itemsNo++; + } + + public void displayResults() { + System.out.println("Number of customers: " + customersNo); + System.out.println("Number of orders: " + ordersNo); + System.out.println("Number of items: " + itemsNo); + } +} +``` + +```java +public class Client { + public static void main(String[] args) { + Customer customer1 = new Customer("customer1"); + customer1.addOrder(new Order("order1", "item1")); + customer1.addOrder(new Order("order2", "item1")); + customer1.addOrder(new Order("order3", "item1")); + + Order order = new Order("order_a"); + order.addItem(new Item("item_a1")); + order.addItem(new Item("item_a2")); + order.addItem(new Item("item_a3")); + Customer customer2 = new Customer("customer2"); + customer2.addOrder(order); + + CustomerGroup customers = new CustomerGroup(); + customers.addCustomer(customer1); + customers.addCustomer(customer2); + + GeneralReport visitor = new GeneralReport(); + customers.accept(visitor); + visitor.displayResults(); + } +} +``` + +```html +customer1 +order1 +item1 +order2 +item1 +order3 +item1 +customer2 +order_a +item_a1 +item_a2 +item_a3 +Number of customers: 2 +Number of orders: 4 +Number of items: 6 +``` ### JDK diff --git a/pics/ec923dc7-864c-47b0-a411-1f2c48d084de.png b/pics/ec923dc7-864c-47b0-a411-1f2c48d084de.png new file mode 100644 index 00000000..007e9646 Binary files /dev/null and b/pics/ec923dc7-864c-47b0-a411-1f2c48d084de.png differ