オフショア開発（マインドセットやツールなど）

# オフショア開発は難しいのか
最近はいわゆるオフショア開発をしています。私は英語がそこそこ話せるため、ブリッジエンジニアみたいな役割をこなしつつ、チームリードや顧客調整的な役割も実施しています。

オフショア開発といえば、何よりコミュニケーション、さらに言えば正しい仕様の共有ではないでしょうか。そこで今回は私がチームで取り入れていた工夫？のようなものを挙げてみたいと思います。


# 前提
## 利用していたツール
- Microsoft Teams
- Azure DevOps（Boards, Repos, Pipelines）
- OneNote
- Visual Studio
- Android Studio

## 体制
- オンショア ４名
- オフショア ８名
- アジャイル開発でスクラムを採用

# 基本的なマインドセット
まず心がけること等をいくつか挙げてみます。

- 名前を覚える
できればFirst Name, Last Name両方。というか、Azure DevOpsで誰かをメンションするには @ファーストネームとしないと表示されないため、否が応でも覚えざる負えなくなります。
　
- さんづけする
Johnさんというように、海外の方にもさんづけするのを私はお薦めします。英語で口頭でしゃべるときも私はさん付けするように心がけています。スクラムガイドの中に「尊敬」が一つの柱であるように、雰囲気醸成のためにも日本チームとできるだけ分け隔てなく接するのが肝要だと感じています。

https://www.nri.com/jp/knowledge/glossary/lst/sa/scrum#:~:text=%E5%B0%8A%E6%95%AC%E3%81%A8%E3%81%AF%E3%80%81%E3%80%8C%E3%82%B9%E3%82%AF%E3%83%A9%E3%83%A0%E3%83%81%E3%83%BC%E3%83%A0,%E3%81%AB%E5%B0%8A%E6%95%AC%E3%81%95%E3%82%8C%E3%82%8B%E3%80%8D%E3%81%93%E3%81%A8%E3%80%82

## コミュニケーションテクニック
- Good Cop, Bad Copをしてみる
直接オフショアメンバーと話すのは私の役割でしたが、私の上にマネージャがいて、朝会には基本的に出席してもらっていました。そこではマネージャがセキュリティ周りや進捗報告等締めるべきところは（場合によってはかなりきつく）締めてもらいました。
勘違いしてほしくないのは、オフショアメンバーだから心がけや能力が低いということではありません。ただ、プロジェクトの初期はプロジェクトルールの定着時期であり、ミスが出てきます。そこで大事なことは厳しめに言うことで緊張感をもって仕事ができたと思います。（特に最初はDevOpsの更新漏れが頻発しました。）

  その分私はマネージャがいない場での仕様の説明等は可能な限り時間をとって、丁寧に説明しました（したつもりです）。

https://ja.wikipedia.org/wiki/%E8%89%AF%E3%81%84%E8%AD%A6%E5%AE%98%E3%83%BB%E6%82%AA%E3%81%84%E8%AD%A6%E5%AE%98

- 誤解のないオープンなコミュニケーションを心がける
    - ゆっくりした英語でしゃべる
発音なんかどうでもいいです。伝わるのが大事。短い文章をステップバイステップで話します。無理に流暢にしゃべるより、東南アジアの人相手だとカタカナ英語のほうが伝わる気がします。
　　
    - 翻訳ツールを導入する
DeepL等の有料版を使いました。専門のブリッジエンジニアを雇うのに比べれば安いです。
    　
    - どんなMTGでも事前になるべく全て文章や図で起こしておく
MTGで心がけるべきことは以下３点です。

        ①事前のメモ準備
        ②MTG中のやりとりのメモ追記
        ③MTGで出たToDoのTask化

        最悪それを渡せばわかる位までメモ（OneNote、パワポ何でも構いません）に落とし込んでおく。作業概要、具体的な作業の順番（環境構築からリリースまで）、作業の意味や背景、デザイン、主な仕様、参考リンク、締め切り等伝えるべきことはテンプレート化することをお勧めします。MTG中に受けた質問は全て文字に起こして回答を追記します。
せっかくAgileなのに資料を作るのかと思うかもしれませんが、Taskが適切に最高８時間程度で区切られていれば、慣れれば３０分ー１時間くらいの負担で済むように感じます。できればMTGの前に読んでおいて、と投げられればベスト。
　　
    - MTGの結果ToDoが出てきたら必ずタスク化する
    Azure DevOpsを使うなら、タスク化されていない仕事は存在しません。極端かもしれませんがそれくらいの意気込みが必要です。MTG中に出てきたタスクはMTG中にアイテムを作り管理します。
　
    - 会議で頻繁に"Any question so far?"としつこいくらいに聞いてみる
    私はおそらく５分に一回は繰り返していたと思います。これによって、一方的なプレゼンではなく自分から質問してもいいんだ、という認識を持ってもらいます。
　
    - 朝会か夕会で毎日進捗を確認する
５分でもいいので開発者の画面を共有してもらい、実際のコードや画面を見て確認するのがお勧めです。また、併せて締め切りに間に合いそうか毎日確認しましました。
　  
- オフショア側でリードやレビュー体制を構築する
オフショアチームが自走できるように体制を構築するのはこちらの役割です。可能であれば契約時からオフショア側のリードやレビュワーはAさん、Bさんお願い、と明確にしておくとよかったです。
特に作業スケジュールの調整等はこちらから直接プログラマに迫るのではなく、リードを通じて調整してみると「難しいけど頑張ります、気になる点は●●ですが、何かあれば報告します」という感じに日本風コミュニケーションになったりします。（リードの人が有能だったという説はある。）

# ツールの設定
## Azure DevOps
とはいっても、オフショアだから特別な設定をしたわけではありません。
昔書いたこちらの設定がベースとなります。

https://qiita.com/smr1/items/a915acbebd7f98ed580c

Azure DevOpsはそれほどメジャーなツールではないため、ツールの使い方をまず説明する必要があります。

### Iterationの初めに実施
- Capacityを設定してもらう。各自の休日、オフショアの国の祝日を入れてもらいます。基本的に開発者はオンショアと同じように１日７時間、リードは場合によっては０です。
　　
- また、オンショア側の重要なポイントとして、オフショアとの会議や仕様説明用の資料の作成の工数が増えるため、その分タスクを事前に追加しておきます。オフショアとやりとりして、でも開発もして、というやり方だと負荷が無視できないものになります。

### タスクを振るとき
- 基本的にオンショアメンバーがBacklogの作成からタスク作成までを実施しました。タスクもしくはBacklogの中にオフショアメンバーに実施してもらいたいことを書きます。その時に一度オンショアでも軽く見積もります。
　　
- そのうえで、オフショアの作業がコーディング、UTだったら、①コーディングとUTの時間を実際のオフショアの開発者に再度見積もってもらい、②タスクを分割して、③Original EstimateとRemainingを入力してらいます。
スクラムでは見積もりは開発チームのものです。仕様を理解し、手順を考え、作業と報告の責任を持ってもらいます。場合によってはオンショアチームと認識のすり合わせを行います。

### 毎日の作業
- Taskを振ったら、Activeにしてもらい毎日Remaining WorkとCompleted Workを更新してもらいます。
　　
- 朝会でBoardを確認していき、矛盾点や昨日とステータスが更新されていないもの等があったら必ずオフショアのリードに対してつっこみます。管理者がツールで現在の開発状況を把握できなくなったらプロジェクトは破綻します。

    特にバーンダウンチャートやWorkDetailで問題がないか確認するのがお勧めです。また、Original EstimateとRemaining Work、Completed Workが大きくずれている場合は要注意です。

https://learn.microsoft.com/ja-jp/azure/devops/report/dashboards/configure-sprint-burndown?view=azure-devops&tabs=remaining-work%2Cmay#the-in-context-burndown-trend-report

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654538/f826b66f-1506-4f8d-9fc4-7615baa7b59c.png)

https://learn.microsoft.com/ja-jp/azure/devops/boards/sprints/adjust-work?view=azure-devops#balance-work-across-the-team

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654538/f7fa5b78-758f-e612-de8c-5bdcb50ca495.png)

### コードレビュー
コードレビューは基本的にAzure DevOpsのPull Requestを使えると思います。
- TaskをIn Reviewのステータスに動かす。
　　
- レビュワーにはオンショア、オフショア両方のレビュワー入れてもらいます。GitのBranch Policyを設定することで、マージにはレビューを必須にして、レビューなしでdevelop branch等のlong-lived branchがマージや直接更新されてしまうことを防ぐことができます。
  
https://learn.microsoft.com/ja-jp/azure/devops/repos/git/branch-policies?view=azure-devops&tabs=browser#require-a-minimum-number-of-reviewers

- Pull Request Templateを使って、できるだけ最低限のチェックは自分でしてもらうようにしたらよいかもしれません。

https://learn.microsoft.com/ja-jp/azure/devops/repos/git/pull-request-templates?view=azure-devops#what-is-a-pull-request-template

- 可能であれば、SonarCloud等を導入して、できるだけレビューは機械化します。

https://qiita.com/smr1/items/7ba8cb5bc2b00824406c

https://azuredevopslabs.com/labs/vstsextend/sonarcloud/

正直あとはDIや単体テストが書ける構造になっていて、単体テストが書けていればそこまで個人的には気になりません。仕様通りに正しくできているかをちゃんとチェックするのはこちらの責任です。

　　
等々諸々書き出してみた後で振り返ってみたら要は日本チームと同じことしたらいいんじゃないか？という結論になってきましたが、せっかくなので残します。