Go 如何减少与从JSON解组动态类型并发送到相关通道相关的重复代码?
考虑下面的示例,它接受一条JSON消息,该消息最终被解组为几种可能的类型。如何减少或删除与添加其他事件类型相关的样板代码Go 如何减少与从JSON解组动态类型并发送到相关通道相关的重复代码?,go,design-patterns,Go,Design Patterns,考虑下面的示例,它接受一条JSON消息,该消息最终被解组为几种可能的类型。如何减少或删除与添加其他事件类型相关的样板代码 package main import ( "encoding/json" "fmt" ) const input = ` { "type": "hello", "event": { "name": "Picard" } } ` type EventEnvelope struct { Type stri
package main
import (
"encoding/json"
"fmt"
)
const input = `
{
"type": "hello",
"event": {
"name": "Picard"
}
}
`
type EventEnvelope struct {
Type string
Event interface{}
}
type EventHello struct {
Name string
}
type EventHowdy struct {
Name string
}
type Display struct {
formal chan EventHello
western chan EventHowdy
}
func newDisplay() *Display {
return &Display{
formal: make(chan EventHello),
western: make(chan EventHowdy),
}
}
func (display *Display) run() {
for {
select {
case formal := <-display.formal:
fmt.Println("Hello", formal.Name)
case western := <-display.western:
fmt.Println("Howdy", western.Name)
}
}
}
func main() {
var event json.RawMessage
env := EventEnvelope{
Event: &event,
}
if err := json.Unmarshal([]byte(input), &env); err != nil {
fmt.Print(err)
}
display := newDisplay()
go display.run()
events(display, event, env.Type)
}
func events(display *Display, raw json.RawMessage, event string) {
switch event {
case "hello":
hello := EventHello{}
if err := json.Unmarshal(raw, &hello); err != nil {
fmt.Println(err)
} else {
display.formal <- hello
}
case "howdy":
howdy := EventHowdy{}
if err := json.Unmarshal(raw, &howdy); err != nil {
fmt.Println(err)
} else {
display.western <- howdy
}
default:
fmt.Println("No event handler")
}
}
包干管
进口(
“编码/json”
“fmt”
)
常量输入=`
{
“类型”:“你好”,
“事件”:{
“名称”:“Picard”
}
}
`
类型EventEnvelope结构{
类型字符串
事件接口{}
}
输入EventHello结构{
名称字符串
}
类型EventHowdy结构{
名称字符串
}
类型显示结构{
正式的chan Event你好
西区陈伟迪酒店
}
func newDisplay()*显示{
返回和显示{
正式:make(chan EventHello),
西部:制作(chan EventHowdy),
}
}
func(显示*显示)运行(){
为了{
挑选{
案例形式:=您可以使用类型工厂:
var types map[string]func() interface{} {"hello":func() interface{} {return &EventHello{}},
"howdy": func() interface{} {return &EventHowdy{}}}
工厂可用于使用其名称创建类型的新实例。您可以向这些类型添加新函数,以便它们可以选择自己的通道:
type sender interface {
send(Display)
}
func (e EventHello) send(d Display) {
d.formal<-e
}
感谢您优雅的解决方案!
type sender interface {
send(Display)
}
func (e EventHello) send(d Display) {
d.formal<-e
}
func events(display *Display, raw json.RawMessage, event string) {
evInstance:=types[event]()
if err := json.Unmarshal(raw, evInstance); err != nil {
fmt.Println(err)
} else {
evInstance.(sender).send(display)
}
}