@eaglesakura です。
皆さん、進捗どうですか?
お仕事の規模が大きくなれば、参加人数が増えていくでしょう。
参加人数が増えれば、様々な宗教観の人がプロジェクトに参加するでしょう。
お一人様プロジェクトを中心にやっていた人もいれば、大規模案件のソルジャーとしてキャリアを積み上げてきた人もいます。彼らのスキルレベルもまちまちです。
私が参加している(そしてプログラマーに対して強い権限のある立場である)プロジェクトでは、次のようなルールをベースに適用しています。
これはなるべくプログラマーの負担をかけずに管理側(プロジェクトマネージャー=PM)が開発管理を行える(進捗がブラックボックス化しない)ことを目的とした開発ルールです。
前提ルール
- ソースコード管理はgit/githubを利用する
- 1コミット(1ブランチ)に対して、複数Issueを処理しない
githubはリポジトリ管理(作成やメンバー削除、権限設定)がしやすいので、私が所属するトップゲート社でのデファクトスタンダードとなっています。
1コミットに対して複数Issue処理を行うと、コードレビューの際にレビュアーが観るべき観点が増えてしまうので、負担を軽減するため(レビュアー側の頭の整理を簡単にするため)に可能な限りコミット単位で整理しましょう。
最低限守るIssue運用ルール
Issue Tracker System選定ルール
ここでいうIssueはgithub上のIssueでも良いですし、Redmineのチケットでも良いです。
大抵のイシュートラッカーシステムは一長一短で、githubには明確な期限設定や親子階層・ガントチャート可視化機能等がありませんし、RedmineはPull-Request等との連携が弱いです。
Issue管理はプログラマーとPMの双方が行いますが、ツールに対する視点が異なる場合があります。
例として、トップゲート社ではgithubとRedmineが使われるため、2つを簡単に比較します。
githubはプログラマーにとって便利ですが、期限設定やガントチャート視覚化が標準で行えないため、お客さんと直接スケジュール折衝を行うPMにはウケが悪いです。
Redmineは上記の問題を解決してくれますが、Pull-Request等のgithub上のフローとは統合されていないため、開発者のウケが悪いです。
私自身は基本的に「PMが使いたいツールを採用する」というふうにしています。
全体スケジュール管理はPMが行います。場合によってはリスケの説得を行うのもPMです。issueはプロジェクト管理上「残作業量」を明確に示すものですので、PMが管理や打ち合わせでの提示をしやすいツールを選んだほうが最終的には利益になるでしょう。
issue可視化ルール
画面ごとにIssue化する
前述したように、Issueは「残作業」を明確に示すものです。ITSに慣れていない場合、「何をIssueにしたら良いか」がわからないという状態になりやすいです。
アプリ開発の場合、ほぼ間違いなく「画面を表示する」というタスクが存在します。たとえばTwitterアプリで言えば「ログイン画面」「タイムライン表示画面」「ツイート画面」等ですね。
プロジェクトが本格稼働すれば、大まかに画面数が固まっているかと思いますので、まずはすべての画面をIssueに書き出します。
画面ごとの「UI」「機能」をIssue化する
画面ごとには、大まかに次のような作業が必要になるでしょう。その際、なるべく「機能」と「UI」(Android Architecture Componentsで言うところのViewModel, Repository程度の粒度)で分けておきます。
チケットレベルでUIと機能で分けておくことで、コーディング中でも「可能な限りそれらは分離して設計する」という点に意識が向くでしょう。
もちろん、1コミットに対して複数issueを処理しないという意識を持つことが前提です。
- レイアウトファイル作成
- 入力処理作成(ID, パスワード入力等)
- データ処理作成(サーバーと通信する, DBに保存する等)
2issue/day ルール
issueを洗い出したら、後述するブランチルールに従って実際に作業を開始します。
実際に作業していると、「作業量の少ないissue」と「かなり大きなissue」があることに気づくでしょう。前者は全く問題ありませんが、後者は問題となります。
issueに全く動きが無ければPMは「作業が進んでいるかわからない」となりますし、開発者も(仮に数日間もissueをcloseできなければ)大きな焦りとなるでしょう。これは互いに不幸な状態です。
概ね、開発者に「途中経過をissueに書いてくれ」といってもだいたい忘れます。
そこで、issue粒度の最大値を「1日に2issue以上closeできる程度」としておきます。それを超えるほどの時間がかかるissueは洗い出しが不十分ですので、更に細かいissueに分割して上げましょう。
例えば
- ログイン機能を実装する
というissueが0.5日くらいで終わらないと判断した場合、次のように分割してあげます。
- ログイン機能 / サーバーとの通信を行う
- ログイン機能 / 認証トークン保存用DB設計を行う
- ログイン機能 / 認証トークンをDBに保存する
こうすることで、PMは高い精度のissue経過を知ることが出来ますし、開発者も「ずっと同じissueをcloseできない」ようなストレスを軽減出来ます。
また、それでも1~2日issueをcloseできない状態が続くようなら、それはいわゆる「ドハマリ」もしくは「自分のやるべきことがわからない」の状態であると客観的に判断が行なえます。それはPMがissue tracker上で簡単に検出可能ですので、開発者に確認を行ったり、適切な人物への橋渡しを行うことが出来ます。
最低限守るgit運用ルール
基本的にgitの運用は以前書いた 小規模開発のgit-flowの導入を楽にするブランチルールと拡張スクリプト配布 に従います。
特に開発ブランチは必ず feature/id/${issue番号}
をベースにします。
ブランチ名 feature/id/${issue番号}/master ルール
ブランチの命名は、開発者の趣味が出ます。概ね、「そのブランチが何をやっているかわかること」が前提となりますが、無数の命名規則のブランチが乱立することになります。
また、ブランチ名の命名が面倒になると、1ブランチに対して複数のissue作業をやりがちです。
この命名規則では、機械的に「必ずissue番号をブランチ名に含める」としています。ブランチ名から作業内容は直接的に不明ですが、issue番号に紐付いているため「どのような作業をしているか」を辿るのは簡単です。
また、命名規則上「作業が必ずissue化されている」ほうがプロジェクト全体での恩恵が大きくなります。
git commit "refs #${issue番号}" ルール
この規則は、github/Redmineの機能として「issueとコミットを紐付ける」ために使用します。
issue詳細を開けば「どのような作業をしたか」が明確になるので、コミット & pushをするだけで(closeしていない場合でも)作業進捗を知ることが出来ます。
develop Pull-Requestルール
feature/id/${issue番号}/master
での作業はPull-Requestを通してdevelopにマージします。
その際、可能であればレビュアーによるレビューを通します。
これはよく行われる作業フローと変わりません。マージ後はブランチを削除して構いません。
命名規則の都合上、開発者数×2のブランチが営業日ごとに増えます。githubのUIはマージ済ブランチとそうでないブランチを分けて表示することが出来ませんので、さっさと消したほうが良いでしょう。
私の場合は、適当なイテレーション(客先チェック等)ごとに削除しています。
最低限守るコードレビュールール
コードレビューは、多人数での開発で品質を保つ際に必須です。
ただし、開発者個々人の趣味や思想・宗教によって観点が様々で、例えばプロジェクトの開発側責任者(開発リーダー、メインプログラマー等と呼ばれる人間)レベルの完璧な品質を求めた場合、見かけの開発進捗は著しく悪くなります。
「自社案件で長期間継続的リリースを目的としたプロジェクト」と「1~2ヶ月の短いスパンでリリースが必要で、アップデートがほぼありえない案件」では前提も目的も異なります。
前者は長期的視点で考えて品質目標を高めに設定し、後者はリリースが最優先ですので「コード品質を妥協し、代わりにテスト期間を長くとる」等のバランスが必要です。
基本的に開発スタート当初は個々人のスキル感が不明である場合があるため、品質設定を高めにします。その状態で進捗が思わしくない場合、開発リーダーとPMはプロジェクトの「目的」と「妥協点」を早いうちに設定し、レビュー観点と品質を明確化しておきます。
例えばある案件では品質と作業品質のバランスとして、次のような観点で見ています。
- レビュアーが見て理解できるコードか
- 大前提です
- ここでいう「理解できる」とは、自分の思想を100%反映している等の宗教的な意味ではなく、「どんな処理をしているかコメントやコードを見て追うことが可能である」ということです。
- 宗教観の反映は不和や戦争を呼びますが、上記は単純に「コードを追えない」という点でNGを出せます。
- 将来的に、コードを書いていない人間がメンテした時、「何をやっているか」を開発リーダーが最低限説明可能な状態とする(コーディングした人間が現場を離れているという場合のリスク回避も見込む)ためです
- 将来にテストコードを追加できる設計であるか
- 理想的には、テストコードは書かせるべきです。ですが、「十分な数のテストコードを書くこと」や、そもそも「テストコードを記述する」というのもスキルの一つであり、それを満たせない開発者もいます。
- それを指摘することもリジェクトすることも簡単ですが、あくまで最終目的は「現時点のアサインで可能な限り最大の出力を発揮する」ことです。
- 妥協点として、「少なくともあとからテストを追加できる設計」ことを前提に通過させます。
- プラットフォームのバッドプラクティスを辿っていないか
- Androidで言えば、「Activityのパラメータをstatic変数で渡す」等のバッドプラクティスは潰しておきます
- これは将来の改善・修正の可能性・即応性を著しく下げるためです。
- 導入したライブラリに責任を取れるか
- 基本的にライブラリの導入は必要に応じて自由にやって良いです
- ただし、問題が発生したとき「自分で対処可能であるか」は確認しておきます
- 例として、データベースにSQLiteとRealmどちらを導入しても構いませんが、提案者は「それが原因でドハマリしても自力で解決すること」を求めます
- 私の宗教上使わないライブラリも数多いですが、それがDeprecatedになっておらず、最終的な外見上の仕様として問題なく動作していれば許します
- 例えば、いまどきApache Http Clientを使おうとしたら明確に反対します
最後に
自分が開発者としてアサインされているか、レビュアー(アーキテクト)としてアサインされているかで状況が変わります。すべてを常にこの通り運用するわけではありません。
ですが、ベースの方針としてはこのようにすることで、管理と開発のバランス取りをはかっています。
また、自分以外が開発リーダーとしてアサインされているならその人間の方針に従います。
開発ルールも一つの宗教であり、きっと私以外の開発リーダーにはその人物なりの宗教観があります。開発リーダーの思惑を外れた勝手なフローは、開発リーダー(責任者)にとって納得できない責任の取らされ方になります。
船頭が多い開発は、明後日の方向へ全力疾走することになってしまいますし、最終的に責任を取る(頭を下げる)人間の方針に従うのが、お互いのためになるでしょう。
大切なのは、PM/開発リーダー/開発者のバランス感を持った「歩み寄り」ですね。