diff --git a/notes/设计模式 - 访问者.md b/notes/设计模式 - 访问者.md
index 104bd102..3b8f3dfa 100644
--- a/notes/设计模式 - 访问者.md
+++ b/notes/设计模式 - 访问者.md
@@ -1,16 +1,26 @@
## 访问者(Visitor)
### 意图
-为一个对象结构(比如组合结构)增加新能力。
+在不修改元素类的前提下,为一个对象结构(比如组合结构)中的元素增加新的操作。
### 类图
-- Visitor:访问者,为每一个 ConcreteElement 声明一个 visit 操作
-- ConcreteVisitor:具体访问者,存储遍历过程中的累计结果
+- Visitor:访问者,为每一个 ConcreteElement 声明一个 visit 操作;
+- ConcreteVisitor:具体访问者,存储遍历过程中的累计结果;
+- Element:元素,声明 accept(Visitor) 方法;
- ObjectStructure:对象结构,可以是组合结构,或者是一个集合。
### 实现
+下面的例子用一个 GeneralReport 访问者统计客户、订单和商品的数量。元素的 accept() 中调用 visitor.visit(this),这次调用经过两次分派才落到正确的代码上:
+
+- 第一次,customer.accept(visitor) 按元素的实际类型选中 Customer 的 accept();
+- 第二次,accept() 中 this 的类型是 Customer,编译时选中 visit(Customer) 这个重载(重载按静态类型选择,见[多态](面向对象思想.md#多态)),运行时再按访问者的实际类型调用 GeneralReport 的实现。
+
+这种做法称为双分派(Double Dispatch)。
+
+新增一种报表只需要再写一个 Visitor 实现,Customer、Order、Item 都不用改;代价是新增一种元素时要修改 Visitor 接口和所有访问者,因此访问者适合元素类型稳定、操作经常增加的场景。
+
```java
public interface Element {
void accept(Visitor visitor);
@@ -65,7 +75,7 @@ public class Customer implements Element {
public class Order implements Element {
private String name;
- private List- items = new ArrayList();
+ private List
- items = new ArrayList<>();
Order(String name) {
this.name = name;
@@ -198,10 +208,10 @@ 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
+- javax.lang.model.element.Element 与 javax.lang.model.element.ElementVisitor;
+- javax.lang.model.type.TypeMirror 与 javax.lang.model.type.TypeVisitor。
## 参考资料
- 弗里曼. Head First 设计模式 [M]. 中国电力出版社, 2007.
-- Gamma E. 设计模式: 可复用面向对象软件的基础 [M]. 机械工业出版社, 2007.
+- Gamma E. 设计模式:可复用面向对象软件的基础 [M]. 机械工业出版社, 2007.