golang的构建器模式

52 阅读1分钟

blog.stackademic.com/design-patt… 构建器模式:

  • 定义struct
  • 定义接口,接口包含构建过程的步骤
  • 实现接口
type QueueBuilder struct {  
consume <-chan amqp.Delivery  
queue *amqp.Queue  
ch *amqp.Channel  
errors []error  
}

type IQueueBuilder interface {  
InitChannel(conn *amqp.Connection) QueueBuilder  
AddQueueDef(name string, durable, autoDelete, exclusive, noWait bool, args amqp.Table) QueueBuilder  
AddListener() QueueBuilder  
Build() (<-chan amqp.Delivery, *amqp.Channel, []error)  
}

func (b QueueBuilder) InitChannel(conn *amqp.Connection) QueueBuilder {  
ch, err := conn.Channel()  
if err != nil {  
b.errors = append(b.errors, err)  
b.ch = nil  
return b  
}  
b.ch = ch  
return b  
}

func (b QueueBuilder) AddQueueDef(  
name string,  
durable bool,  
autoDelete bool,  
exclusive bool,  
noWait bool,  
args amqp.Table) QueueBuilder {  
if b.ch == nil {  
b.errors = append(b.errors, errors.New("channel not initialized"))  
return b  
}  
queue, err := b.ch.QueueDeclare(  
name,  
durable,  
autoDelete,  
exclusive,  
noWait,  
args,  
)  
if err != nil {  
b.errors = append(b.errors, err)  
}  
b.queue = &queue  
return b  
}

func (b QueueBuilder) AddListener() QueueBuilder {  
if len(b.errors) != 0 {  
b.errors = append(b.errors, errors.New("error occurred in the previous step"))  
return b  
}  
msgs, err := b.ch.Consume(  
b.queue.Name,  
"",  
true, // Auto-acknowledge  
false, // Exclusive  
false, // No local  
false, // No wait time  
nil,  
)  
if err != nil {  
b.errors = append(b.errors, err)  
}  
b.consume = msgs  
return b  
}

func (b QueueBuilder) Build() (<-chan amqp.Delivery, *amqp.Channel, []error) {  
if len(b.errors) != 0 {  
return nil, nil, b.errors  
}  
return b.consume, b.ch, nil  
}


conn, err := amqp.Dial(amqpURI)  
failOnError(err, "Failed to connect to RabbitMQ")  
defer conn.Close()  
var addQueue QueueBuilder  
consume, ch, errs := addQueue.  
InitChannel(conn).  
AddQueueDef("add", false, false, false, false, nil).  
AddListener().  
Build()  
if len(errs) != 0 {  
for _, err := range errs {  
log.Fatalf("%s", err)  
}  
panic("error for the 'add' queue")  
}  
var multQueue QueueBuilder  
consumeMulti, chMulti, errs := multQueue.  
InitChannel(conn).  
AddQueueDef("mult", false, false, false, false, nil).  
AddListener().  
Build()  
if len(errs) != 0 {  
for _, err := range errs {  
log.Fatalf("%s", err)  
}  
panic("error for the 'mult' queue")  
}  
var divQueue QueueBuilder  
consumeDiv, chDiv, errs := divQueue.  
InitChannel(conn).  
AddQueueDef("div", false, false, false, false, nil).  
AddListener().  
Build()  
if len(errs) != 0 {  
for _, err := range errs {  
log.Fatalf("%s", err)  
}  
panic("error for the 'div' queue")  
}  
// Start goroutines for each type of operation  
go add(consume, ch)  
go mult(consumeMulti, chMulti)  
go div(consumeDiv, chDiv)  
select {}