Skip to content

Commit 3b2d0fd

Browse files
committed
add visitor mode
1 parent d5f4abd commit 3b2d0fd

File tree

3 files changed

+104
-0
lines changed

3 files changed

+104
-0
lines changed

23_visitor/README.md

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# 访问者模式
2+
3+
访问者模式可以给一系列对象透明的添加功能,并且把相关代码封装到一个类中。
4+
5+
对象只要预留访问者接口`Accept`则后期为对象添加功能的时候就不需要改动对象。
6+

23_visitor/visitor.go

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package visitor
2+
3+
import "fmt"
4+
5+
type Customer interface {
6+
Accept(Visitor)
7+
}
8+
9+
type Visitor interface {
10+
Visit(Customer)
11+
}
12+
13+
type EnterpriseCustomer struct {
14+
name string
15+
}
16+
17+
type CustomerCol struct {
18+
customers []Customer
19+
}
20+
21+
func (c *CustomerCol) Add(customer Customer) {
22+
c.customers = append(c.customers, customer)
23+
}
24+
25+
func (c *CustomerCol) Accept(visitor Visitor) {
26+
for _, customer := range c.customers {
27+
customer.Accept(visitor)
28+
}
29+
}
30+
31+
func NewEnterpriseCustomer(name string) *EnterpriseCustomer {
32+
return &EnterpriseCustomer{
33+
name: name,
34+
}
35+
}
36+
37+
func (c *EnterpriseCustomer) Accept(visitor Visitor) {
38+
visitor.Visit(c)
39+
}
40+
41+
type IndividualCustomer struct {
42+
name string
43+
}
44+
45+
func NewIndividualCustomer(name string) *IndividualCustomer {
46+
return &IndividualCustomer{
47+
name: name,
48+
}
49+
}
50+
51+
func (c *IndividualCustomer) Accept(visitor Visitor) {
52+
visitor.Visit(c)
53+
}
54+
55+
type ServiceRequestVisitor struct{}
56+
57+
func (*ServiceRequestVisitor) Visit(customer Customer) {
58+
switch c := customer.(type) {
59+
case *EnterpriseCustomer:
60+
fmt.Printf("serving enterprise customer %s\n", c.name)
61+
case *IndividualCustomer:
62+
fmt.Printf("serving individual customer %s\n", c.name)
63+
}
64+
}
65+
66+
// only for enterprise
67+
type AnalysisVisitor struct{}
68+
69+
func (*AnalysisVisitor) Visit(customer Customer) {
70+
switch c := customer.(type) {
71+
case *EnterpriseCustomer:
72+
fmt.Printf("analysis enterprise customer %s\n", c.name)
73+
}
74+
}

23_visitor/visitor_test.go

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package visitor
2+
3+
func ExampleRequestVisitor() {
4+
c := &CustomerCol{}
5+
c.Add(NewEnterpriseCustomer("A company"))
6+
c.Add(NewEnterpriseCustomer("B company"))
7+
c.Add(NewIndividualCustomer("bob"))
8+
c.Accept(&ServiceRequestVisitor{})
9+
// Output:
10+
// serving enterprise customer A company
11+
// serving enterprise customer B company
12+
// serving individual customer bob
13+
}
14+
15+
func ExampleAnalysis() {
16+
c := &CustomerCol{}
17+
c.Add(NewEnterpriseCustomer("A company"))
18+
c.Add(NewIndividualCustomer("bob"))
19+
c.Add(NewEnterpriseCustomer("B company"))
20+
c.Accept(&AnalysisVisitor{})
21+
// Output:
22+
// analysis enterprise customer A company
23+
// analysis enterprise customer B company
24+
}

0 commit comments

Comments
 (0)