2014-10-20 73 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