eurekaさんのGoエンジニアによるミートアップに参加しました。 懇親会には参加できませんでしたが、熱々のpizzaとお酒をご用意いただきました。
3人のサーバーサイドエンジニアの方によるセッションの内容をまとめました。
Goのパッケージ構成について
Goはパッケージ構成悩みがち
- 経験言語に引っ張られる
- Goはシンプル故に言語化して説明するのが難しい
- パッケージの命名規則は The Go Blogに書いてある
抽象レイヤーはインターフェースの定義のみを書いて軽く薄くするの がいい
- 具象レイヤはインターフェースを満たしていくように書くといい
- ioパッケージはインターフェースの定義の仕方がきれいなので、参考になる
上位に抽象レイヤ、下位に具象レイヤを配置する場合が多い
- 上位に具象レイヤ、下位に抽象レイヤというパターンも稀にある
- ストラテジーパターンみたいな感じ
- 外部に公開するライブラリなど。個人の開発ではあまりない
- 具象レイヤの振る舞いを変えたい時に便利
- 凝ったデザインパターンはGoでは好まれない
一個のパッケージで作っておいて何処かのタイミングで細分化するのがやりやすい
- 著名なパッケージであるgolag/dep(ベンダリングツール)も、バージョンアップ時に一気にパッケージ構成を変えた
野良パッケージではなく、標準パッケージを参考にすること!!
感想
いままで聞いたことのなかったパッケージ構成のパターンを実例を交えながら見せていただき、勉強になりました。
会場からの質問で、ioパッケージの他に参考になる標準パッケージは?というものがありました。cryptパッケージがよいとのお話でした。
標準ライブラリのコードリーディングで学ぶGo
Yusuku Usuiさん いま話題のSREのチームでGoをたくさん書いていらっしゃる。
Goは標準ライブラリの可読性が高い
- 可読性とパフォーマンスのバランスに優れている
- 言語仕様が小さくシンプルなため compressパッケージを例に、実装例を追いながらコードリーディングの方法を紹介していく
構文解析をしてくれるプラグインがあると良い
- Goglandか、InteliJ + プラグインがいい
- ブラウザベースだとSourcegraphも良い
コードリーディングで得られるもの
- Goの考え方やイディオムが学べる
- 基本的なアルゴリズムをアプリケーションコードのように(軽めに)読める
感想
Goは標準パッケージや有名どころのパッケージが初心者でも大変読みやすいのが素晴らしいと思います。 コードリーディングを行うタイミングや、続けるモチベーションの保ち方について懇親会でお聞きしたかったのですが、聞きそびれてしまったのが残念でした。
またcompressパッケージの他に、API Clientだったらaws-sdk-goが良いお手本になるのでリーディングするのに良いと紹介いただきました。
Goぽいんとれっすん
@evalphobiaさん いつもWomen Who Go Tokyoの先生としてお世話になっている森川さん。SREチーム。
推奨エディタを決めておく
- セットアップ手順書が共有できて、共通設定ができる
コメントはちゃんと書く
- ちゃんと書いておけば関数内部のコメントはなくても良い
- 日本語話者の多い会社では、英語のコメントは読めない&書き間違いの原因になりがちなのでやめたほうがいい
golintを使う
- しっかり対応するなら英語コメントの下に日本語コメントを書くと良い
テストをちゃんと書く
- 書く文化を作る。テストコードがなかったらPRで指摘する
- CIの設定をしておく
- 実行方法を統一しておく
- make, gulp, bazel
- CIを変更する時にも簡単になるのでよい
- tips
- テーブルドリブンテスト
- サブテスト
- ゴールデンファイル
- 標準パッケージのテストとwebサービスのテストは形式が異なるので、そのまま参考になるとは限らない
- 外部パッケージを参考にするなら、メンテナンスされていて、大きすぎたり歴史が古すぎないものがよい
- BDDは不要
- 遅くなる
- テーブルドリブンテストの可読性が高いので不要
- テストの目的はあくまでバグ検知・高品質リリース
- 可読性とメンテナンス性は気にする必要がある
CIはなんでもいい
- go fmt, go vet, golintは必ず入れる
- @haya14busaさん作のreviewdogを入れると良い
並行処理 Concurrensyについて
- あまり使っていない
- -raceオプションをつけるとレースディテクションができる
- ボトルネックがあるときに使う
- ネットワーク処理周りと相性がいい
- ベンチマークをとって検証すること
- バックグランドデーモンでたまに使う
- バグ混入の可能性が高くなるのでむやみには使わない
ベンダリングについて
- 早めに入れる
- 新しくやるならdepかなあ
- 何を使っても年2回くらいベンダリングでつらいときはある、仕方ない
- 大きめのライブラリは内部用アダプタを作りましょう
情報共有の方法
- キャッチアップと共有は難しい
- 更新が早い
- 英語の情報が多い
- 本は古い
- 日本語の情報インフルエンサー
- ビジネスナレッジの共有方法
- Qiita, Confulence, Git book…なんでもいい
- OWNERSファイルを活用する
- 「この人に聞いたらいい」をまとめるファイル
パッケージ構成
- プロジェクトの規模や性質によってまちまち
- 細分化しすぎない。テストが遅くなる
- olivere/elasticは細分化されている例。サービスでここまで細分化すると大変
- 統一しすぎるのもだめ。あんばいが大事
- 機能ベース、ライブラリベースで分けるといい
- パッケージ名は簡潔にする。呼び出す時に大変にならないように
- ファイル名は多少冗長でも良い。IDEで検索する時に便利
- Goはパッケージベースなのでファイル名に自由さがある
pprof/trace
- pprofは全員が使えるようになるべき!
- CPUやメモリの使用率が見られる。デバッグがしやすい
- goroutineを追加したときのメモリリークの検知に使える
- trace機構は早い段階で入れて追いたほうがいい
- デバッグはあまり使わない。traceの方がいい
正しさよりも統一性が重要
- Goの正しさよりも、多少不器用でもサービスの統一性があった方がいい
感想
eurekaさんSREチームの開発体制や、チーム開発で大事にしていることのあらましがわかる、ボリューミーかつ濃厚な内容でした。 明日からすぐに活かせそうな知見を惜しげも無く発表していただき感謝ばかりです。
発表全体のまとめとして、チーム開発のベストプラクティスに従うこと、特有の癖のある部分はきちんと理解してルールを決めておくことの重要性を改めて強調されていたのが印象的でした。 Goに限ったことではなく、チームでコードの品質を良いものにしていくために、あらゆる場面でていねいなアプローチをとっていらっしゃるんだなということを感じることができました。