GoのMVC

最近業務でGoの修正を行う機会があり、クライアント側しか触ってこなかった自分には未知のことがたくさんあった。
まずは大枠としてMVCから学ぶ。

 

 
MVCレイヤーアーキテクチャという設計手法に基づいている。

レイヤーアーキテクチャ

アプリケーションを責務に応じたいくつかの層としてとらえる設計手法。

View ユーザーインターフェース モデルのデータを取り出してユーザが見るのに適した形で表示する要素
Controller アプリケーション層 ユーザからの入力(通常イベントとして通知される)をモデルへのメッセージへと変換してモデルに伝える要素
Model ドメイン データと手続きを表現し、データの変更をViewに通知する要素
  • 各オブジェクトはいずれかの層に属し、複数の層にまたがることはない
  • 層の関係は一方通行であり、相互参照する関係は層をまたがない

ModelはControllerやViewでどう呼び出されるか知るべきではないし、ControllerはViewがどのように描画するか知るべきでない。
互いの層を一方的に利用するようにすることで、オブジェクト間の結合を疎に保ち、ドメインロジックの凝集度を高める。

これは作り手により異なるところかもしれないが、Goの勉強なので自社で扱っているプロダクトのGoの構造をこれにあてはめた。

f:id:yuri_iOS:20180612001814p:plain

Controller

  • routes: アプリからユーザーが入力したデータを受け取り、どの処理をするかをモデルへ通知する。
  • handlers: モデルへ通知する前にセッションのチェックなど毎回実施されるチェック処理を行う。
  • helpers: 便利道具。毎回実施するチェック、とはいかないがさまざまなところで使う処理群。

Model

routes
func New (r * httprouter.Router) {
    r.GET('users/:id', handlersLoginRequired(GetUser))
}

handlersであるhandlersLoginRequired()でユーザーがログインしていることを確認し、modelのGetUser()へ通知する。

models
type User struct {
    Id    Int64        `db:"id"     json:"id"`
    Name  String       `db:"name"   json:"name"`
}

func (u *User) Login() {
  // ログインのビジネスロジック...
}

構造体の定義(型とdb,jsonでのkeyの定義)とその構造体に紐づくビジネスロジックの処理がmodels配下に書かれる。