2014-10-20 39 views
0

我正在从一个文件中读取json数据并使用gob编码将它发送到远程服务器,但我对我的代码不满意,我尝试了几种方法来获得更通用的功能,但是我失败了,我的代码工作的唯一方法是为每个类型使用相同的函数。按类型划分的功能?如何重构它?

我试着用开关的类型,但以同样的方式是需要重复的代码,以解组和编码采空区数据

请,能有人帮助我了解如何改进呢?

两种类型:

type Data1 struct{ 
ID int 
Message string 
} 

type Data2 struct{ 
Serial int 
Height float64 
Loss float64 
Temp float64 
Oil float64 
} 

功能为数据1型

func SenderData1(address string, buff *filebuffer.Buffer) { 
    var conn net.Conn 
    var err error 
    var line string 
    var obj Data1 
    for { 
     line, err = buff.Pop() 
     if err != nil { 
      log.Critical("Error Poping:", err.Error()) 
      continue 
     } 
     if len(line) == 0 { 
      time.Sleep(1 * time.Second) 
      continue 
     } 
     if err := json.Unmarshal([]byte(line), &obj); err != nil { 
      log.Critical("Error Unmarshaling:", err.Error()) 
      continue 
     } 
     for { 
      log.Info("Trying to connect with Server...") 
      conn, err = net.Dial(PROTO, address) 
      // If err try to connect again 
      if err != nil { 
       log.Error("Error connecting:", err.Error()) 
       time.Sleep(1 * time.Second) 
       continue 
      } 
      // If connected break the loop 
      break 
     } 
     log.Debug("Sending ", obj, " to:", address) 

     encoder := gob.NewEncoder(conn) 
     err := encoder.Encode(obj) 
     if err != nil { 
      log.Critical("Error Encoding Gob:", err.Error()) 
     } 
     // Timer between every sending, ie. Reading from buffer 
     time.Sleep(300 * time.Millisecond) 
     conn.Close() 
    } 
} 

同样的功能,但对于数据2型

func SenderData2(address string, buff *filebuffer.Buffer) { 
    var conn net.Conn 
    var err error 
    var line string 
    var obj Data2 
    for { 
     line, err = buff.Pop() 
     if err != nil { 
      log.Critical("Error Poping:", err.Error()) 
      continue 
     } 
     if len(line) == 0 { 
      time.Sleep(1 * time.Second) 
      continue 
     } 
     if err := json.Unmarshal([]byte(line), &obj); err != nil { 
      log.Critical("Error Unmarshaling:", err.Error()) 
      continue 
     } 
     for { 
      log.Info("Trying to connect with Server...") 
      conn, err = net.Dial(PROTO, address) 
      // If err try to connect again 
      if err != nil { 
       log.Error("Error connecting:", err.Error()) 
       time.Sleep(1 * time.Second) 
       continue 
      } 
      // If connected break the loop 
      break 
     } 
     log.Debug("Sending ", obj, " to:", address) 

     encoder := gob.NewEncoder(conn) 
     err := encoder.Encode(obj) 
     if err != nil { 
      log.Critical("Error Encoding Gob:", err.Error()) 
     } 
     // Timer between every sending, ie. Reading from buffer 
     time.Sleep(300 * time.Millisecond) 
     conn.Close() 
    } 

回答

2

添加分配所述类型的新值的参数接收和发送:

func SenderData1(address string, buff *filebuffer.Buffer) { 
    SenderData(address, buff, func() interface{} { return new(Data1) }) 
} 

func SenderData2(address string, buff *filebuffer.Buffer) { 
    SenderData(address, buff, func() interface{} { return new(Data2) }) 
} 

func SenderData(address string, buff *filebuffer.Buffer, newfn func() interface{}) { 
    var conn net.Conn 
    var err error 
    var line string 
    for { 
     line, err = buff.Pop() 
     if err != nil { 
      log.Critical("Error Poping:", err.Error()) 
      continue 
     } 
     if len(line) == 0 { 
      time.Sleep(1 * time.Second) 
      continue 
     } 
     obj := newfn() 
     if err := json.Unmarshal([]byte(line), obj); err != nil { 
      log.Critical("Error Unmarshaling:", err.Error()) 
      continue 
     } 
     for { 
      log.Info("Trying to connect with Server...") 
      conn, err = net.Dial(PROTO, address) 
      // If err try to connect again 
      if err != nil { 
       log.Error("Error connecting:", err.Error()) 
       time.Sleep(1 * time.Second) 
       continue 
      } 
      // If connected break the loop 
      break 
     } 
     log.Debug("Sending ", obj, " to:", address) 

     encoder := gob.NewEncoder(conn) 
     err := encoder.Encode(obj) 
     if err != nil { 
      log.Critical("Error Encoding Gob:", err.Error()) 
     } 
     // Timer between every sending, ie. Reading from buffer 
     time.Sleep(300 * time.Millisecond) 
     conn.Close() 
    } 
} 

此答案中的代码每次通过循环分配一个新值,而问题中的代码分配一次对象。通过循环分配每一次可防止接收到的JSON对象之间的串扰。

+0

我该如何命名?我从来没有想过这样的事情。 – Jzala 2014-10-20 21:29:26

+0

我有同样的问题,有渠道作为参数的功能,我可以做同样的功能吗? – Jzala 2014-10-20 22:01:57