経験の浅いエンジニアはチーム開発でどう頑張ればよかったのか
はじめに
チーム開発をしていくと、メンバーひとりが持つ実装力の高さによるアウトプット よりも コミュニケーションや協調の重要性を理解したメンバーで補完しながらのアウトプット の方が効果が高いです。実装力の高さとチームでの視点で思考する感覚は付随して習得できるものではないため、チーム開発でしか学べないスキルや立ち回り方があるでしょう。
この記事では、経験年数1年6ヶ月の Web まわりをさわっているエンジニアが、PrAha Challenge [1] で 戦術DDD やアジャイル開発手法を取り入れながら、チーム開発をした振り返りをしていこうと考えています。(かなり独断と偏見が入っています)
想定読者
- Web領域 で経験年数1~2年目のエンジニアの方
- PrAha Challenge に参加している方
要約
- 面識のないメンバー同士でチーム開発をする難しさについて
- チームの開発フローを形成する方法について
- チームの単位を分割するメリットについて
- 技術についての考え方を共有する方法と心構えについて
衝突した課題
チーム課題では、面識のないメンバー6~7人で開発することになりました。
「タックマンモデル」[2]の形成期 [3]と直面し、チーム開発の難しさを感じました。
チーム状況の特徴として
・チーム内には不安や緊張感がある
・お互いに遠慮があり、本音を隠している
・目標に向かってどう役割分担をして進めていくかが定まっていない
・リーダーを強く求め、リーダーからの指示を期待する(特に私)
私自身には経験の浅さから発生する受け身の姿勢があり、払拭しなければなりませんでした。
メンバーの特徴として
- 技術領域は UIデザイン、フロントエンド、バックエンドや SRE領域など多様
- 業務で使用している得意な技術と今回の開発で使用する技術は異なる
メンバーがどのような性格でどう作業を進めることが有効なのか各メンバーは分かっていない状況でチームの目標を定めなければなりませんでした。
チーム開発に進める期間は、おおよそ2ヶ月~3ヶ月で平日の夜と休日の時間で進めます。
課題の内容は PrAha を通じて学習した「ドメイン駆動設計」,「TDD(テスト駆動開発)」, 「データベース設計」の知識を活かして、アプリケーションの実装に挑戦します。
上記の状況でチーム全体でどのように具体的な行動をすればよかったのか、これから振り返ってみます。
余談
このチーム課題をやる上で重要なのは、事前に知識を習得して、知識の応用をできるようにしましょう。私自身はチーム内で最も課題が進んでいないメンバーだったため、大変でした。
学習効率の向上、知識の定着といったメリットがあるため、準備は怠らずにしましょう。
型をつくること
料理人は「なんとなく」でも料理を作れるようになっています。最初はレシピを読み解かなければ、作れなかった料理であっても、身体で覚えて、自然と作れるように熟達する過程があります。
その過程には「型をつくる」、そして「型を覚える」ことをするでしょう。 型は具体、言語化していくとチームのフローを形成してくれます。
思いつく方法として型を2つほど挙げます。
- 講義型 : あなた自身が責任を持って「進行役」を努めて、方向性や行動指針をドキュメントにまとめてチームに共有する方法
- 対話型 :「自分達の課題にどのように対処するか」を疑問点や課題についてチーム全員で対話する方法。
もし、講義型を選んだときのメリットは リソース効率でしょうか。初期フェーズにおいて、技術的なリーダーの存在による集権的な決定は、プロジェクトの推進力を上げてくれます。
ですが、 プロダクトコードの全体に責任をもつことを平日の夜や休日で担保するのは技術的なリーダーの負担が非常に高いでしょう。
それよりも、メンバー全員のポテンシャルを発揮する風土を醸成するために対話型が良いと考えています。
今回のチーム開発ではプロダクトの「成果」より参加者の「成長」が優先されるので、講義型より対話型で良いのではないでしょうか
具体的な型の例
対話型で進めていくとして、具体な型を2つほど挙げます。
定例がある場合なら、以下のような型で進める
- 進捗報告とアイディア出し
- プロジェクトを進行して気づいた点や浮かんだ疑問を共有。
- 発言の心理的ハードルを軽減するため、報告する手法を複数持つ(個人へのDM、テキストチャット、times、ハドル)
- 2~3人ほどのグループを作成して、意見共有 → 最後に各グループ合流して意見共有
- グループの分割は機能やユースケースごとで分割をすることを推奨する
- 発言の準備を整える
- 経験、学びや詰まったことを各個人が一覧にしている状態で参加する
- もしできていなかった場合は、発言する前に一人で考える時間を3分設ける
- アイデアに磨きをかける
- 並べられた疑問や意見について、各自、意見を述べて深ぼっていく。
- 意見交換で意識しなければならないのはメンバーへの理想の押し付けないこと。
- 理想を考えるのはチームが向かうべきゴールへ進むのに重要ですが、独善はチームのスループットを上げれないためです。
- 異なる意見が衝突するのは、形成期から混乱期に移行してるため、仕事に対する考え方・価値観・方針などを可能な限り話して共有すべきではないでしょうか
- 課題に対しての対話
- どういう現状なのか、その現状に至った過去の背景を知る、理想的な状態がどのようなものか 具体的にどのような課題があるのか
- 課題に対してどのような解決方法があるか、解決方法が正しいかどうかを判定するための定量的指標を定義できそうか
- 最後に
- 実施できる手立てと影響度を一覧化する
- 一覧化した中から、実効性が高く具体的な行動を実行する
ライブラリやツールを採用する場合なら、以下のような型で進める
- 事前準備として、提案者はライブラリはどんな根拠や具象に基づいて導入しようとしているのか言語化する
- 技術的な根拠とビジネス上の根拠があるのか
- 提案者は、提案したいライブラリと現在の使用できる機能との間に重複はあるのか?
- 具体例として、fetch api を使うか、axios を使うか
- 提案者は、ライブラリやツールの影響によって、各個人と合意形成を得て、どのように運用するかを対話する
- 局所的な課題を解決するための場合
- 他一人の開発者から同意を得る
- NextUI, react-select ぐらいのライブラリやツール(以下略)
- 他一人の開発者から同意を得る
- 汎用的な課題を解決するための場合
- 同じ分野の複数人の開発者から同意を得る
- react-testing-library, axios
- 同じ分野の複数人の開発者から同意を得る
- フレームワークを導入する場合(構造全体を構成する、影響度の大きいもの)
- チーム全員から同意を得る
- React, OpenAPI, GraphQL
- チーム全員から同意を得る
- 局所的な課題を解決するための場合
チームの構造を変える
6~7人で合意形成を図るのは至難の業です。あるメンバーは安定して時間を確保するのが難しく、あるメンバーは時間の都合が合わないのは、よくあることです。その場合は、チームの構造を再考してみましょう。
Amazon の CEO であるジェフ・ベゾスは2015年の株主への手紙の一文。(意訳)
But most decisions aren’t like that – they are changeable, reversible – they’re two-way doors. If you’ve made a suboptimal Type 2 decision, you don’t have to live with the consequences for that long. You can reopen the door and go back through. Type 2 decisions can and should be made quickly by high judgment individuals or small groups.
2015年年の株主への手紙
「決定は変更可能で、可逆的です。誤った判断をした場合でもやり直したらよいのです。そのような決定をしたい場合は、判断力が高い個人か少人数のグループであるべきです。」
これは、不確実性の高い初期フェーズや決定することに慣れていないチームであれば、小さく分断した方が良い理由の一つです。「6~7」人でチーム開発を行うのではなく、「3と4」人でチームを分割して開発するのが良いのではないでしょうか。
より局所的な意思決定(変数の命名、モデリング、詳細なディレクトリ構成)や適切でアドホックな意思決定(ユビキタス言語の策定、静的解析の各ルール)を問題に詳しいチームメンバーに判断を委ねることができます。また、決定が間違ったとしても、後から修正するのも容易になります。
関心ごと(フロントエンド、バックエンド)でチームを分割せず、ユースケースや機能ごとで分割するのが良いでしょう。
実装するときは小さく試しやすい場所を探す
設計手法は 戦術DDD に沿っています。実装の詳細を隠蔽したり、契約 [4]に従っているのです。
具体的にはクライアント、ドメイン層、永続層間での契約を前もって定義しておき、各層は API の契約を変更しない限り、他層に影響を与えることなく、実装の詳細を変更できるようにしていました。
ですが、私はこのような設計に疎く、品質の高い成果物を生み出すことができなかったのです。
それに対して、改善策を出すとしたら、試しやすい場所で、モブプログラミング[5]を行うことをするでしょう
もし、ひとりで実装をして初期設計が誤っていたらどうなるでしょうか。ドメイン間で過度に結合された統合を分解したり、API を完全に書き換えるのは大きな負担になります。
小さい機能(タグの追加、編集機能)で実装してみたり、ホワイトボードで思考を繰り返してみたり、提案された設計を図に落とすのが良いでしょう。
そのような成果をレビューで各メンバーの創発の効果や結果(コード、図式)を共有し合い、意見交換しても良いです。
また、モブプログラミングで過程や技術も共有するのを推奨します。過程を共有しているので、参加者全員が対象のコードの所有権を持っているので、あとから変更しやすいです。
ここで意識しなければならないことは、コントロールフリーク(仕切り屋)になるのではなく、決定に対して各メンバーに意見を求め続けることです。
コントロールフリークは各メンバーからプログラミングの技術、設計を奪う振る舞いになります。それは各メンバーのフラストレーションやコントロールフリークに対して敬意の欠如が発生するかもしれません。
ベストプラクティスを理解している場合でも「とりあえず、〜しておけ!」と自分の意見を押し付けるのではなくて、「〜は何を参考にしていますか?」「〜を変えたら何が起こるだろう?」と質問することで、一緒に課題を考える協調的な会話が生まれ、チームのスループットを向上してくれるかもしれません。
なので、「How」より信頼ある情報源の「What」を示しながら「Why」を伝えていくのが良いです。技術の熟練度が高いメンバーの場合は「How」に関して、放任するのが良いとも考えています。私のような技術の熟練度が低い場合は、細かく「How」に関して指摘するのがいいですし、私は嬉しいです。
さいごに
チーム開発を行っていた期間はおおよそ3ヶ月ほどでしょうか。沢山の学びがあって、深く考えさせる貴重な体験になりました。今回の課題で、卒業される方が複数人いらしゃるようで、すごいです。私も同時期に参加したはずなのですが、進捗が倍近く遅れてるんですよね...
私自身は課題の理解がまだ浅いため、マイペースに深堀して課題の進捗を出していこうと思いました。チームの力になれるよう、実力を上げるため精一杯頑張ります。
もしも、記事の内容に誤りがある場合はご指摘ください。修正させて頂きます。
Discussion