説明って難しいなと思う機会があり、備忘録的に記します。
前提
- ここで言う「説明」は文面で行われるものを指します。(文面がない状態で口頭で即興で行う説明は指しません)
- 例として挙げているのはコードレビュー時の説明です。
伝わる説明を書くには
①前提を省かない
■NG例
説明:「Hogeクラスのhogehogeメソッドに対して修正を入れた。hogehogeはFugaクラスから呼び出されているが、これはFugaFuga機能でのみ使われているため、全体として支障はない」
疑問:「なんでFugaFuga機能でのみ使われている場合には支障がないと言えるの?」
以下のような前提が隠れている場合、説明者は前提を無意識のうちに省略しがちです。
■NG例の説明者の脳内
「Hogeクラスのhogehogeメソッドに対して修正を入れた。hogehogeはFugaクラスから呼び出されているが、これはFugaFuga機能でのみ使われている (。FugaFuga機能は現在ほとんど廃止されており、Fuga内の呼び出し箇所も実質的にデッドコードの) ため、全体として支障はない」
※FugaFuga機能がほとんど廃止されていることは、チーム内のほとんどの開発者が知っている
「なんだ!皆廃止されていること知っているなら省いていいじゃん!」と思うかもしれませんが、基本的にNGです。
■なぜ前提を省いてはいけないのか
未経験者、部外者、未来の自分たちに不親切
チーム外の人からしたら、FugaFuga機能がほとんど廃止されていることなど知らないことです。
このレビューにたまたまチーム外の人が出席していたり、あるいは入ってきたばかりの新人、さらには全部忘れた未来の自分たちがいたりした場合には最初の疑問を持つでしょう。
■こんなご意見もあるかも
・「自分たちでキャッチアップしたりその都度質問したりしてほしい」
→短期的にはその方が早いです。
しかし、1年後、2年後、我々は自分でやった修正を忘れます。なんなら異動しているかもしれません。
そうなったときに、3年後プルリクエストの履歴を見た後輩から「先輩、このプルリクエスト見たんですけど、なんでここって支障ないって言えるんですか?」と聞かれた際、「なんだったっけ…」と探す工数が生じます。
それだけならまだいい方で、すでに開発者が退職してしまった場合には、知りもしないコードの意図を地道に読み解く作業が生じます。
もちろん、コードから裏どりする作業は結果的に必要かもしれません。しかし、説明から仮説を立てて臨めるのならその方が時間短縮になります。
・「さっと読み解けるくらいの技術をつけてほしい」
→できるならそれがベストですよね、とは思います。
小規模な開発であれば、個々人の実力ありきでもいいかもしれません。
しかしある程度大きなプロダクトとなってくると、天才だけで開発を維持するのは不可能です。
誰にでも、今いない未来の誰かにでも伝わるようにするのが、結果的に全体の工数の削減にもつながるでしょう。
・「そんなこといちいち説明していたらきりがない」
→ものによってはそういうこともありえます。(「クラスってなんですか?」みたいな疑問にいちいち答えるのはもちろんおかしな話なので…)
とはいえ、今回の例は「明らかに一般常識ではなく、説明も1~2行で済む」ものですから、もったいぶらずに書いてしまった方が伝わりやすいでしょう。
■OK例
「Hogeクラスのhogehogeメソッドに対して修正を入れた。hogehogeはFugaクラスから呼び出されているが、これはFugaFuga機能でのみ使われている 。FugaFuga機能は現在ほとんど廃止されており、Fuga内の呼び出し箇所も実質的にデッドコードの ため、全体として支障はない」
②対象を統一する。できない場合は明示的に書きわける。
■NG例
説明:「Hogeクラスのhogehogeメソッドに対して修正を入れた。修正でPiyoのpiyopiyoがfalseを返すようになっているため、hogehogeもfalseを返す意図通りの挙動に変わる」
疑問:「え、このプルリクエスト、どこでPiyoの修正してる?なくない?」
■NG例の説明者の脳内
「Hogeクラスのhogehogeメソッドに対して修正を入れた。(先月行った) 修正でPiyoのpiyopiyoがfalseを返すようになっているため、意図通りの挙動となる」
例として出しているので極端ですが、これがやった本人だと意外に気づかないものです。
■なぜNG例の説明ではダメなのか
日常生活にたとえてみると
「(今日) にんじんを買いに八百屋に行った。(前日に) 豚肉を買ったので (今日の夕飯に) カレーが作れるようになった」
疑問:「え、八百屋なのに豚肉売ってたの?」
誤解:「八百屋なのに肉が売ってるんだ。珍しい。便利だし今度からそこに行こ」
本来2回行われたはずの「買い物」が、1回としか読み取れないことで誤解を招いています。
レビューに置き換えてみると
これを先ほどのレビューの例に置き換えるとこんな疑問や誤解が生じかねません。
疑問:「え、Hoge直したはずなのにPiyoも直るの?」
誤解:「Hoge直すと自動でPiyoも直るんだ。珍しい。便利だし今度からPiyo直すときはHoge見よ」
極力、同じ文章のまとまりで、同じ単語で2個を説明するのはやめた方がいいです。
どうしても説明する必要がある場合は明示的に書き方を分けましょう。
■OK例
「Hogeクラスのhogehogeメソッドに対して修正を入れた。これによって意図通りの挙動となる。」
「補足:先月行った修正(リンクを掲載)でPiyoのpiyopiyoがfalseを返すようになっている。このためhogehogeの挙動がXXXになっているために意図通りとなる」
③結論を最初に書く
■NG例
説明:「今回の不具合の原因ですが、まず、Hogeクラスのhogeメソッドを実行しています。hogeはfugaを呼び出しており、ここでSQL文を流している。ここで…」
疑問:「え、で原因は何?」
「結論から話す/書く」とはよくいいますが、「結論」ってなんでしょうか。
なんとなく「大事なこと」「一言で表すとしたら」とかいうイメージはあっても、「大事なことって何?」「じゃあその一言って何?」と言われるとわからなくなりませんか。
私は以下のように結論を構築しています。
1:これから説明する内容について、トピックは何か「単語」で決める
例:「不具合の原因」
必ずしも1単語でなくてもいいですが、あまり冗長にならないのがベストです。
とはいえ、スタイリッシュにしようとして必要な要素がなくなるくらいなら長くなってもいいでしょう。変数やメソッドの命名と同じですね。
2:「(1で決めた単語)はなんですか」という質問に対する回答を一文で書く
例:「不具合の原因:DBからデータを取得するロジックに考慮漏れがあったため」
全ての回答を一文に収めろという話ではありません。大切なのは、サマリーが最初にあるということです。
これによって、聞く側は「今から何の話をされるのか」を把握することができます。
3:Bの根拠となる説明を続ける
例:「fugaでDBからデータを取得しているが、Fooの場合のみ、if文に入らず、fugaが実行されなかった」
特に初心者の場合、自分の主張の根拠が合っているか不安になり、つい根拠(となる調査結果)から話したくなる傾向があります。
しかしあくまで根拠は主張の支えであって、主張のない根拠(となる調査結果)は「やったことの報告」でしかありません。そもそもいずれ全部説明することにはなるんですから、腹を括って主張から話しましょう。
難しい問題:前提について
「これはトピックでも主張でもないが、この前提を最初に説明しないと以後の説明が伝わらない」という場合があります。
そういった場合には、「前提」と大きく書いておくのが良いと思っています。
読み手に対して「主となるトピックや主張ではないが、把握の必要があるんだな」という役割さえ伝われば、混乱を防ぐことができます。
■OK例
1~3をつなげるとこうなります。
「不具合の原因:DBからデータを取得するロジックに考慮漏れがあったため。」
「詳細:fugaでDBからデータを取得しているが、Fooの場合のみif文に入らず、fugaが実行されなかった」
④不用意に長い・難しい語を使わない
長い・難しいことが一概に悪いわけではないですが、しばしばニュアンスで誤解を生むことがあります。
■NG例
説明:「Piyoの修正の際、if文の考慮漏れを感知できなかったことが原因です」
疑問:「感知?じゃあ人為的なミスじゃなくて、システム上の機械的な確認の過程で問題があったっていうこと?」
「感知」という単語は、決して機械にだけ使われる単語ではありません。一方で、「気づく」「見つける」などに比べて人為的なニュアンスが薄いことも事実です。
もしそもそも機械的な確認の過程などなく、人為的なミスであるということなら、「感知」よりは「気づく」の方が誤解を与えにくいでしょう。
■OK例
「Piyoの修正の際、if文の考慮漏れに気付けなかったことが原因です」
おわりに
「この文章はこれに則れているのだろうか…」と思いながら書いていました。
伝わっているかどうかは相手に聞かないとわからないものですから、定期的にコミュニケーションについてもフィードバックをもらうことを意識していきたいですね。