エンジニアとマネージャーは似ているのかもしれない～設計・開発で考えていること～

私はアプリ開発をしているエンジニアですが、コードを書くときクラスを「人」として考えています。
xxActivityはxxを表示する人、ooUtilsはooをする人など。
周りのエンジニアやPMにこのことを話したら「分かる」という賛同や「そう考えて設計してるんですね」という感想「そういう考えがあるのか」というフィードバックをもらったので、文章に起こしてみようと思います。

先に断っておくと、私は多種の開発に関わったことも、マネージャーとしての知識も多くはありません。
的を絞って話すため、これのこと考えられてないじゃん！ということもあるかもしれませんが、優しい目で見ていただけると幸いです。

# Introduction～自社ビル建ててと言われたら～
Aさんという名前のあなたはとあるIT企業で働く普通のエンジニアです。
ある日社長からこう言われます。
社長「Aさん、うちで新しく建築事業部を立ち上げるんだけど、明日からそこの責任者になってくれない？
まずはお試しでうちの新しい自社ビルを建ててほしい。
この資料のようなビルが良くて、期間は長くて2年ぐらい。」
あなた「・・・」

どうでしょう。
あなたは普通のエンジニア。ここはIT企業。
建築事業部の責任者？自社ビルを建てる？「無理・・・」ですよね。
※あなたが建築や法律を修めている人なら「はい」と答えるかもしれませんが。笑

ではこう言われたらどうでしょう。
社長「Aさん、うちで新しく建築事業を立ち上げるんだけど、明日からそこの責任者になってくれない？
まずはお試しでうちの新しい自社ビルを建ててほしい。
この資料のようなビルが良くて、期間は長くて2年ぐらい。
**`予算は無限で、欲しい人材がいればいくらでも補充するから。`**」

予算無限で人材も集められる、これなら詳しい人・その道のプロたちをチームに入れれば進められそうです。
例えばこんな人たち。

- 不動産に詳しい人
- 建築に詳しい人
- 法律に詳しい人

実際に建てるとなれば、他にも集める必要がありそうです。

- 設計・建設作業をする人
- 必要な機材・材料

一見無理に見える依頼も、予算とリソースが無限であれば何でもできそうです。

# Engineer～エンジニアに当てはめるとあなたは神～
最初にクラスは「人」という話をしました。
クラスが持つメソッドは「その人ができること」とすることが多いです。
そしてエンジニアであるあなたはクラスやメソッドを自由に作れます。
ということは、人材は自分で好きなように雇えて、その人の能力も思いのままということになります。
**`「予算は無限で、欲しい人材がいればいくらでも補充するから」`**という状態ですね。
おや、ちょっと楽しくなってきました。

エンジニアはなぜコードを書くのか？というと「機能を開発するため」です。
予算は無限～の例に当てはめてみると、

**`ある機能を開発する`**という目的を達成するために
その機能に必要な**`人`**も、その人が持っている**`能力`**も
好きに決めて集めて良い

ということになります。

あなたは目的達成のために部下に誰を持ってきてもいいし、何人持って来てもいい。
リソースが無限なチームのリーダー、楽しくないですか？
なんならコードという面ではあなたはクラスを作ることができるわけです。
クラス=人、それも欲しい力を持った人を生み出すことができる。
神のような存在ですね！

# Example～実際にやってみる～
では、実際のITエンジニアの開発で見てみましょう。
例えば、運用している自社スマホアプリに記事を表示する新機能を任されるとしましょう。(記事は自社APIで取得できる)

最初の例に当てはめると、
社長の依頼(=目的)：記事を表示する機能の開発
責任者(=作る人)：あなた
ですね。

さて、プログラム設計をしてみましょう。
クラス=人として、この「記事を表示する機能」に必要な人材を上げてみましょう。
大まかに言うと下記の2人になると思います。

- 記事を表示する人
- 記事を取得する人

こうすると、あなたの仕事はこの2人雇って、働いてもらえば依頼達成です。
しかしあなたは実際にはエンジニアなので、その部下のやることも細かく考えなければなりません。
各々の仕事内容としてはこうなるでしょう。

- 記事を表示する人(Bさん)
 - `記事を取得する人`に、必要な情報を渡して記事を取ってきてもらって表示する
- 記事を取得する人(Cさん)
 - 必要な情報を受け取り、自社APIを使って記事を取得し、`記事を表示する人`に渡す

仕事風景を想像するとこんな感じ。
Bさん「Cさん、この記事取ってきて」
Cさん「はい、取ってきます」
～Cさんが記事を取ってくる～
Cさん「Bさん、取ってきたからあげます」
Bさん「ありがとう。じゃあ表示します」

人=クラス、その人の仕事=メソッドなので、もうコーディングできそうですね。

では、仕様として下記が加わっているとします。

- 記事にはいいね機能を付ける
- 記事にはいいね数が表示される
- 記事にはレビューが表示される
- 記事はTwitterへの共有ができる
- 記事はFacebookへの共有ができる

先程の2人の人材・能力では足りないので、必要なことを考えてみます。

- 記事を表示する人
 - 記事を取得する人に、必要な情報を渡して記事を取ってきてもらう
 - Twitterの共有ボタンを表示する
 - Facebookの共有ボタンを表示する
- 記事をAPIで取得する人
 - 必要な情報を受け取り、自社APIを使って記事といいね数、レビューを取得し、記事を表示する人に渡す
- いいねを送信する人
 - 自社APIを使って記事へのいいねを送信する
- Twitterへの共有をする人
 - 記事を受け取りTwitterへ共有する
- Facebookへの共有をする人
 - 記事を受け取りFacebookへ共有する

人も能力も増えました。
さて責任者として全体を俯瞰すると、同じようなことをしている人がいます。
共有する人ですね。
共有先が違うだけで、「共有」すること自体には変わりありません。
無駄に人数がいても管理が大変になるので、減らせるところは減らしましょう。
(なぜ管理を考えるのかは先にある[Reality](#reality現実を見てみる)以降で話します)

- 記事を共有する人
 - TwitterまたはFacebookの依頼を受け取り、それぞれへの共有を行う

これで、あとはそれぞれ実装していけば問題なく目的を達成できそうです。

#Details～細かく見てみると～

メイン人材の仕事を細かく見ると下のようなこともする必要がありますよね。

- 記事を表示する人
 -  スマホに文字を表示する
 -  スクロール動作を検知して文字をスクロールする
- 記事をAPIで取得する人
 - HTTP通信を行う
 - 通信がエラーになったらエラーを伝える

しかし、普段私達はこういうことは考えていません。
それはなぜかというと「OSやライブラリがやってくれるから」です。
ではここにおいて「クラス=人」という考え方ではどうなるでしょう？
私は「外部委託」という風に考えています。

Androidでは、TextViewにテキストをセットすると表示してくれますし、ScrollViewにTextViewをたくさん入れると、スクロールをやってくれます。
「やってくれる人」が既にいるという状態はありがたいものですね。

- TextViewを使う→Googleに所属するTextViewさんに外部委託する
- OkHttp(通信ライブラリ)を使う→Squareに所属するOkHttpさんに外部委託する

もちろん外部委託するときには、そこが信頼できるのか見極める必要があります。
そういった意味でサードパーティ製のライブラリを入れる際は評判やスター数を見たりするわけですね。

# Reality～現実を見てみる～
今までは「新しい機能を作る」という話をしてきました。
しかし、実際はどうでしょう？
新規機能開発ばかりではないですよね？
現在公開しているものの不具合修正だったり、既存機能の変更だったり。
自分だけではない他人が作ったコードを見ることは非常に多いです。
そういったものを今回の「クラス=人」で考えると、「他のリーダーが作ったチーム」の人たちと働くことになるわけです。
そういう人たちと働くためには、まずは自分の目的達成をするために「誰と関わるのか」「どんな人がいて」「どんなことをしているのか」を把握する必要があります。
新しくマネージャーとしてチームに入った場合と同じですね。
チームが最高にできる人だけで構成されていればいいですが、現実ではそうは行きません。
チームには色々な人がいます。

- 1年目の新人
- ある道でベテランだけど今やっていることは初めて間もない人
- 何でもやっていて仕事が多すぎる人
- 正直あまり使えない人

クラスの世界も同じです。

- 同じことをやっている複数のUtilクラス
- 使われていないクラス
- ロジックも表示も全部やり、肥大化した画面クラス
- 共通処理以外もやっているBaseクラス

またクラスの世界では命名で困ることもあります。
命名が実際の内容と異なると、あなたはその人のことをすぐに把握できず想定外のことが起こります。

- クラス名があっていない
 - 「あなたは何する人なの？」と聞いたときに違う答えが返ってくる
     - 「記事を表示する」という人が記事を表示しないでレビューだけ表示していたら困りますよね
- メソッド名があっていない
 - 「これお願い！」と依頼をしたときに想定外のことが起こる
     - getArticleみたいなメソッドを見て、「すぐ終わりそうだし、記事取ってきて！」と気軽にお願いすると中々結果が返って来ない
          - 中ではAPIで記事を取得してそれをキャッシュに保存してから返していた
          - 時間がかかることが分かる名前にするか、処理を分離するかした方が分かりやすそうです

こういう状態のものはコードとして読みづらく、何をしているのか・どう使うべきなのか、という理解に時間を要すと思います。
また理解が間違っていて期待した結果が出ない場合や、実は必要ない仕事をしている場合もあるかもしれません。(=不具合)
目的を早く達成することはもちろん大事ですが、今いる人たちのことを理解し、より良い状態にしていくことが後々のためになります。
そして、あなたが生み出す新人(新しいクラス)や今いる人への新しい指示(既存クラス改修)は、同じ過ちを繰り返さないように気をつけなければなりません。
この辺がマネジメントだと思っています。

# God's mission～神だけどマネジメントしなければならない～
あなたは人を生み出せる「神」という話をしましたが、あくまでやることは目的達成のためのチームリーダーです。
生み出した人々はそこで仕事を続けますし、あなたが新しい仕事をその人達とすることもあるでしょう。
はたまたチームリーダーが変わって、あなたではない別の人が、あなたが作った人々と仕事をすることもあるでしょう。
それは前章で話した通り、あなた自身が他の(リーダーが作った)人と仕事することも多いので容易に想像できると思います。

こう考えたときに大事になるのが、マネジメントです。
あなたは気軽に人を生み出せる「神」ですが、生み出す人はなるべく優秀である必要がありますし、小さい仕事に対して人数を増やしすぎると、誰が何をやっているのか分からなくなったり、実は何もしていない人が出てきたり、仕事の引き継ぎが大変になったります。
優秀な人を、最適な人数作り出せば、のちのあなたのためにも、のちのチームリーダーのためにもなります。
あなたは、`目標やチーム全体を把握`しつつ、`チームメンバー(クラス)に寄り添い`、最適な仕事を割り振り、人材を作り出さなくてはなりません。

## 目標を把握すること

- 作っているものは正しいか？
 - チームメンバーはあなたの指示通りにしか動いてくれません。あなたが間違っていると、チーム全体も間違うことになります。

## チーム全体を把握すること

 - 無理をしているメンバーはいないか？
  - 一つのクラスに処理が集中していないか？
      - 他のメンバーに割り振る？新しい人を作る？
 - 仕事をしていない人はいないか？
  - 要らなければ時には消す
 - チームメンバーの関係がぎくしゃくしていないか？
  - 場合によってはメンバー全員に集まってもらって話す(見つめ直す)。必要があれば変える。
  - 設計を変えてみたり、役割を再検討してみたり(リファクタリング)

## チームメンバーに寄り添うこと

 - その人の責任以外のことをさせていないか？
  - やりたいこと・やるべきことに集中できているか？
      - そもそも責任が明確になっていない場合は明確にする
  - その人の気持ちになって、やりたくないことをしてないか考える
      - 実は他の人がやった方がいいかも
 - 責任が大きくなっていないか？
  - 何かあったときにどこが原因なのか把握しづらくなる
  - 人を増やすべきかもしれない
 - 他の人とのやり取りやスムーズにできているか？
  - 引数の数・命名が適切か？
  - できれば親切か？
      - 文脈に合った命名や、単位を含めた引数名など、他者から依頼を受けやすければ尚良い
 - 自分だけでなく、他人も指示を出しやすいか？
  - 何をする人なのか、何ができる人なのか、クラスやメソッドの命名が適切か？

#Finally～終わりに～
クラス=人と考えることを始め、その流れで私が考えていることをまとめてみました。
プロジェクトやチームと同じで、開発も作ったら終わりではなく継続していくものです。
開発という世界で、より良いチームを作っていく。
こういうことからエンジニアは、**`リソースを無限に生み出せるチームのリーダー(=神)`**でありながら、**`よいチームを作るマネージャー`**であると思うのです。