我開始嘗試Go,到目前爲止它一直是一個爆炸。我決定製作一個小應用程序,它可以幫助朋友在他的(小)公司組織信息業務相關信息,我想我會用Go來實現它。避免反思 - 如何最好地重構此代碼?
我沒有(確切地說)遇到問題,這更多的是一個問題,我應該考慮什麼時候使用反射?例如,我有3種相關的類型:Company
,Project
和Staff
。他們都有幾個共同的領域(如id
,name
),你可以想象,從數據庫加載它們的功能(我使用的是MySQL
)都非常相似。
看LoadCompany()
,LoadStaff()
,並且LoadProject()
:
// Loads the company from the database with the given id.
func LoadCompany(id int) (Company, error) {
db := tools.OpenDB()
defer db.Close()
stmt, err := db.Prepare("SELECT * FROM companies WHERE id = ?")
if err != nil {
log.Panic(err)
}
var c Company
err = stmt.QueryRow(id).Scan(&c.id, &c.FullName, &c.Name, &c.History, &c.Overview, &c.Est, &c.Phone, &c.Website, &c.Email)
if err != nil {
return Company{}, err
}
return c, nil
}
// Loads the staff from the database with the given id.
func LoadStaff(id int) (Staff, error) {
db := tools.OpenDB()
defer db.Close()
stmt, err := db.Prepare("SELECT * FROM staff WHERE id = ?")
if err != nil {
log.Panic(err)
}
var s Staff
err = stmt.QueryRow(id).Scan(&s.id, &s.FullName, &s.Name, &s.Email, &s.Joined, &s.Left, &s.History, &s.Phone, &s.Position)
if err != nil {
return Staff{}, err
}
return s, nil
}
// Loads the project from the database with the given id.
func LoadProject(id int) (Project, error) {
db := tools.OpenDB()
defer db.Close()
stmt, err := db.Prepare("SELECT * FROM projects WHERE id = ?")
if err != nil {
log.Panic(err)
}
var p Project
err = stmt.QueryRow(id).Scan(&p.id, &p.Title, &p.Overview, &p.Value, &p.Started, &p.Finished, &p.Client, &p.Architect, &p.Status)
if err != nil {
return Project{}, err
}
return p, nil
}
當我寫LoadCompany()
,我感覺我自己(啊哈作爲初級/中級程序員),因爲它似乎是最小的,乾淨的很不錯。但正如我寫的LoadStaff()
和LoadProject()
,我所做的只是複製和調整。我敢肯定有一個更好的方式來做到這一點,但我厭倦跳進反思,讀Pike's post on it後:
[反射是一種強大的工具,應該小心使用和避免,除非絕對必要。
所以我的問題是,我應該使用反射,如果是的話,你能給我一些關於這種最好技術的指針嗎?這只是冰山一角,因爲我覺得其餘的與這些類型相關的函數和方法都是重複的(並且不會讓我開始測試!)。
謝謝!
明確指定列順序看看https://github.com/jmoiron/sqlx。 – kostya
謝謝......那應該解決掃描重複,關於3個函數和反射的一般建議嗎? –