tumo.jpのプログラム

それぞれが選んだStyle

プログラマにとって一番重要な能力は「想像力」である

はじめに

こんにちは。プログラマ歴10年の tumo.jp です。

先日、ふと「プログラマにとって一番重要な能力って何だろう?」と考える機会があったので、ここに私なりの考えを書いてみたいと思います。

プログラマに必要な能力ってなんだと思いますか?
論理的思考能力、プログラミング言語フレームワークの知識、数学的な素養、複雑なアルゴリズムの処理が書ける... etc
また「コミュニケーション能力が一番重要だ」なんていう人も結構いたりします。
当然答えは一つではないと思います。

結論

私は、プログラマにとって一番重要な能力は「想像力 = Imagination」だと思います。

ちなみに「創造力 = Creativity」ではありません。もちろん創造力があればそれはそれで素晴らしいことだとは思いますが、たぶんプログラマの本質ではないです。
また、ある人がクリエイティブかどうかは客観的に判断するのは難しいです。 プログラマに必要な能力というのは、ある程度客観的に「測定可能 = Measurable」なものでなければなりません。

では、プログラマにとっての「想像力」は、客観的に測定可能なのか?
以下の観点で、それぞれ具体的なケースを用いて説明してみたいと思います。

  1. プログラムの理解
  2. フレームワーク・ライブラリの理解
  3. 業務の理解
  4. ユーザビリティ
  5. 保守性・可読性
  6. 工数の見積り
  7. コミュニケーション

具体的なケースで説明

1. プログラムの理解

これは、自分の書いたプログラムがメモリ上でどのように展開されているか、を想像する能力です。
メモリの状態というのは目に見えないので、想像する力が必要になります。

例えばJavascriptでプリミティブ型で変数宣言した時と、オブジェクト型で変数宣言した時とでは、メモリの状態は全く違います。 JavaにおけるListとArrayの違いなんかもそうです。 マルチスレッド処理を書くときなども、自分の書いたコードの実際の動作を想像できるかどうかで、大きな差が出るでしょう。
二流は動けばいいやという感じで、特になにも考えず実装します。
優秀なプログラマはパフォーマンスや拡張性や可読性など、様々なことを加味して実装します。

また、こういった能力はトラブル・シューティングの際にも役立ちます。
優秀なプログラマはコードをじっくりと読んで当たりをつけ、短時間でトラブルの原因を特定します。 二流はdebugコンソールを出したり、データを変えて実行してみたり、時間をかけてあれこれ試して問題の切り分けをします。
ちなみに三流は問題の切り分けもできません。事件は迷宮入りです。

2. フレームワーク・ライブラリの理解

プログラムの理解と比較的似ているのですが、フレームワーク・ライブラリの理解においても、想像力で差が出ると考えています。

現代のプログラマは、既存のフレームワーク・ライブラリを一切使わずに実装することはまずありません。 速く、正確にプログラムを実装するためには、フレームワーク・ライブラリを素早く、そして深く理解し、使いこなすことが肝要です。

優秀なプログラマは、そのフレームワークが「なぜそうなっているのか?」を想像して理解します。
またそのライブラリが「自分だったらこういうAPIを用意してこんな風に作るのだが」と想像しながらドキュメントを読みます。
つまりフレームワーク・ライブラリの思想を理解しながら実装します。
二流は動けばええねん、という感じでワケもわからず実装します。

3. 業務の理解

想像力は、お客様の業務を理解する上でも役立ちます。
ほとんどのプログラマは、クライアントの業務を経験したことはありません。
例えば会計士が使うシステムを構築する場合、会計士が普段どんな風に仕事をしているのかを想像する必要があります。

もちろん、想像するだけでは限界があるので、適宜ヒアリングを行うことになります。
ただし、ここに罠があります。
というのも、お客様はたいてい、業務には詳しいけれどシステムには詳しくありません。
業務ヒアリングや要件定義を行う際に、お客様は業務の説明はできますが、システム化した後の業務を想像できるとは限らないのです。
俗にいう「お客様の本当に求めているものは、お客様自身もわかっていない」というやつです。

二流は「あの時お客様はこう言ったじゃん」と言って、ヘンテコシステムを構築します。
最悪なケースでは、システム構築後の方が仕事の効率が下がるなんてこともあります。結果、そのシステムは使われなくなりました、となります。
優秀なプログラマはお客様の業務を理解した上で、システム化後の世界を想像します。
当たり前のように使われるシステムを構築するというのは、案外難しいことだったりするのです。

4. ユーザビリティ

これはシンプルに、ユーザーがそのシステムを触った時にどう思うだろう? と想像する能力です。
割と単純な話ですね。

UI・UXというのは本当に奥が深い世界で、C向けのアプリケーションでは専門のデザイナーなどが存在します。
しかし、多くの場合(特に業務システムなどの場合)は、プログラマがUI・UXも担当します。
プログラマって大変ですね。

最近はリッチなUIフレームワークが増えてきて、簡単にカッコイイ(見栄えのいい)UIを構築することができます。
しかし、業務システムの場合は特に、一見リッチなデザインが逆に使いづらいなんてこともあります。
ユーザビリティの本質を見抜き、真に使いやすいシステムを構築するには、思っている以上にレベルの高い想像力が必要とされるのです。

5. 保守性・可読性

これは、自分以外の人間が読んだ時どう思うだろう? と想像する能力です。
本当に優秀なプログラマの書いたコードは、処理が読みやすく、影響範囲がわかりやすく、仕様も理解しやすく書かれています。
結果、保守フェーズで機能追加などが発生しても、不具合なく実装することが可能です。

三流はソースコードを大量にコピペし、ビジネスロジックをとっ散らかし、ソースコードを蹂躙(じゅうりん)します。
二流は特に指示がなければ逐一順列に処理を記述し、決まりがあれば決められた通りの作法で実装します。
一流は必要十分な抽象化を行い、必要十分なパフォーマンス調整を実施し、開発チーム全体の実装方針まで立てます。

ちなみに、この観点にも実はちょっとした罠があります。
それは「一見一流に見えるエセ一流プログラマのコードは保守しづらい」というやつです。
エセ一流は不要な2ミリ秒の速度を優先し、謎のコーディング論を引っ張り出し、独自の思想で他人には理解しがたいコードを書くことがあります。
こういうエセ一流には注意しましょう。

サッカーで例えるなら、真に一流のMF(ミッドフィールダー)は味方の能力に合わせてパスを出す、ということです。
イニエスタは日本のクラブに移籍しても、一流の活躍をしています。
もしチームメートの取れないパスを出して「お前らはダメだ」とか言っているプレーヤーがいたら、サッサと移籍してもらった方がよいでしょう。 (※)

※補足
ただし、未来の勝利のために必要な、味方がギリギリとれないくらいのキラーパスを意図的に出すプレーヤーがいるかもしれません。 ここらへんの按排(あんばい)は、もはや理屈では説明できないですね。

6. 工数の見積り

プログラマというのは本当に大変です。
ここまででもかなりの能力を求められているのに、さらに難題を押し付けられるのですから。
それが未来を予想する能力 = 工数見積もり、というやつです。

システム構築というのは、ほとんどの場合、今まで存在しなかったシステムを構築することになります。
しかも技術が日進月歩のこの世界、たいていの場合は何らかの新しい言語、インフラ、フレームワーク、ライブラリなどを採用して実装します。
さらに先述したように、構築対象は自分の知らない業務をサポートするシステムです。

新しい技術を採用すると、予想してないエラーが発生することがあります。
お客様が説明していた業務に漏れがあり、追加仕様が必要になることもあります。
ある程度モノができた段階で、実際にユーザーに触ってもらって、仕様を変更することもあります。

プログラマはこのような将来発生しうるあらゆる可能性を加味して、「このシステムは〇〇日で実装できます」と宣言しなければなりません。
さらにその限られた期間の中で業務の重要度を切り分け、最高の品質(完璧な品質などありえない、あるとすれば最高の品質だ)をも提供しなければなりません。
そのためには圧倒的な想像力が問われます。
それは、ある意味では神にも等しい先見性が求められていると言っても過言ではないかもしれません。

7. コミュニケーション

プログラマはこんなに頑張っているのに、まだ求められる能力があります。
皮肉なことに、それは多くのプログラマにとって苦手分野でもあるのです。
それがコミュニケーション能力です。

しかも、こんな残酷なことを言う人までいます。
プログラマにとって一番重要な能力はコミュニケーション能力だ」

私自身もその昔勘違いしていたのですが、システム開発というのは実はかなりのチームプレーです。
バスケは5人、野球は9人、サッカーは11人でプレーします。監督やコーチを含めても、せいぜい1チーム20~30人程度です。
みずほの勘定システムは、ピーク時8000人で開発していたそうです。
そりゃコミュニケーション能力なしではやっていけないですね。

コミュニケーションって本当に難しいです。
なぜ難しいかという端的な理由として、「本質的にアンコントローラブル(自分では制御不可能)である」という点が挙げられると思います。
要は、相手あってのコミュニケーションということですね。自分だけ理解していてもダメなのです。(※)

プログラマは、お客様に目に見えない仕様を説明する必要があります。
同僚のプログラマに、目に見えない実装方針を説明する必要があります。
いずれの場合もメリットを伝え、デメリットを伝え、自分の意見を伝え、根拠を伝える必要があります。
不明点があれば質問に回答し、反対意見があれば反駁(はんばく)し、或いは譲歩し、論点がずれれば訂正し、方針を決定しなければなりません。

どうすればわかりやすく伝わるだろうか? 先方の理解はどの程度まで進んでいるだろうか? どうすれば納得してもらえるだろうか?
そういったことを常に意識しながらコミュニケーションをとる必要があります。
つまり相手がどう理解しているのかを「想像する力」が必要なのです。

優秀なプログラマは、説明も上手です。 端的に必要十分な説明を行い、不要な情報を排除し、相手を納得させることができます。
二流はいつだって他人のせいにします。 あんなやつに説明してもわからない、と言って隅っこでふてくされています。

※補足
システム開発におけるコミュニケーション能力というのはかなり奥が深いので、いつかまた別の記事を書こうと思っています。

さいごに

偉そうにいろいろと語りましたが、私自身、まだまだ修行中の身です。
コツコツと努力を続けて、少しでもよいプログラマになれるよう、これからも頑張っていきたいと思います。

また蛇足ですが、上記の全てを兼ね備えた神様みたいなプログラマなんて、この世界には(たぶん)存在しません。
たいていの人は、このうち〇〇の想像力は優れているけれど、XXの想像力は乏しいね、ということがほとんどです。
完璧な人間なんていない、ということですね。

なんだかとても長い記事になってしまいましたが、いかがでしたでしょうか?
なにはともあれ、最後までお読みいただき、ありがとうございました。

高評価・コメントなどいただけますと大変励みになりますので、どうぞよろしくお願いします。