Open6

Goなんもわからん

あざらしあざらし

テスト

https://www.twihike.dev/docs/golang-primer/testing

コマンドなど

go test ./...
PJ全部のテストコードを実行

go test ./hoge
hoge直下のテストコードを実行

go test ./hoge -run TestFuga
特定のテストだけ実行

詳細なログを出す場合は -v オプションをつける
カバー率を知りたい場合は -cover オプションをつける(カバレッジ)

gomock

https://github.com/golang/mock

↑のは2023年にサポート終了している
後継は https://github.com/uber-go/mock になる

https://ramble.impl.co.jp/3235/

https://zenn.dev/sanpo_shiho/articles/01da627ead98f5

https://qiita.com/maooz4426/items/63071aba6a69c9a55ef4

あざらしあざらし

クリーンアーキテクチャ

って何

  • ビジネスロジック(ドメイン)を中心に置き、インターフェースの層や技術を外側に配置する設計
  • システムの保守性・拡張性・テスト容易性を高めるためのアーキテクチャ
  • 役割が明確に分離する
    • 1つ変更しても、他の層には影響がないように作ることができる
    • 既存機能の改修の場合、手を入れる場所が明確になる
    • 他の機能への影響を減らせる
    • テストコードを書きやすい
    • バグがあった時にどこが原因かの特定がしやすい

例:じゃんけんアプリを作るとする

グーはチョキに勝つ、というのがメインのルール(ビジネスロジック)
→これが、MySQL使おうが、Oracleだろうが、この根底のロジックは変わらないよね
→つまり、何かロジック以外の部分を変えたくなってもロジックには影響しないように作ろう!ということ

https://zenn.dev/sre_holdings/articles/a57f088e9ca07d
https://qiita.com/o-yyu-o/items/755cb47f733687e8331f

ビジネスロジック

システム固有の処理を行う部分・・・みたいなイメージ

https://wa3.i-3-i.info/word13666.html
https://qiita.com/os1ma/items/25725edfe3c2af93d735

MVC との違い

  • 役割、層の違い
    • MVC:3つに分かれる
    • クリーン(略):4つの層に分かれるのがベース。なんならもっと細かい場合もある
  • 依存の違い
    • MVC:依存の方向性は決められていない、VCは依存しているし、CMは依存していたりする
    • クリーン:依存性の方向性に厳格なルールがある、常に内側から外側にのみ発生する、逆はありえない
  • ビジネスロジック(達成したいルール、処理)
    • MVC:通常はMに含まれるが実装による
    • クリーン:2つの層に分ける
      • エンティティ層:最重要のビジネスルール
      • ユースケース層:アプリ固有のルール

構成例

  • model
    • MVCで言えばMの部分
    • データ構造とビジネスルールを定義(ドメインエンティティ)
    • じゃんけんで言えば
      • データ構造:「手の種類」「勝敗結果」「ゲーム履歴」など
      • ビジネスルール:どの手がどの手に勝つのかの判定
  • usecase
    • 機能のインターフェース
    • じゃんけんで言えば
      • じゃんけんを始める、履歴を取得する などの機能のIF部分
  • interactor
    • 実際のusecaseの実装部分
    • じゃんけんで言えば
      • 実際に対戦を始める時の処理、履歴を取得する処理
  • repository
    • データの操作に関するインターフェース
    • じゃんけんで言えば
      • ゲーム履歴を保存、取得 などのDBに関わるIF部分
  • datastore
    • 実際のrepositoryの実装部分
    • じゃんけんで言えば
      • 履歴テーブルへの保存、取得の処理

処理の流れ

どういう処理の流れになるのか?

じゃんけんしたいよ!

  1. フロントから「POST /janken」が来る
  2. リクエスト受け取り、usecaseを呼ぶ
  3. usecase を実装しているinteractorが実行。処理に必要な情報が欲しいのでrepositoryを呼ぶ
  4. repositoryを実装しているdatastoreが実行。実際のDB処理を行って情報を取得
  5. datastoreから情報を受け取って必要な処理を行う、usecaseの出力DTOに情報をつめる
  6. interactorから情報を受け取ってフロントに返す
あざらしあざらし

DTO

Data Transfer Object(データ転送オブジェクト)のこと
システムの層と層の間(webapi と usecase の間)でデータを受け渡すためのハコ

例:じゃんけん履歴を日付で絞り込んで取得したい

リクエストDTO

(api はHTTPリクエストを受け取ってこのHistoryInに情報をつめる)

type HistoryIn struct {
    PlayerID  string    // 誰の履歴か
    FromDate  string    // いつから(例: "2025-08-01")
    ToDate    string    // いつまで(例: "2025-08-20")
    Page      int       // ページ番号(ページング)
    PageSize  int       // 1ページあたり件数
}

レスポンスDTO

(Interactor はこれを使ってRepository に問い合わせ、結果をHistoryListOutにつめて apiに返す)

type HistoryListOut struct {
    Matches []HistoryOut // 履歴の配列
    Total   int          // 全件数(ページング用)
}
あざらしあざらし

Goa

https://goa.design/ja/

  • REST API を使いたい時に利用することが多い
  • ビジネスロジック中心で開発ができる
  • Swaggerなど自動生成される
    • Disignのファイルを作った後、 goagen のコマンドを実行すると、色々と必要なファイルや関数を自動生成してくれる

https://qiita.com/hiroykam/items/398875ef4cff4d35454e

今はv3が一番新しいのかな?(なお使っているのはv1)

あざらしあざらし

DI

依存性の注入
→処理に必要なオブジェクトを外部から注入できるようにする ということ

関数とかにベタ書きしないで、別のIFで管理しようねーみたいな感じ
→関数とかにベタ書きしちゃうと柔軟性がなくなったりテストしにくかったり・・・ということが発生する

たとえばDBにアクセスする関数内でMySQLにアクセスするよ!とかやってる場合
→DBをOracleとかに変えたらどうするの?関数内も変える必要あるよね?
という問題が発生する

外から注入する(関数外でDBを指定する)ことで、DBが変わったらそのIF部分のみ変えればよいよね〜
(つまりクリーンアーキテクチャするにはDIの考えが必須という感じなのかな?)

https://qiita.com/yoshinori_hisakawa/items/a944115eb77ed9247794

DIコンテナ

DIを簡単に使えるようにするツール
たとえばwire というライブラリを使う

wire

https://github.com/google/wire
(2025年8月にサポート終了してるやんけ)

  1. wire.goを書く
  2. wire.go から wire_gen.go が生成される(wire gen を実行する)
  3. main.go みたいな全体管理のファイルから wire_gen.go が使われる

https://qiita.com/kez/items/657da2b8b643b69a2e21