mirror of
https://github.com/crazybber/go-pattern-examples.git
synced 2024-11-22 03:46:03 +03:00
finish visitor pattern
This commit is contained in:
parent
cbdb15f07f
commit
0c69fdb726
@ -1,6 +1,14 @@
|
||||
# 访问者模式
|
||||
|
||||
访问者模式可以给一系列对象透明的添加功能,并且把相关代码封装到一个类中。
|
||||
访问者模式,
|
||||
|
||||
对象只要预留访问者接口`Accept`则后期为对象添加功能的时候就不需要改动对象。
|
||||
访问者模式的目的是为了解耦对象和对象的使用和处理逻辑,一边提供资源,一边使用,也可以说是解耦生产出来的产品和产品消费者。
|
||||
|
||||
一个石油的例子,油田提供石油,不同的客户将石油用到不同的地方,可能用于生产武器,可能用于提纯材料,生产服装,也可能只是用于只是用于提供动力,这些客户就是石油的不同visitor.
|
||||
|
||||
客户买石油的时候,都要遵循油田的购买方式,否则,就不卖给你,这个特定的购买方式就是指Visitor模式中常说的Accept方法。
|
||||
|
||||
打游戏是个不错的例子。
|
||||
|
||||
玩家角色需要跟NPC,其他玩家,以及游戏环境,交换这些都是Visit的过程.
|
||||
|
||||
|
@ -2,73 +2,58 @@ package visitor
|
||||
|
||||
import "fmt"
|
||||
|
||||
type Customer interface {
|
||||
Accept(Visitor)
|
||||
////////////////////////////////
|
||||
//使用石油的例子
|
||||
|
||||
//IGasResource 作为资源提供接口
|
||||
type IGasResource interface {
|
||||
Accept(IGasVisitor)
|
||||
}
|
||||
|
||||
type Visitor interface {
|
||||
Visit(Customer)
|
||||
//gas 汽油
|
||||
type gas struct {
|
||||
density int
|
||||
}
|
||||
|
||||
type EnterpriseCustomer struct {
|
||||
//IGasVisitor 访问者接口
|
||||
type IGasVisitor interface {
|
||||
Visit(gas)
|
||||
}
|
||||
|
||||
//Accept 接待汽油客户
|
||||
func (g gas) Accept(visitor IGasVisitor) {
|
||||
visitor.Visit(g)
|
||||
}
|
||||
|
||||
//diesel 柴油
|
||||
type diesel struct {
|
||||
energy int
|
||||
}
|
||||
|
||||
//IDieselVisitor 访问者接口
|
||||
type IDieselVisitor interface {
|
||||
Visit(diesel)
|
||||
}
|
||||
|
||||
//Accept 提供柴油
|
||||
func (d diesel) Accept(visitor IDieselVisitor) {
|
||||
visitor.Visit(d)
|
||||
}
|
||||
|
||||
//militaryFactory 军工厂,消费石油,制造务器
|
||||
type militaryFactory struct {
|
||||
name string
|
||||
}
|
||||
|
||||
type CustomerCol struct {
|
||||
customers []Customer
|
||||
//Visit 军工厂只够买柴油,制造武器
|
||||
func (m *militaryFactory) Visit(d diesel) {
|
||||
fmt.Println("militaryFactory: use diesel with inner energy", d.energy)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
// clothFactory 服务装类工厂,购买汽油,制造化纤物品
|
||||
type clothFactory struct{}
|
||||
|
||||
//Visit 购买汽油
|
||||
func (c *clothFactory) Visit(g gas) {
|
||||
fmt.Println("clothFactory: use gas with density", g.density)
|
||||
}
|
||||
|
@ -1,15 +1,24 @@
|
||||
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
|
||||
import "testing"
|
||||
|
||||
func TestVisitor(t *testing.T) {
|
||||
|
||||
//汽油提供给,制衣工厂
|
||||
g := gas{density: 100}
|
||||
|
||||
//柴油,提供给军工厂
|
||||
d := diesel{energy: 897}
|
||||
|
||||
//购买石油的客户
|
||||
m := &militaryFactory{}
|
||||
|
||||
c := &clothFactory{}
|
||||
|
||||
g.Accept(c)
|
||||
|
||||
d.Accept(m)
|
||||
|
||||
}
|
||||
|
||||
func ExampleAnalysis() {
|
||||
|
Loading…
Reference in New Issue
Block a user