207 lines
4.2 KiB
Java
207 lines
4.2 KiB
Java
## 访问者(Visitor)
|
||
|
||
### Intent
|
||
|
||
为一个对象结构(比如组合结构)增加新能力。
|
||
|
||
### Class Diagram
|
||
|
||
- Visitor:访问者,为每一个 ConcreteElement 声明一个 visit 操作
|
||
- ConcreteVisitor:具体访问者,存储遍历过程中的累计结果
|
||
- ObjectStructure:对象结构,可以是组合结构,或者是一个集合。
|
||
|
||
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/79c6f036-bde6-4393-85a3-ef36a0327bd2.png"/> </div><br>
|
||
|
||
### Implementation
|
||
|
||
```java
|
||
public interface Element {
|
||
void accept(Visitor visitor);
|
||
}
|
||
```
|
||
|
||
```java
|
||
class CustomerGroup {
|
||
|
||
private List<Customer> 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<Order> 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<Item> 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
|
||
|
||
- javax.lang.model.element.Element and javax.lang.model.element.ElementVisitor
|
||
- javax.lang.model.type.TypeMirror and javax.lang.model.type.TypeVisitor
|