こんにちは。
2017年4月からGoでアプリを開発しておりますが、4月時点では完全にGo初心者でひどいコードを精製してしまったのでリファクタをしたいと思います。
現状
mainパッケージにしたapp.goに全てを書いている状態です。
最悪ですね。
github.com
Ginを使っています。
超軽量フレームワーク。
最低限の機能だけはいっているフレームワークなので、構成なんかは自力でなんとかしなくてはいけない。
調査
Goのアーキテクチャって何がいいんだろうと思って調べてみました。
qiita.com
クリーンアーキテクチャーかぁ…。
とりあえずやってみようと思って途中まで実装してみたのですが、
難しくてやめました。
こういう繊細なやつは私には向いてない。
せめてMVCくらいにはしたい。
と、思って考えたパッケージ構成はこれです。
└── src
├── app.go
├── controllers
├── database
│ └── models
├── utils
└── templates
役割
app.go
このファイルは一番最初に読み込むmain関数が書いてるファイルです。
中はこんな感じにしました。
package main
// importは省略
func main() {
router := gin.Default()
router.GET("/", func(c *gin.Context) {
controllers.Index(c)
})
router.GET("/main", func(c *gin.Context) {
controllers.Main(c)
})
router.Run(":5000")
}
dbの接続なんかもここでやってます。
router的な役割にして、必要なcontrollerを呼び出すようにしています。
controllerでdbが必要な時はここで、dbも渡すようにしています。
controllers
ざっくり、画面や機能に合わせていくつかのファイルに分けています。
中はこんな感じ。
package controllers
// importは省略
func InputedCompany(c *gin.Context) {
c.HTML(http.StatusOK, "inputed_company.tmpl", gin.H{})
}
func User(c *gin.Context, db *sql.DB) {
users, err := models.SelectUserAll(aaaaID, db)
if err != nil {
fmt.Printf(err.Error())
c.Redirect(http.StatusMovedPermanently, "/error")
}
c.HTML(http.StatusOK, "user.tmpl", gin.H{
"users": users,
})
}
modelから画面表示に必要なデータをとってくる。
入力がある場合にはmodelを呼び出して入力をやってもらう。
そして、最後に表示したいテンプレートを呼び出す。
models
package models
// importは省略
// User is personal information
type User struct {
ID int
Name string
Mail string
Pass string
}
// SelectUserAll is acquire all user data
func SelectUserAll(db *sql.DB) (users []User, err error) {
query := "SELECT id, name, mail, pass FROM user;"
result, err := db.Query(query)
if err != nil {
return users, err
}
var id int
var name string
var pass string
var mail string
for result.Next() {
if err := result.Scan(&id, &name, &mail, &pass); err != nil {
return users, err
}
users = append(users, User{id, name, pass, mail})
}
return users, nil
}
こんな感じ。
データをSelect,Insert,Update,Deleteするだけ。
utils
よく使う処理や定数をここにまとめました。
内容は割愛。
やってみて
初期状態がひどすぎるのであれなのですが、
かなりすっきりしたと思います。
私の知識不足でcontrollerがまだ煩雑な感じになってしまっているので、
今後なんとかしたいです。