組織における、エンジニアの情報共有について。あるいは、レビューや設計について。

これは、「ドリコム Advent Calendar 2015 その2」の、8日目の記事になる。

7日目は、middlemanとGitHub Pagesでブログを5分で開設!ほか盛りだくさん! | いくら寝ても眠たい だった。


私は、ドリコムでエンジニアをしている matsusaki (@misoobu) という者だ。 ここでは、最近考えることの多い、組織におけるエンジニアの情報共有と、そのあるべき姿について書く。 また、それに関連して、コードレビューや設計についても触れる。 内容は、エンジニア視点のものになる。

情報共有は、組織にとって極めて重要だが、簡単なことではない。 本記事が、再考するきっかけとなれば、幸いである。

情報共有とは

情報共有とは、「他人と、必要となる情報を伝え合い、活用する」という行為である。 これは、大小至る所で行われている事だろう。 この出来により、行動時の円滑さや効率は大きく変わってくる。 その為、大切なのだ。

ここでは、「チームでサービス開発をするエンジニア」に焦点を絞って、話を進める。

情報共有を失敗するとどうなるのか

情報共有が上手くいかなかった時に、どのようなことが起こり得るのか。

  • 認識齟齬による、作業効率の悪化やクオリティの低下
  • 誰が何をしているのか分からない
  • 高コストな、コードや設計のレビューとその成果物の保守作業
  • 充実しない会議による、時間浪費
  • 有用な情報があっても、知らない
  • 意図しない車輪の再発明
  • 実装と乖離したドキュメント
  • 遅い障害対応

目を覆いたくなるような、悲惨な光景である。 これらを防ぐために、情報共有を見直していく。

様々な情報共有

例えば、以下の様な内容の情報共有が行われる。

  • プロジェクトの状況や方針
  • 作業内容とその状況
  • プログラムの設計やコード
  • ドキュメント
  • 障害情報
  • 日報

それぞれについて、確認していく。

プロジェクトの状況や方針

プロジェクトの、状態や目指す方向を確認し、メンバーの目線を揃える為に行われる。 この共有が、優先事項の適切な判断、目的の理解、メンバーの意思統一に繋がる。

作業内容とその状況

メンバーが、何をしていて、どれだけ進んでいるかを把握する為に行われる。 また、プロジェクトの見通しを良くし、課題の発見にも役立つ。 前項のプロジェクト現状と合わせて、いわゆる朝会にまとめて行われることが多いようだ。 エンジニアとしては、他職種にもある程度分かりやすく、簡潔に現状を伝えることを心がけたい。

プログラムの設計やコード

日々行われるレビューも、情報共有と言っていいだろう。 双方に時間が掛かりがちな行為なので、よく考えておきたい。 ここでは、私の経験から得た、効率的なレビューの知見を紹介する。

なお、社内では、コードの管理に GitLab と GitHub を使っている。

レビューの目的

第三者が確認する事で、クオリティを高めたり、その対象についての把握者を増やすことが目的である。 これにより、バグを減らし、メンテナンスコストを下げ、総合的・長期的に効率を上げる。 また、メンバーのスキル向上も望めるだろう。

レビューをするときに心がけていること

これは、チームの規模によって変わってくるだろうから、ここでは10人以下のエンジニアチームメンバーがいることを想定する。 また、きっちりやりきると時間が掛かり過ぎることもあるので、適度な範囲で形式を崩すこともある。

早めにレビューをする

レビューをする時は、出来るだけ後回しにせず、見かけたその場でレビューをするようにしている。 こうすると、その対象物の展開は早くなり、レビューをされる側は効率よく対応がしやすい。 物は早く出来上がるだろう。 レビューをする側は、自身の作業の一時中断により、少し手が止まるかも知れないが、前述の利点は大きい。

コードレビューの流れ

pull request のタイトル、説明を読み、内容を理解する

この時点から、違和感がないか確認する。

メモを取りながら、コードを確認する

全体的な作りを先に見て、次に細かい所を見る。 これは、全体的な作りに問題があり修正を行う場合、それにより細かい指摘箇所はなくなる可能性がある為だ。 確認した結果、指摘事項がない事も多い。

作業を讃えるコメントする

指摘により、ネガティブな印象を与えない為である。 レビューは攻撃ではない。

メモを見ながら、指摘点をコメントする

全体的な作りの問題から先に、指摘のコメントを付ける。 これは、修正作業のしやすさを考慮してのものである。 コメントは、出来るだけ柔らかく、分かり易くを心がける。

モチベーション

お互いのスキルを高める行為でもあるので、積極的にやっていきたい。 折角やるのだから、自身の糧となるようにする。 また、簡単なミスや、頻繁に指摘する事項は、毎回指摘するのは厳しいので、後述の自動化を検討する。

レビューに反応や対応をして貰えたら感謝する

議論になる場合もあるが、円滑にコミュニケーションをする。

レビューをされるときに心がけていること

レビューをしやすい状態にする

コード、コミットの粒度とメッセージ、pull request の粒度とタイトルと説明、それぞれを分かりやすく整える。

お互いに少しの時間を使ってレビューをしやすくすることで、全体としての効率は上がる。 そして勿論、コードはより良くなる。

レビューを貰ったら、早めに対応する

これも、スピード感を持って対応を進める為である。 対応に取り掛かれるまでに時間が掛る場合や、少し考えたり調べてから答えたい場合には、一旦その由を伝えるコメントをするようにする。 無反応な時間が長いと、対応が進んでいるのか分からない。

レビューされることを感謝する

同じく。

「大人の事情」で、悪い事を認識しながらも行う場合は、その事を示す

例えば、時間が取れなかったり、緊急性が高く急ぎの対応となり、ベストでない選択をする時は、その事を示す。 いわゆる技術的負債を選択する場面もあるはずだ。 しかし、レビューをする側がその状況を分かっていない場合は、指摘せざるを得なく、効率的でないので、その無駄はなくすべきだ。

「周りに合わせる」は、良くない場合がある

周辺の似た実装をただ真似て作るのではなく、それがベストかを確認する。 結果として、周りに合わせた実装がベストな場面も多い。 合わせる方針を続けた場合、もしその元の実装に良くない所があると、コードは悪化の一途を辿ることになる。

自動化で人間による作業を減らす

コーディング規約の違反や、テストが落ちるようになったなどの、定型化した指摘は面倒である。 人間がやるべきではない。 自動化が出来るものは、積極的に自動化する。

ドリコムには、共通の rubocop の設定がある。

rubocop のしつけ方 - onk.ninja

多くのプロジェクトでこの規約を導入しており、自動で違反がコメントされる体制のプロジェクトもある。

同じように、自動テストも行われている。

余談になるが、コーディング規約は、どうしても個人の好みが出てしまう所である。 設定に迷った時は、近くの強い人に決めて貰うか、なるべくデフォルト推しが良いと考えている。

通知方法

コミットを push した時、pull request を作った時などのアクションを通知する方法は、いくつかある。 最近は、普段から使っているテキストチャットに、bot がそれらのアクションを投稿していく方法が、やりやすいと感じている。 集中力は切られにくく、流れも見やすい。 自然とメンバーが見に行ける状況を作りたい。

良い設計とは

良い設計により、後々の情報共有の形も変わってくると言えるだろう。 なぜ良い設計をしたいのか。 それは、後に掛かるコストが大きく変わってくるからである。

様々な設計

設計にも種類があるので、いくつか見ていく。

データ運用設計

コードには手を入れず、運用作業で投入するデータによってアプリケーションが変化していく作りは、一般的だろう。 その場合は、どうやって、どんなデータを入れるのかについて、慎重な設計が必要だ。 何を使って、どのような形式でデータを作るのか。

例えば、ゲームのパラメーター設定など、頻繁にデータ投入と確認を繰り返す作業を考える。 データ作成がやりにくかったり、そこから確認できる状態にする作業が複雑だったりすると、時間が掛かってしまう。 データ作成者がエンジニアでない場合に、毎回エンジニアに何か作業を依頼する必要があるなどのパターンは、その最たる例だろう。 これを繰り返していくのだから、コストが大きく増えてしまう。

長期的なプロジェクトほど、このコストは効いてくるので、できるだけ簡潔・簡単にすむような、データ運用の設計をすべきだ。 使うツールも、いろいろと考えられるだろう。

この為に、しっかりとした運用基盤の構築や、自動化をしていきたい。 なお、この作業は、なるべく初期の段階で行えるのが理想的である。

ここで注意しておきたいのは、データ運用の為に、データのテーブル設計等を歪にするのは、極力避けるべきであるということだ。 データベースサイドとしてのデータ設計についての記述はしないが、アプリケーションの保守性に関わるので、これは蔑ろにしてはならない。

また、例えば、モバイルネイティブアプリの場合、データ種別の使い分けも必要だ。 主に、以下のようにデータが分かれる。

  • サーバーでの処理に使われたり、 サーバーから web API として返すデータ
  • クライアントが組み込んでいるデータ
  • クライアントがダウンロードして、ローカルに保持するデータ

それぞれの特徴に応じて、適切に使い分ける。

リポジトリ設計

管理するソースは、サーバーコード、クライアントコード、データ、グラフィックなど、多岐にわたる。 これを、作業がしやすく、役割が分かりやすい形を目指して、分けて管理する。

大きなソースを扱う場合は、リポジトリが肥大化し重くなり過ぎないように気をつけたい。 コードの管理には Git が使われることが多いが、そのような場合では、SVN や Git LFS も検討する。

設定設計

コードと設定は、上手くファイル等で切り分ける。 これにより、分かりやすくなるのは勿論のこと、例えばソースを外部に公開する場合に、秘密としたい key 情報等がまとまっていると、作業が楽になる。 また、多言語のサポートを行うのなら、整理された文言設定は大切だ。

ブランチ設計

同一のアプリケーションを、プラットフォーム展開したり、海外向けの対応を行うなどで、ブランチを分けることもあるだろう。 ここでも、楽なブランチ運用を探すことになるのだが、その前にまず、ブランチを分けずに済む方法を検討してみたい。 ブランチを切るとマージや追従のコストが掛かるので、先に前項のようなデータや設定分けを使って、なんとかならないかを考えるべきである。 ブランチ分けが良い場合は、運用しやすいブランチ戦略を立てることになる。

設計の基本方針

私は、「理想を考えてから、現実に落としこむ」という流れを心がけている。

例えば、データベースにおいては、負荷を考慮し、非正規化等を行う事が多々あるだろう。

しかし、最初から現実問題を考慮し過ぎると、必要以上に形を崩してしまう事になりがちである。 その為、設計時には、基本の綺麗でシンプルな形を考えてから、現実の条件に照らし合わせて、手を入れていく方法を取っている。

また、「なくせるはずの単純作業を繰り返す状況(人)を生み出したら負け」とも心に置き、設計を考えている。

設計によっても、情報共有は変わるのだ。

ドキュメント

何かについて調べる時、人に聴いたりコードを読んだりしなくても、概要が分かると効率的なので作られる。 何から何までに対応するのは難しいので、需要と効果が大きい箇所を狙って作成する。 時間が経つにつれて、実装とドキュメントが乖離をしてしまう事は良くあるので、メンテナンスされやすい状態や環境を整えたい。

障害

運用しているアプリケーションに問題が発生した時は、速やかに検知、共有し、対応に入る。 検知とその通知のフローや仕組みは、事前に十分確認しておく。 運用を続けるに連れて、通知される物の種類や数は増えがちだが、緊急の物と緊急でない物はしっかり分けて、緊急時の対応をスムーズにしたい。

また、障害対応後は、また同じことが起きないように、対策を講じる。

日報

日単位で、行動を記録し、振り返りを行う。 これにより、作業改善のサイクルを回したり、自身の成長に繋げることも出来る。 頭の中を文章として整理することで、その場では解決できなかったことへの糸口が見えてきたり、モヤモヤしたものがハッキリしたりもする。 時間が立ってから見返しても、なかなか興味深く、この記事を書くのにも役立ってる。

日報の為の方法はいろいろあるようだが、ゆるくやれるのがいいと思っている。

情報共有の範囲

組織における情報共有と言っても、スコープは様々だ。 個人間、プロジェクト内、社内、社外…。

情報が必要になる範囲を考え、適切な範囲へ向けた共有を心がけたい。 プロジェクトを越えて有用な情報が、小さな範囲のみに共有されていては、勿体ない。

ドリコムの社内 gem も、そういった取り組みの一環である。

RubyKaigi2014で発表した - mitaku.log

また、このドリコム Advent Calendar 内でも、社内にあった sharedoc が、社外へ公開されている。

スライド共有サービス sharedoc を作りました - onk.ninja

私としても、gem を作ったり、登壇の機会を頂いたりもした。

また、情報を得たい人が、どんな情報があるか、どうやったら知れるのかが分かる環境を整える。

情報共有の手段

情報共有の際には、様々な手段が使われる。

大まかに、テキストと口頭に分けられる。 それぞれに良さはあるが、口頭でのやり取りも、概要をテキストでも共有できると良いだろう。 テキストだと、非同期なので邪魔になりにくく、また透過性や検索性を上げることが出来る。

また、前述の通り、適切なスコープを意識する。 例えば、問題ないチャットルームについては、基本的に公開しておき、アクセスしやすくしておきたい。

状況や条件を考慮し、適切に共有手段を使い分けていきたい。

情報の取捨選択

情報が多いのは基本的に喜ぶべき状況だが、それを単に追いかけ続けるだけだと、時間を大きく消費しかねない。 情報にアクセス可能なのを前提に、必要な部分を上手くフィルタリングする。 ツールを使いこなそう。

情報共有の自動化

本記事でも数回出てきた「自動化」は、エンジニアが得意とすることであるので、他職種の作業にも注目して、導入を検討したい。 人間は、人間にしか出来ないことをやるべきだ。

情報共有環境の継続的な改善

組織の規模など、状況は刻々と変化する。 慣れて思考停止せずに、環境の継続的な改善を心がける。

まとめ

組織における、エンジニアの情報共有について書いた。 レビューや設計についての深掘りは、別記事としたほうが見やすかったのかもしれないが、関連して書きたかった事柄であったので盛り込んだ。

私自身も、まだまだ情報共有力が弱いので、高めて行きたいと思う。

情報共有は、誰しもが行い、そして苦労をしやすいことだろう。 様々な考え方や取り組みがあるだろうから、その知見の情報を収集し、改善に活かしたいものである。

「情報は発信するところに集まる」という言葉もあるので、積極的に、良い情報共有を行おう。


ドリコム Advent Calendar 2015 その2」、明日9日目は、massy22 さんによる dotfilesを管理しよう - Qiita だ。