多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
访问者模式可以给一系列对象透明的添加功能,并且把相关代码封装到一个类中。 对象只要预留访问者接口`Accept`则后期为对象添加功能的时候就不需要改动对象。 #### visitor.go ~~~go package visitor import "fmt" type Customer interface { Accept(Visitor) } type Visitor interface { Visit(Customer) } type EnterpriseCustomer struct { name string } type CustomerCol struct { customers []Customer } func (c *CustomerCol) Add(customer Customer) { c.customers = append(c.customers, customer) } func (c *CustomerCol) Accept(visitor Visitor) { for _, customer := range c.customers { customer.Accept(visitor) } } func NewEnterpriseCustomer(name string) *EnterpriseCustomer { return &EnterpriseCustomer{ name: name, } } func (c *EnterpriseCustomer) Accept(visitor Visitor) { visitor.Visit(c) } type IndividualCustomer struct { name string } func NewIndividualCustomer(name string) *IndividualCustomer { return &IndividualCustomer{ name: name, } } func (c *IndividualCustomer) Accept(visitor Visitor) { visitor.Visit(c) } type ServiceRequestVisitor struct{} func (*ServiceRequestVisitor) Visit(customer Customer) { switch c := customer.(type) { case *EnterpriseCustomer: fmt.Printf("serving enterprise customer %s\n", c.name) case *IndividualCustomer: fmt.Printf("serving individual customer %s\n", c.name) } } // only for enterprise type AnalysisVisitor struct{} func (*AnalysisVisitor) Visit(customer Customer) { switch c := customer.(type) { case *EnterpriseCustomer: fmt.Printf("analysis enterprise customer %s\n", c.name) } } ~~~ #### visitor\_test.go ~~~go package visitor func ExampleRequestVisitor() { c := &CustomerCol{} c.Add(NewEnterpriseCustomer("A company")) c.Add(NewEnterpriseCustomer("B company")) c.Add(NewIndividualCustomer("bob")) c.Accept(&ServiceRequestVisitor{}) // Output: // serving enterprise customer A company // serving enterprise customer B company // serving individual customer bob } func ExampleAnalysis() { c := &CustomerCol{} c.Add(NewEnterpriseCustomer("A company")) c.Add(NewIndividualCustomer("bob")) c.Add(NewEnterpriseCustomer("B company")) c.Accept(&AnalysisVisitor{}) // Output: // analysis enterprise customer A company // analysis enterprise customer B company } ~~~