https://yakst.com/ja/tags
Yakst - programming
2018-09-28T09:19:01+09:00
Yakst
https://yakst.com/ja/posts/5296
2018-09-28T09:19:01+09:00
2018-09-28T09:19:01+09:00
「20年以上プログラミングしてきた人しか知らないこととは?」に対するJohn Byrd氏の回答
<p>ソフトウェア開発におけるあらゆることは、既に発明されてしまっています。人々は、それを再発見し、あたかも初めて見つけたかのようなフリをしているだけです。あなたがかっこよくて新しいと思ったものはすべて、Smalltalk、HAKMEM(訳注 : MIT AI研究所で書かれた、アルゴリズムや理論などが書かれたメモ。<a href="https://en.wikipedia.org/wiki/HAKMEM">Wikipedia英語版</a>)、Ivan Sutherland(訳注 : <a href="https://ja.wikipedia.org/wiki/%E3%82%A2%E3%82%A4%E3%83%90%E3%83%B3%E3%83%BB%E3%82%B5%E3%82%B6%E3%83%A9%E3%83%B3%E3%83%89">Wikipedia日本語版</a>)、Douglas Engelbart(訳注 : <a href="https://ja.wikipedia.org/wiki/%E3%83%80%E3%82%B0%E3%83%A9%E3%82%B9%E3%83%BB%E3%82%A8%E3%83%B3%E3%82%B2%E3%83%AB%E3%83%90%E3%83%BC%E3%83%88">Wikipedia日本語版</a>)、初期のIBM、あるいはBell Labsからのコピーでしかありません。</p>
<p>コンパイラーを信じてはいけません。ツールを信じてはいけません。ドキュメントを信じてはいけません。自分のことも信じてはいけません。</p>
<p>もうこれ以上コンピュータ言語はいりません。しかし、あなたはすぐに新しい言語を作ってしまうでしょう。予想するに、その新しいすごい言語は、IEEE-754の規格(訳注 : <a href="https://ja.wikipedia.org/wiki/IEEE_754">Wikipedia日本語版</a>)と、固定長の整数を使うはずです。つまり、あなたの新しい言語は壊れてます。</p>
<p>コードをメンテナンスするのは、コードを書くより大変です。たくさんコードを書くことはつまり、怠けていることを意味します。</p>
<p>あなた方は皆、メモリー、プロセッサー時間、ネットワークの帯域といったものはすべて無料で、無限にある前提でプログラミングを教わってきたでしょう。そんなことはありません。そんなことはありません。そんなことあるわけないんです。Knuthのpremature optimizationに関する段落(訳注 : Donald Knuthによる有名な格言「早すぎる最適化は諸悪の根源(premature optimization is the root of all evil)」が書かれた<a href="https://dl.acm.org/citation.cfm?id=361612">論文</a>の該当する段落のこと)の残りの部分を読みましょう。</p>
<p>数ヶ月したら、自分が書いたコードが何をするものかも忘れてしまうでしょう。バカみたいに読みやすくしておきましょう。</p>
<p>必要なのはsedのワンライナーだけということだってあります。</p>
<p>「自分のメソッドはお前のよりも常にいいんだ」といったように決めつけで話すプログラマーは警戒しましょう。プログラミングはアートであって、宗教ではありません。</p>
<p>決まった手順を10回以上やることが分かっているなら、自動化しましょう。</p>
<p>バックアップとリストアはまったく別のことです。</p>
<p>自分のマシン上で動いたからといって、バグがないことにはなりません。 --<a href="https://www.quora.com/profile/Piers-Sutton">Piers Sutton</a></p>
<p>開発ツールをはインストールする前に、最初のマイナーリリースまで様子を見ましょう。誰か他の人に実験台になってもらいましょう。</p>
<p>良いプログラマーは良いコードを書きます。素晴らしいプログラマーはコードを書きません。<a href="https://teespring.com/stores/the-zen-programmer">禅プログラマーはコードを削除します。</a></p>
<p>何人の管理職が騒ぎ立てていようと、最初にやることは確実にバグを再現することです。</p>
<p>遅かれ早かれ、長らく業界にいる年寄りに出会うでしょう。いつかその人は「プログラミングの法則」について教えてくるはずです。そういう人は完全に無視しましょう。</p>
doublemarket
https://yakst.com/ja/posts/4965
2017-12-25T07:25:06+09:00
2017-12-25T07:25:06+09:00
人間らしくコードレビューするには(パート2)
<p><img src="https://mtlynch.io/images/human-code-reviews-2/cover-part-two.png" alt="https://mtlynch.io/images/human-code-reviews-2/cover-part-two.png)"></p>
<p>この記事はコードレビューの際に落とし穴にはまらずに、どのようにうまくコミュニケーションをとるか、に関する記事の後半部分です。今回はひどい衝突を避け成功裏にレビューを終わらせるテクニックに焦点をあてます。</p>
<p><a href="https://yakst.com/ja/posts/4907">パート1</a>で基礎的なことを述べましたので、そこから読み始めることをお勧めします。我慢ができない方のために、簡単にお伝えしますと次の通りです: 優れたコードレビュアーはバグを発見するだけではなく、チームメイトがより良くなるためによく吟味してフィードバックします。</p>
<h3>私の最悪のコードレビュー</h3>
<p>私の人生で最悪のコードレビューは以前のチームメイト(ここではマロリーとします)とのやりとりです。彼女は私が会社に入る数年前から会社に在籍し、ごく最近になって私のチームに異動しました。</p>
<h4>レビュー</h4>
<p>マロリーが初めて変更リストを作成し私にレビューを依頼してくれたとき、コードは少し荒削りでした。彼女にとってPythonは初めてで、その上彼女は私が維持管理していた格好の悪いレガシーなシステムを元にコードを書いていました。</p>
<p>私は律儀に気がついた全ての問題を記載し、これは全部で59にもなりました。私が読んだレビューに関する文献によると、私はとても素晴らしい仕事をやりとげました。<strong>本当に</strong>とてもたくさんの誤りを見つけたのです。つまり、私は良いレビュアーに違いありません。</p>
<p>2, 3日後、マロリーは変更リストを修正し、私のコメントに対する回答をしてくれました。彼女は単純な問題に関しては修正していました。タイポ、変数名の修正、などです。しかし、彼女は高位の問題、すなわち不正な入力に対する挙動が定義されていなかったり、ある関数内の制御フローが6段階ネストされている、といったことに対応することを拒んでいました。そのかわりに彼女は拒絶的にこれらの問題は時間をかけて修正する価値がないことを説明していました。</p>
<p>私は怒り、そして苛立って、新しいラウンドでコメントをつけました。コメントは専門的ではありましたが問題解決に取組むものではない(passive-aggressive)ものとなっていました: 「不正な入力に対して挙動を定義しないのは<em>なぜ</em>なのか」。ご想像の通り、マロリーの返信は一層意地のはったものとなりました。</p>
<p><img src="https://mtlynch.io/images/human-code-reviews-2/boulder.png" alt="https://mtlynch.io/images/human-code-reviews-2/boulder.png"></p>
<h4>負のサイクル</h4>
<p>私とマロリーが同じレビューのやり取りをまだしていた火曜日のことでした。私は夕方に新しいコメントを書いていました。私は彼女がそのレビューを読んでいる時に同じ部屋にいたくなかったので、その日は意図的に彼女が帰るまでそのままにしました。</p>
<p>午前中ずっと、次のレビューラウンドがとても怖かったので悪いことが起きそうな感覚をお腹の底に感じてました。昼食から戻ったら、マロリーは不在でしたが新しい変更をリストをくれていたことに気が付きました。おそらく、彼女は私がその回答を読んでいるときに近くにいたくなかったのだとおもいます。</p>
<p>彼女の回答ごとに私の怒りはどんどん増長し私の心はズキズキし始めました。私はすぐに反発心を持ちキーボードを叩き始め、彼女が私の提案した変更も実施するでもなく、その正当性について私に承認を求めてもいないことを指摘しました。</p>
<p>我々はこのルーチンを3週間にわたって毎日実施しました。コードはほとんど変わりませんでした。</p>
<h4>中断</h4>
<p>ありがたいことに、我々の一番年上のチームメイトであるボブはこの循環を打開してくれました。彼は長い休暇から戻り、私達がレビューのコメントを投げつけあい行ったり来たりしているのに気が付き注意してくれました。彼はすぐにどのような状況なのか認識しました: 膠着状態です。彼はレビューを引き継ぐよう要請し我々はお互いにそれに合意しました。</p>
<p>ボブはレビューを始めるにあたってマロリーに新しい変更リストを作成するよう要請しました。我々が決して争うことのなかった2つの小さなライブラリを分割し、それぞれおよそ30から50行に分割するように、です。マロリーがこれを終えると、ボブはすぐにこれを承認しました。</p>
<p>それからボブは主な変更リストに戻り、これは200行のコードにスリム化されていました。ボブはマロニーが取り組んだ問題に2、3の小さな提案をしました。そして、彼は変更リストを承認しました。</p>
<p>ボブのレビューは全体で2日で完了しました。</p>
<h4>コミュニケーションの問題</h4>
<p>おそらくみなさんはこの衝突は本当はコードに関するものではないと推察されることでしょう。本物の問題もありましたが、これは効果的にコミュニケーションできるチームメイトであれば、明らかに解決できたでしょう。</p>
<p>これは嫌な経験でしたが、今になって思えば感謝すべき経験です。これにより自分のレビューのアプローチを再評価し、改善点を見つけられました。</p>
<p>次に、同じように望ましくない結果になるリスクを低減するためのいくつかのテクニックをご紹介します。後程マロリーの件に戻り、そこでなぜ当初の私のアプローチが悪い方向に向かい、ボブのアプローチがとても素晴らしかったかについて説明します。</p>
<h3>テクニック</h3>
<ul>
<li>9. コードを1段階か2段階向上させることを目標にする</li>
<li>10. 同じ指摘を繰り返さないようにする</li>
<li>11. レビューのスコープを順守する</li>
<li>12. 大きなレビューを分割する機会をさがす</li>
<li>13. 心の底からの賞賛を</li>
<li>14. 残った修正が軽微なものであれば承認する</li>
<li>15. 膠着状態に対してはプロアクティブに対応する</li>
</ul>
<p>訳注: No. 1-8は本記事の<a href="https://yakst.com/ja/posts/4907">前半記事</a>の通番です。</p>
<h4>コードを1段階か2段階向上させることを目標にする</h4>
<p><em>論理上は</em>チームメイトはコードを改善するためにすべての機会を探し求めているはずですが、彼らの忍耐にも限界があります。彼らの変更リストを改善する新しくよりよい方法をあなたが考え続け何ラウンドも承認せずにいると、彼らの苛立ちはすぐに募ります。</p>
<p>私はコードについて個人的にAからFまでの評価を考えます。もしDから始まる変更リストを受け取ったならば、オーサーがCまたはB-にもっていけるように手助けするよう試みます。完璧ではなく、十分なレベル目指します。</p>
<p>理論上は、DをA+にすることもできますが、これはおそらく向上させるには8ラウンドものレビューを実施することでしょう。終いには、オーサーはあなたのことを嫌いになり、あなたには2度とコードを見せたくないと思うことでょう。</p>
<p><img src="https://mtlynch.io/images/human-code-reviews-2/letter-grade.png" alt="letter-grade.png"></p>
<p>次のように考えるかもしれません、「Cレベルのコードを承認したら、コードベースは最終的にCグレードになってしまうのだろうか?」幸運にも、そうではありません。チームメイトをDからCに向上するのを手助けすれば、彼らの次の変更リストはC「から始まる」ことでしょう。2, 3ヶ月のうちにBから始まるレビューを提示するようになり、こうなればレビューの最後にAにできるのです。</p>
<p>Fは機能的に正しくない、あるいは正しいかどうか確信を持てないくらいとても複雑な場合にとっておきます。唯一承認を保留すべきケースとして、レビュー2, 3ラウンドでFのままである場合があります。この場合は下記の膠着状態に関する章を参照してください。</p>
<h4>同じ指摘を繰り返さないようにする</h4>
<p>全く同じパターンの複数の誤りに気がついた場合、それぞれにコメントするのはやめましょう。同じことを25回書くのに時間を使いたくないでしょうし、オーサーは25回同じコメントを読みたいと思っていないに違いありません。</p>
<p>指摘は2, 3の個別の箇所に留めるのが良いでしょう。それぞれの例に対応するより、単にそのパターンを修正するようにオーサーに依頼するのが何よりです。</p>
<p><img src="https://mtlynch.io/images/human-code-reviews-2/instance-variables.png" alt="instance-variables.png"></p>
<p>※レビューコメント訳</p>
<p>インスタンス変数名は、それがpublicのインターフェースの一部でない限りはアンダースコアで始めるべきです。</p>
<p><a href="https://google.github.io/styleguide/pyguide.html#Naming">https://google.github.io/styleguide/pyguide.html#Naming</a></p>
<p>(他の箇所も同様)</p>
<h4>レビューのスコープを順守する</h4>
<p>私がよく見るアンチパターンとして、レビュアーが変更リストの<em>近くの</em>コードに関して何かしら気がつきオーサーに修正を求める、というものがあります。一度オーサーが応じると、通常レビュアーは良くはなっているものの一貫性がない事に気が付き、更に細かないくつかの変更が必要となります。そしていくつか更に...。そしてそして小さくスコープが指定されている変更リストが多数の無関係な変更を含むものに拡大されます。</p>
<blockquote>
<p>玄関の近くに小さな空腹のネズミが待ちうけていれば、おそらくクッキーをあげたくなることでしょう。クッキーをあげれば、ミルクが欲しいというでしょう。そして鏡の中にミルクの口ひげが映らないように、はさみが欲しいというでしょう...</p>
<p>Laura Joffe Numeroff著, <a href="https://aax-us-east.amazon-adsystem.com/x/c/QpKGG2XkpGLk5t6q1099ApwAAAFgaTIA3gEAAAFKAS70zI8/https://assoc-redirect.amazon.com/g/r/http://www.amazon.com/If-You-Give-Mouse-Cookie/dp/0060245867/ref=as_at/?imprToken=GnR7npueA8HYxSJB5P1ubQ&slotNum=0&ie=UTF8&qid=1509191838&sr=8-1&keywords=if+you+give+a+mouse+a+cookie&linkCode=sl1&tag=mtlynch-20&linkId=ffcba792715c1f7538d598060aeff982">If You Give a Mouse a Cookie</a></p>
</blockquote>
<p><img src="https://mtlynch.io/images/2017-11-09-human-code-reviews-2/if-you-give-a-mouse-a-cookie.jpg" alt="if-you-give-a-mouse-a-cookie.jpg"></p>
<p>経験則としては次のとおりです: その行が変更リストの範囲でなければ、それはスコープ外です。</p>
<p>ここで一例を示します: </p>
<p><img src="https://mtlynch.io/images/human-code-reviews-2/out-of-scope-1.png" alt="out-of-scope-1.png"></p>
<p>仮にあなたが徹夜をしており、コードベースの<a href="https://ja.wikipedia.org/wiki/%E3%83%9E%E3%82%B8%E3%83%83%E3%82%AF%E3%83%8A%E3%83%B3%E3%83%90%E3%83%BC_(%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0)">マジックナンバー</a>とおかしな変数名に悩まされたとしても、これはスコープ外です。オーサーがその近くの行を書いたのと同じ人であったとしても、これはスコープ外です。それがどんなにひどかったとしても、バグを記録するかあなた自身が修正を提示するかのどちらかとし、このレビューでのオーサーに対応を強いないことです。</p>
<p>この例外として、変更リストは実際にそれを変更してはいないものの周辺のコードに影響をあたえる場合があります。例えば次のとおりです:</p>
<p><img src="https://mtlynch.io/images/human-code-reviews-2/in-scope.png" alt="in-scope.png"></p>
<p>このケースでは、オーサーは関数名を<code>ValidateAndSerialize</code>からただの<code>Serialize</code>に変更すべきという指摘です。関数シグネチャを含む行は変更していませんが、変更により正しくなくなっています。</p>
<p>指摘箇所は少ないもののスコープ外の簡単な修正に気がついた場合に私はこのルールをゆるく破っています。この場合には、オーサーはコメントを無視しても良いことを明示しています。</p>
<p><img src="https://mtlynch.io/images/human-code-reviews-2/out-of-scope-note.png" alt="out-of-scope-note.png"></p>
<h4>大きなレビューを分割する機会をさがす</h4>
<p>400行を超えるコードの変更リストを受け取った場合、オーサーにはこれを小さく分割するように促します。この制限を超えれば超えるほどそれだけ反対をとなえるのが難しくなります。私は個人的に、1000行以上の変更リストはいかなるものも受け取らないようにしています。</p>
<p><img src="https://mtlynch.io/images/human-code-reviews-2/magician.png" alt="magician.png"></p>
<p>変更リストの分割は退屈な作業ですのでオーサーはこれに不平をこぼすことでしょう。この分割の論理的な境界を明らかにすることにより彼らの重荷を軽減します。もっとも簡単なケースとしては変更リストが複数のファイルに独立に変更を加えている場合です。この場合は、変更リストをより小さい単位のファイル群に分割するだけで良いでしょう。難しいケースでは、関数やクラスの最も抽象化レイヤーが低いものを探します。オーサーにこれらを別々の変更リストとするように依頼し、最初の変更リストがマージされてから残りのコードに戻ります。</p>
<p>コードの品質が低い場合は、<strong>はっきりと</strong>分割することを依頼します。悪いコードをレビューする際、その大きさに対して指数関数的にレビューが困難となります。600行の1つのひどいコードより、1組の粗雑な300行の変更リストのほうが遥かによく内容を確認できます。</p>
<h4>心の底からの賞賛を</h4>
<p>大多数のレビュアーはコードのどこが<em>誤っているか</em>のみに焦点をあてますが、レビューはすばらしいところをより促進する貴重な機会です。</p>
<p>例えば、あなたがレビューしておりオーサーがドキュメントを頑張って書いており明確で簡潔な関数のコメントを見つけたシーンを想像してみてください。よくやったことを伝えてあげます。出来がひどい場合にそれが改善されるのをただ待つだけではなく、その代わりにきちんと修正されたときにそれを伝えてあげれば、改善の速度が増すことでしょう。</p>
<p><img src="https://mtlynch.io/images/human-code-reviews-2/mma.png" alt="mma.png"></p>
<p>賞賛をするために具体的なゴールを念頭におく必要はありません。変更リストに何か喜ばしいことを見つけたときはいつでもそれをオーサーに伝えてあげています:</p>
<ul>
<li>「このAPIは知りませんでした。とても便利ですね!!」</li>
<li>「これは素晴らしい解決策です。考えてもみませんでした。」</li>
<li>「この関数を分割するのは素晴らしいアイデアですね。以前よりとてもシンプルになりました。」</li>
</ul>
<p>オーサーが経験の浅い開発者であるかあるいは最近チームに加わった場合は、彼らはレビューの最中に神経質あるいは防衛的になりやすいのです。丁寧に誠意ある賛辞を送り、あなたが非情なゲートキーパーではなく助けてくれるチームメイトであることを実際に示すことで、彼らの緊張は緩和します。</p>
<h4>残った修正が軽微なものであれば承認する</h4>
<p>レビュアーの方々の中には、全てのコメントに対する修正を確認するまで承認をしてはならない、という誤った考えをお持ちの方がいます。これにより不要なレビューラウンドが発生し、レビュアーおよびオーサー両者の時間が無駄になります。</p>
<p>以下のいずれかに当てはまれば承認します。</p>
<ul>
<li>追加のコメントがない場合</li>
<li>残りのコメントが軽微な問題である場合
<ul>
<li>例) 変数名の修正、タイポの修正</li>
</ul></li>
<li>残りのコメントがオプショナルな提案である場合
<ul>
<li>チームメイトがこの修正が承認の条件だと考えないようにオプショナルであることを明示しましょう。</li>
</ul></li>
</ul>
<p>コードへのコメントの最後のピリオドが欠けているためにレビュアーが承認を保留したのを見たことがあります。これはやめてください。これはあなたが「彼らは単なる句読点の追加すら監督されないとできない」とみなしているとオーサーに伝えることになります。</p>
<p>未解決のコメントがあるのに承認するのはいくらか危険があります。私の見積もりでは 〜 5%のケースで、オーサーは最後のラウンドのコメントに対して誤った解釈をするか、あるいはそれを完全に忘れるかします。これを緩和するために、私は単純に承認後のオーサーの変更をチェックしています。ミスコミュニケーションがあった場合はオーサーにフォローアップするか修正の変更リストを自分で作成するかのいずれかとします。5%のケースに対して少量の修正をするほうが、その他の95%に対して不要なコストをかけ遅延を発生させるより良いのです。</p>
<h4>膠着状態に対してはプロアクティブに対応する</h4>
<p>コードレビューでありうる中で一番良くない結果は膠着状態です: あなたが変更なしには変更リストの承認を拒否し、一方でオーサーがその変更を拒んでいる場合です。</p>
<p>膠着状態に向かっていると判断するいくつかの指針を示します:</p>
<ul>
<li>ディスカッション口調の緊迫度合いあるいは敵対度合いが増している</li>
<li>レビュー毎のあなたのコメントが収束傾向となっていない</li>
<li>通常ではない数のコメントで押し返している</li>
</ul>
<p><img src="https://mtlynch.io/images/human-code-reviews-2/pilots.png" alt="pilots.png"></p>
<h5>話してみる</h5>
<p>対面で話すか、ビデオチャットをします。文字のコミュニケーションは、会話のもう片側に現実世界の人間がいることを忘れてしまうような事態を引き起こす1つの要因となります。チームメイトが意地を張ってるから、あるいはできる能力がないからそうなっているのかを容易に想像できるようになります。対面することであなたとオーサー両者にかかった魔法が解けるかもしれません。</p>
<h5>設計のレビューを考える</h5>
<p>議論を引き起こすコードレビューは、このコードレビュー以前の過程が不十分であることを示しているかもしれません。設計レビューの際に網羅すべきだったことについて言及しましたか?設計レビューは<em>ありましたか</em>?</p>
<p>意見の不一致の根本原因が高位のレベルの設計の選択まで戻るのであれば、たまたまコードレビューをしている2人の手の内に留めるのではなく、よりチームの広範囲のメンバーが介入すべきです。設計レビューをチームの残りのメンバーに対する公開ディスカッションとして開催する中でオーサーと話し合いましょう。</p>
<h5>譲歩するかエスカレーションする</h5>
<p>あなたとチームメイトの膠着状態が長引けばそれだけ、関係が損なわれます。複数の選択肢で解決しないのであれば、あなたの意見を譲歩するかあるいはエスカレーションします。</p>
<p>変更を承認することのコストだけを見積もります。低品質のコードを不用意に承認すればソフトウェアの品質は築けませんが、あなたとチームメイトが激しくやり合い一緒に働かなくなっても高品質も達成できません。この変更リストを承認すると<em>本当に</em>何が良くないのでしょうか。重要なデータを破壊する可能性があるコードでしょうか?あるいはバックグラウンドプロセスでの修正で、最悪のケースでジョブが失敗し開発者がデバッグすれば良いでしょうか?もし後者に近いのであれば、チームメイトと良い関係性で働き続けられるように単に譲歩することを考えます。</p>
<p>譲歩できないと判断されれば、この議論をチームのマネージャーあるいは技術リーダーにエスカレーションすることをオーサーに伝えましょう。違うレビュアーを再アサインするよう提案します。エスカレーションの結果あなたの意見と異なる場合、決定を受け入れ次に進みます。やり合いが継続すると良くない状態が長引きあなたがプロフェッショナルでないように見えます。</p>
<h5>膠着状態を脱する</h5>
<p>入り乱れたレビューのコメントはコードについての内容ではなく関係する人々の関係に関するものになりがちです。膠着状態あるいは、膠着状態に近い状態に達した場合、内在する衝突の問題に対処しなければこの状況は継続するでしょう。</p>
<ul>
<li>状況についてマネージャーと議論する。
<ul>
<li>チーム内の衝突があれば、マネージャーはそれを把握しておく必要があります。おそらくオーサーは対処が難しいでしょう。 もしかするとあなたは自身が受け入れない状況を作るのに寄与しているかもしれません。素晴らしいマネージャはこれらの問題を解決するために両者の助けとなるでしょう。</li>
</ul></li>
<li>お互いに休憩を取る。
<ul>
<li>可能であれば、クールダウンするまでお互いに2, 3週間コードレビューを止めてみます。</li>
</ul></li>
<li>衝突の解消について学ぶ。
<ul>
<li>「<a href="https://aax-us-east.amazon-adsystem.com/x/c/QpD8D4pbRAUMePERdW46CG4AAAFgc5ji3QEAAAFKAYAUEn8/https://assoc-redirect.amazon.com/g/r/http://www.amazon.com/Crucial-Conversations-Talking-Stakes-Business/dp/0071771328/ref=as_at/?imprToken=zdw9hPVuiZvMq93ghGCJUA&slotNum=1&ie=UTF8&qid=1506388074&sr=8-1&keywords=crucial+conversations&linkCode=sl1&tag=mtlynch-20&linkId=255f34b9bc79323f513f41104eb19d91">Crucial Conversations</a>」が有用です。記されたアドバイスは常識のようですが、あなたがそのつもりはなくても衝突しているアプローチについて分析するのにとても大きな価値があります。</li>
</ul></li>
</ul>
<h3>私の最悪のコードレビュー: 再考</h3>
<p>マロリーとのコードレビューを覚えているでしょうか?なぜ私のレビューは3週間、問題の解決に向かわないおぞましいものだったのに、ボブのレビューは2日間でいとも簡単に終わったのでしょうか?</p>
<h4>私の何が悪かったか</h4>
<p>これはマロリーがチームに来て初めてのレビューでした。私は彼女が非難されていると感じたり防御的になっているであろうことを考慮しませんでした。私は彼女が大量のコメントに不意討ちされたように感じないように「4. 高位のレベルから始め詳細化する」べきでした。</p>
<p>私は自分のレビューが彼女の仕事を妨げるためでないことをもっと実際に示す必要がありましたが、どちらかといえばこれを前に推し進めてしまいました。私は「5. コードのサンプルを示して寛大に」し、彼女の変更リストに対して「13. 心の底からの賞賛を」送るべきでした。</p>
<p>私は「個人的なエゴ」をレビューに介入させてしまいました(6. 相手に直接言及しない)。私は過去数年間この古いシステムを健全にするために時間を費やしてきました。突然これをいじる新しいメンバーが現れたのですが、彼女は私の懸念を真面目に受け止めこれ以上にないほど悩んだでしょうか?私はこれを無礼と感じたのですが、その態度が逆効果でした。レビュー全てに客観的な心持ちを持ちつづけるべきでした。</p>
<p>最後に、私は膠着状態をあまりにも長く継続させました。2, 3ラウンドの後に、我々は有意義な前進をしていないことを明確とすべきでした。私は「大きな変更を決断し(15. 膠着状態に対してはプロアクティブに対応する)」、例えば直接話し合い深い衝突に対処したり、マネージャーにエスカレーションすべきでした。</p>
<h4>ボブの何が良かったか</h4>
<p>ボブが最初の第1手として「12. レビューを分割」したのはとても効果的でした。レビューが苦痛の3週間にわたって停滞していたのを思い出してみてください。突然、コードの2ピースがマージされたのです。これは前に進む動きを確立したため、マロリーとボブ両者の気分を良いものとしました。残りの部分に問題が残っていたものの、これは小さく扱いやすい変更リストとなっていました。</p>
<p>ボブは「レビューを完全なところまでもっていこうとはしませんでした(9. コードを1段階か2段階向上させることを目標にする)」。彼は私が叫んでいたものと同じ問題に気がついていましたが、マロリーはしばらくチームに居ることを認識していました。彼の短期的な柔軟な対応によって、マロリーが長期的に品質を向上させるのに役立つように関係を築きました。</p>
<h3>結論</h3>
<p>この記事の前半を公開した後、読者の何名かは私の提案したコミュニケーションスタイルに問題を提起しました。ある人達は気に入りました。その他の人は、間接的でリスクのあるミスコミュニケーションを懸念していました。</p>
<p>このフィードバックは理にかなっており予測されたものです。ある人は簡潔なレビューコメントをぞんざいである、あるいは無礼であると感じるかもしれません。他の人は同じコメントを簡潔で効率的と感じるかもしれません。</p>
<p>コードのレビューでは、あなたは多くの選択をします: 何に焦点を当てるか、フィードバックをどのように構成するか、いつ承認するか、です。<em>私の</em>意見を選択するかは重要ではありません。ただこのような意見が<em>ある</em>ことを認識すればよいのです。</p>
<p>あなたに完全なレビューのレシピを手渡しできる人は誰もいません。最もうまくいくテクニックはコードのオーサーの性格や、彼らとの関係、チームの文化に依ります。コードレビューの成果について真剣に考えることによってあなたのアプローチを磨き上げましょう。レビューの品質に注意を払いましょう。あなたの基準を満たすところまでコードの品質を向上できないと感じるなら、レビュープロセス上の何が妨げになっているか、そしてどのようにそれに対処できるかを考えましょう。</p>
<p>人間らしいコードレビューができるよう、幸運を祈ります。</p>
<h3>追加の文献</h3>
<p>コードレビューの社会的な要因に十分な注意をはらっている私が知りうる唯一の著者として、Dr. Kari Wiegersがいます。彼は「<a href="http://www.processimpact.com/articles/humanizing_reviews.html">Humanizing Peer Reviews</a>」で彼の見解をよくまとめています。2002年に書かれたものですが、継続して適用可能な内容が効果的なコミュニケーションの長期的な価値を実証しています。</p>
<p><em>この記事は編集: <a href="https://www.upwork.com/fl/samanthamason">Samantha Mason</a>、イラスト: <a href="https://www.linkedin.com/in/lolo-ology/">Loraine Yow</a>です。この投稿の初期の草稿段階で貴重なフィードバックをくれた<a href="https://twitter.com/global4g">@global4g</a>へ感謝します。</em></p>
taka-h
https://yakst.com/ja/posts/4907
2017-10-25T07:41:23+09:00
2017-10-25T07:41:23+09:00
人間らしくコードレビューするには(パート1)
<p>最近、コードレビューのベストプラクティスについての記事をいくつか読みました。これらの記事はバグを見つけることにフォーカスしていて、レビューにおける他の要素には焦点があたっていないことに気が付きました。見つけた問題点に対して建設的、かつうまくコミュニケーションをとる方法?全然違います!バグを全て抽出し、あとはよろしくとなっています。</p>
<p>そこで、私はお告げを受けました: これがもしコードでうまくいったら、なぜロマンスがうまれないといえましょうか。
私は開発者の皆様に愛が芽生える新しい電子書籍をだそうと思います。</p>
<p><img src="https://mtlynch.io/images/human-code-reviews-1/book-cover.png" alt="書籍の表紙"></p>
<p>私の革新的な電子書籍はあなたのパートナーの不備を最も多く見つける <strong>実証済みのテクニック</strong>をご案内します。この本は次のことは<strong>取り扱いません</strong></p>
<ul>
<li>発生した問題に対してパートナーと相手の感情を理解してコミュニケーションする</li>
<li>あなたのパートナーの弱みを指摘しやすくする</li>
</ul>
<p>私がコードレビューの書籍を読んだ限りでは、人間関係については、<em>明白</em>であり<em>議論するに値しません</em>。</p>
<p>この電子書籍はお役に立ちそうでしょうか?きっと「違う違う!」と甲高い声でいわれるのではないかと思います。</p>
<p>それでは、なぜそのようになってしまったのでしょうか?</p>
<p>私は、今まで私が読んだ書籍は未来の書籍であり、そこでは開発者は全てロボットになっているとしか考えられません。その世界では、チームメイトはコードに対する思慮のない言葉での批評で、その冷たいロボットの心を暖かくし、これを喜んで受け入れるでしょう。</p>
<p>私はあなたがいま現在のコードレビューを改善したいという大胆な仮説をたてようとしており、そこではあなたのチームメイトは人間です。さらに大胆な仮説として、同僚と良い関係となれば、これはただ単に各不備を改修するコスト(cost-per-defect)を最小化するだけでなく、結果的に以前よりより良い関係が築けるとしましょう。このような環境下でどのようにあなたのレビューを改善できるでしょうか?</p>
<p>この記事では、コードレビューに関しての、技術的なプロセスだけではなく、同時に良い関係が築ける技術について議論したいと思います。</p>
<h4>コードレビューとは何か?</h4>
<p>「コードレビュー」という言葉は、チームメイトの肩越しにコードを読むことから、20人の打合せでコードを1行ずつ解析することまで様々な活動で使われます。私はこの用語を、打合せで直接コードインスペクションするような大掛かりなものではなく、形式的に書かれたものとして進めるものとして利用します。</p>
<p><img src="https://mtlynch.io/images/human-code-reviews-1/flowchart.png" alt="コードレビューの流れ"></p>
<p>コードレビューの参加者としては、コードを書いてレビューを依頼する<strong>オーサー</strong>と、コードを読みチームのコードベースにマージできるかを判断する<strong>レビュアー</strong>がいます。レビューは複数のレビュアーを設け実施することもできますが、単純にするためにあなたが唯一のレビュアーであると仮定することにします。</p>
<p>コードレビューを開始する前に、オーサーは<strong>変更リスト(changelist)</strong>を作成しなければなりません。コードレビューは複数回の<strong>ラウンド</strong>で実施されます。それぞれのラウンドはオーサーとレビュアーの間の1回の往復で完了します。オーサーは変更を提示し、レビュアーはこれらの変更に対してフィードバックを書き起こしそれに応えます。コードレビューは1回以上のラウンドとなります。</p>
<p>レビューはレビュアーが変更を<strong>承認</strong>したら完了します。これは通常LGTM(「looks good to me」の短縮形)をというコメントをつけることで行われます。</p>
<h4>なぜコードレビューは難しいのか?</h4>
<p>プログラマーが彼らが最高と考えている変更をあなたに提示し、あなたがなぜそれが素晴らしくないかを大掛かりに一覧を書き起こす必要がある場合、これを伝えるのはとてもセンシティブなメッセージです。</p>
<blockquote>
<p>私がITに戻りたいと思わない理由の1つが、プログラマーの人々はとても好かれない人々であることです... 例えば航空業界では自身のスキルレベルを大きく過信した人はみな死んでしまうのです。</p>
<p><a href="https://aax-us-east.amazon-adsystem.com/x/c/QsbeTa_Fv3xsYs2aB-3dwCUAAAFfPt7YRQEAAAFKATC-c1Y/https://assoc-redirect.amazon.com/g/r/http://www.amazon.com/Founders-Work-Stories-Startups-Early/dp/1430210788/ref=as_at/?imprToken=5j3R.nsLZBM-O4MP2PCcDw&slotNum=0&s=books&ie=UTF8&qid=1506990643&sr=1-1&keywords=founders+at+work&linkCode=sl1&tag=mtlynch-20&linkId=1976363a3117e2a2d4bac2ca75ec30ae">Founder at Work</a>からArsDigitaの共同創設者であるPhilip Greenspun氏の言葉の引用</p>
</blockquote>
<p>オーサーは彼らのコードへの批評を、彼らが能力のないプログラマーであると暗に伝えているととらえるのは容易でしょう。コードレビューは知識を共有し、より確かな知識に基づき技術観点の決断をする機会です。しかし、オーサーがこのディスカッションを個人への攻撃と認識すればそれらは達成されません。</p>
<p>あなたの考えを書いて伝えることは、そんなに難しくないと思われるかもしれませんが大変なことです。ミスコミュニケーションのリスクはより高くなります。オーサーはあなたの声の調子もわかりませんし、ボディーランゲージもわかりませんので、注意深くはっきりとフィードバックすることがより重要となります。批評に対して身構えているオーサーからすると、「ファイルハンドラーをクローズし忘れています」といった何の変哲のないコメントでも「ファイルハンドラーをクローズし忘れるなんて<em>信じられません</em>ね!あなたは本当に間抜けですね」といったように解釈しうるのです。</p>
<h4>コードレビューのテクニック</h4>
<ul>
<li>1. 単純なことはコンピューターにやらせてしまう</li>
<li>2. コードの記法については規約で明確に決める</li>
<li>3. すぐにレビューを始める</li>
<li>4. 高位のレベルから始め詳細化する</li>
<li>5. コードのサンプルを示して寛大に</li>
<li>6. 相手に直接言及しない</li>
<li>7. フィードバックする際に命令するのではなく、お願いする</li>
<li>8. 意見ではなく原則に基づいてコメントをする</li>
</ul>
<h5>単純なことはコンピューターにやらせてしまう</h5>
<p>打ち合わせやEメールのような割込みがあり、あなたがコードにあてられる時間は多くありません。そして、精神的にも持続しないものです。チームメイトのコードを読むのは経験的にとても骨が折れることで、高レベルの集中が求められます。これらのリソースをコンピュータができること、特に人間よりコンピューターのほうがよくできることに無駄遣いしてはなりません。</p>
<p>空白のエラーはわかりやすい例です。人間のレビュアーがインデントのミスを見つけ、修正するためにオーサーとやり取りするのと、自動書式整形ツールを利用するのとを比べてみましょう。</p>
<h6>人間のレビュアーが実施する際に必要なコスト</h6>
<ul>
<li>1. レビュアーが空白の問題や誤ったインデントを探す</li>
<li>2. レビュアーが誤ったインデントについてコメントをかく</li>
<li>3. レビュアーがコメントが明確で、非難するような書き方をしていないことを読み直して確認する</li>
<li>4. オーサーがコメントを読む</li>
<li>5. オーサーがコードのインデントを修正する</li>
<li>6. オーサーがコメントに対して適切に対処したことをレビューワーが確認する</li>
</ul>
<h6>書式整形ツールを使う際に必要なコスト</h6>
<p>なし!</p>
<p>後者の書式整形ツールを使った場合は、オーサーが「保存」ボタンを押すたびに空白を自動で直してくれるツールを利用しているため、なにもコストがありません。最悪のケースでも、オーサーはコードに対するレビュー依頼を実施し、<a href="https://ja.wikipedia.org/wiki/%E7%B6%99%E7%B6%9A%E7%9A%84%E3%82%A4%E3%83%B3%E3%83%86%E3%82%B0%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3">継続的インテグレーション</a>によって空白が正しくないことを知らせてくれます。レビュアーが全く気にすることなく、オーサーは問題を修正します。</p>
<p>自動化することによってレビューから取り除ける機械的にできるタスクについて見てみましょう。ここに一般的なものを記します。</p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th style="text-align: left">タスク</th>
<th style="text-align: left">自動化の方法</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: left">ビルドの確認</td>
<td style="text-align: left"><a href="https://travis-ci.com/">Travis</a>や<a href="https://circleci.com/">CircleCI</a>のようなCIサービス</td>
</tr>
<tr>
<td style="text-align: left">自動テストの状態の確認</td>
<td style="text-align: left"><a href="https://travis-ci.com/">Travis</a>や<a href="https://circleci.com/">CircleCI</a>のようなCIサービス</td>
</tr>
<tr>
<td style="text-align: left">空行がチームの規約とあっているかの確認</td>
<td style="text-align: left"><a href="https://clang.llvm.org/docs/ClangFormat.html">ClangFormat</a>(C/C++)または<a href="https://golang.org/cmd/gofmt/">gofmt</a>(Go)のような書式整形ツール</td>
</tr>
<tr>
<td style="text-align: left">利用されていないインポートや変数の確認</td>
<td style="text-align: left"><a href="https://pypi.python.org/pypi/pyflakes">pyflakes</a>(Python)や<a href="http://jslint.com/help.html">JSLint</a>(JavaScript)などのコードチェックツールを利用する</td>
</tr>
</tbody>
</table>
<p>自動化することによりあなたはレビュアーとしてより価値のある貢献ができるようになります。<code>imports</code>の順序やソースコードのファイル名の命名規約などの問題を無視できるならば、機能上の誤りや可読性の問題といった、より関心のある問題にフォーカスすることができます。</p>
<p>オーサーもまた自動化の恩恵を受けます。ケアレスミスを見つけるのに1時間浪費することなく、即座に見つけられます。即座にフィードバックを受けられることで、関係のあることがオーサーの頭に残り、これにより学習が容易となり、修正コストが低くなります。それに加え、彼らが初歩的な誤りについて指摘を受ける必要がある場合、あなたから指摘を受けるよりコンピューターから指摘を受けたほうが彼らの自尊心の観点からはるかに気分がよいわけです。</p>
<p>これらの自動チェックはコードレビューのワークフローの中に入れましょう(例えば、Gitの<a href="https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks">コミット前のフック</a>やGithubの<a href="https://developer.github.com/webhooks/">webhook</a>です)。オーサーがこのチェックを手動で行うことを前提としておけば、あなたはこの恩恵に授かれます。
オーサーもたまに忘れることがありレビュアーがやむをえずこの単純な問題をレビューし続けなければいけない場合も、自動化すれば代わりに対処してくれます。</p>
<h5>コードスタイルについてはコーディング規約で明確に確定させる</h5>
<p>レビューする際のコードスタイルについてのコメントは時間の無駄です。一貫性のあるスタイルはたしかに重要ですが、コードレビューは波括弧 { をどこに書くかについて言い争う場ではありません。書き方についての議論をレビューから切り離す最善の方法はコーディング規約を最新に保つことです。</p>
<p><img src="https://mtlynch.io/images/human-code-reviews-1/style-argument.png" alt="コードの書き方についてのコメント"></p>
<p>良いコーディング規約は、命名規約や空白のルールのような表面的なことだけでなく、そのプログラミング言語の機能をどのように利用するかについても定義します。例えば、JavaScriptとPerlでは、たくさんの機能が提供されており、同じロジックに複数の実装があります。コーディング規約は、チームの半分がある言語の機能群を使い、残りの半分が違う機能群を使うようにならないようにならないよう、「唯一の正しい方法」を定義します。</p>
<p>一度コーディング規約を決めれば、どの命名規則が最善かについてオーサーと議論し、レビューのサイクルを無駄にする必要がなくなるでしょう。コーディング規約に従うだけで次に進めます。コーディング規約にある問題に対して規定がない場合、一般的にはこれは指摘するに値しません。コーディング規約でカバーしていない問題に直面し、それが議論に値することだとすれば、チームで詳細に議論しましょう。それから、この議論を2度としなくてよいようにコーディング規約に決定したことを追記するのです。</p>
<p><strong>選択肢1: 既存のコーディング規約を採用する</strong></p>
<p>インターネット上を検索すれば採用するのにふさわしい公開されたコーディング規約を見つけることができるでしょう。<a href="https://google.github.io/styleguide/">Googleのコーディング規約</a>が最もよく知られたもので、仮にこれがあなたに合わなければ他の規約を見つけることができるでしょう。既存のコーディング規約を採用することで、1から作成するコストを払うことなくコーディング規約の恩恵にあやかることができます。</p>
<p>否定的側面としては、既存のコーディング規約は彼ら自身の要望に合わせて最適化されていることがあげられます。例えばGoogleのコーディング規約は<a href="https://google.github.io/styleguide/cppguide.html#C++11">新しい言語の機能</a>を利用することには保守的であり、これは彼らが自宅用のルーターから最新のiPhoneまで動作させる必要のある膨大なコードベースを持っているためです。あなたが4人である1つの製品を作り事業を立ち上げているのならば、もっと最新の言語の機能や拡張機能を積極的に利用することを選択することでしょう。</p>
<p><strong>選択肢2: コーディング規約を少しずつ増やしていく</strong></p>
<p>既存のコーディング規約を採用したくなければ、自分で作ればよいでしょう。コードレビューで規約に関する議論が発生した場合、チームとしてどのようにすべきかを決めるためにチーム全体に問いかけましょう。合意したら、コーディング規約に追記しましょう。</p>
<p>私はチームのコーディング規約をMarkdown形式でバージョン管理下に置くのが良いと思っています。(例えば、<a href="https://pages.github.com/">GitHub pages</a>)。そのようにしておけば、コーディング規約のいかなる変更も通常のレビュープロセスを経ることができます。つまり、だれかが変更を明示的に承認する必要があり、チームの全員が意見を述べるチャンスがあります。WikiとGoogle Docsも選択肢としてはよいでしょう。</p>
<p><strong>選択肢3: これらを組み合わせる</strong></p>
<p>選択肢1と選択肢2を組み合わせることで、既存のコーディング規約をベースとし、これを拡張またはオーバーライドするためのチーム固有のコーディング規約を維持できます。<a href="https://chromium.googlesource.com/chromium/src/+/master/styleguide/c++/c++.md">Chromium C++コーディング規約</a>がこれのよい例です。<a href="https://google.github.io/styleguide/cppguide.html">GoogleのC++コーディング規約</a>をベースとして、独自の変更や追加をしています。</p>
<h5>すぐにレビューを始める</h5>
<p>コードレビューを最高優先度にしましょう。時間を取って、コード実際に読んで、フィードバックする際に、レビューをすぐに<em>開始</em>しましょう。理想的には数分以内に、です。</p>
<p><img src="https://mtlynch.io/images/human-code-reviews-1/relay.png" alt="コードの贈り物"></p>
<p>チームメイトが変更リストを提示している場合、あなたのレビューが終わるまで彼らの仕事がブロックされていることがありがちです。理論上は、ソースコードのバージョン管理システムはオーサーが、ブランチを作成することを許容しており、仕事を継続し、レビューに対する変更を彼らのブランチに前方マージします。現実にはこれを効率的にできる開発者はほぼいないのです。レビューが返ってくるまでに待っている間の変更を考慮して3ウェイマージの差分を紐解くのに大多数の開発者に長い時間がかかります。</p>
<p>レビューをすぐに始めれば、好循環を作ることができます。レビューが返るまでの時間が単純にオーサーの変更の複雑さと機能の大きさで決まります。これはオーサーが、小さく、スコープを区切った変更リストを提示する動機付けとなります。これらはあなたがレビューする際により容易になり嬉しいはずで、レビューが高速化し、良いサイクルが継続します。</p>
<p>あなたのチームメイトが1000行のコードの変更を含む新機能を実装したシーンを想像してみてください。もし彼らがあなたは200行の変更リストを2時間でレビューできるとわかっていれば、彼らはおよそ200行毎に変更リストを分割し、全機能を1日か2日でチェックしてもらうことができるでしょう。しかしながら、その変更の規模にかかわらず、全てのコードのレビューに丸1日かかっている場合、その機能をすべてチェックするには1週間かかるでしょう。あなたのチームメイトは1週間にわたって座っていたくないですから、500行から600行といった大きなコードレビューを送る動機が生まれるでしょう。200行の変更より600行の変更のほうが内容を覚えていることが困難になりますので、レビューにより多くのコストがかかる一方でフィードバックの内容が乏しいものになります。</p>
<p>レビューの1ラウンドは最大で1営業日であるべきです。もしより優先度の高い問題に取り組む必要があり、レビューを1日以内に完了できない場合は、チームメイトにこれを知らせ、他のメンバに再アサインできるようにしましょう。レビューを1ヶ月に1度以上辞退せざるをえない場合は、あなたが健全な開発プロセスを維持できるようチームはペースを落とす必要があることを意味します。</p>
<h5>高位のレベルから始め詳細化する</h5>
<p>1回のレビューラウンドで多くのコメントをつければつけるほど、オーサーが困惑するリスクが増します。この上限は開発者によって異なりますが、1回のレビューのラウンドで20から50のコメントがつくと危険ゾーンです。</p>
<p>オーサーがコメントの海に溺れてしまうのが心配であれば、初期のラウンドでは高位のフィードバックを行うように自制しましょう。クラスのインターフェースの再設計や、複雑な関数の分割といった問題に集中しましょう。この問題が解決するまで待ってから、変数名のつけかたや、コードのコメントが明瞭かといった低位の問題に取り組みましょう。</p>
<p>低位のコメントについてはオーサーが高位のコメントを反映すると無意味になります。これの低位のコメントを後のラウンドに遅らせることで、あなたが問題を指摘するために注意深くコメントを記入する馬鹿にならない時間を節約できますし、オーサーが不要なコメントに対応しなくてよいようになります。このテクニックはレビューの最中に抽象レイヤーを分割し、あなたとオーサーが変更リストを明確に、システマチックに処理することに役立ちます。</p>
<h5>コードのサンプルを示して寛大に</h5>
<p>理想的な世界では、コードのオーサーは彼らが受け取る全てのレビューに感謝します。レビューは学びをえる機会であり、誤りを防ぐものです。現実世界では、オーサーがレビューを否定的に認知しコメントを付けたことに腹立たしく思う外的要因がたくさんあります。期限を守るためにプレッシャーを感じており、あなたの即座の、承認の印以外は邪魔だ、と感じるかもしれません。そんなに一緒に仕事をしていないため、あなたのフィードバックが善意であると信じられないかもしれません。</p>
<p>レビューのプロセスの中でオーサーが気持ちよくなるための良い方法は、レビューの最中に彼らに贈り物を送るチャンスを見つけることです。開発者はどのような贈り物を喜んで受け取るでしょうか?もちろん、コードのサンプルです。</p>
<p><img src="https://mtlynch.io/images/human-code-reviews-1/code-gift.png" alt="コードの贈り物"></p>
<p>あなたの考えている変更のいくつかを書きおこしてあげることでオーサーの負荷を軽減すれば、レビュアーとしての寛大さが示せるでしょう。</p>
<p>例えば、同僚にPythonの機能の<a href="http://treyhunner.com/2015/12/python-list-comprehensions-now-in-color/">list内包表記</a>に慣れていない同僚がいたとしましょう。彼らは次のようなコードを提示しています。</p>
<pre><code>urls = []
for path in paths:
url = 'https://'
url += domain
url += path
urls.append(url)
</code></pre>
<p>「リスト内包表記を利用してこれをシンプルにできませんか?」と答えた場合、彼らは今までに経験していないことを調べるのに20分程度調べて時間を使うのに苛立つことでしょう。</p>
<p>次のように書いてあげるとより嬉しくなるでしょう</p>
<blockquote>
<p>次のようにリスト内包表記を利用してシンプル化することを検討してみてください。</p>
<pre><code>urls = ['https://' + domain + path for path in paths]
</code></pre>
</blockquote>
<p>このテクニックはワンライナーに限ったものではありません。私は、大きな関数を分割したり、追加のエッジケースをカバーするための単体テストを追加するなどといったときに、オーサーに大きな概念(proof of concept)を実証するために自分のブランチを作成します。</p>
<p>このテクニックは、明確に、議論の余地がなく改善するものにする必要があります。上記のリスト内包表記の例では、83%のコード削減に反対する技術者はほとんどいません。反対に、自身の好み(例えばスタイルの変更)に基づいて「より良い」長い変更を例示した場合、そのコード例は寛大であるというより押し付けがましいと見えるようになります。</p>
<p>1回のレビューラウンドでは2つか3つのコード例の提示に抑えましょう。オーサーの全ての変更リストに記載を始めた場合は、彼らがコードをかく能力がないと考えていることを示します。</p>
<h5>相手に直接言及しない(Never say "you")</h5>
<p>これは奇妙に聞こえるかもしれませんが、ちょっとよく聞いてください。コードレビューで「あなた」という言葉を使ってはなりません。</p>
<p>レビューで至った決断については、誰がそのアイデアを考えついたかではなく、どうしたらコードが良くなるか、に基づくべきです。チームメイトは変更リストに膨大な時間をかけ、やったことに誇りを持っています。彼らの成果に対する批評に対しては防衛的になるのが自然な反応でしょう。</p>
<p>チームメイトが身構えるリスクを最小化するようにフィードバックの言葉を選びましょう。コードを書いている人間を批評しているのではなく、コードを批評していることを明確にしましょう。「あなた(You)」という言葉がコメントにあると、これはフォーカスがコードではなく彼ら自身に移ってしまいます。これは彼らが批評を個人的なものであると捉えるリスクを増しています。</p>
<p>次のような害のないコメントについて考えてみましょう。</p>
<blockquote>
<p>You misspelled ‘successfully.’</p>
<p>('successfully'の綴りが誤っています)</p>
</blockquote>
<p>オーサーは2つの違った解釈をしえます。</p>
<ul>
<li><strong>解釈1</strong>: Hey、相棒よ!君は「successfully」のスペルを間違えてました。あなたは賢明だと思ってますよ!おそらく単なるtypoでしょう。</li>
<li><strong>解釈2</strong>: 君は「successfully」のスペルを間違えてました。大ばかもの。</li>
</ul>
<p>「あなた(you)」を削除してみましょう</p>
<blockquote>
<p>sucessfully -> successfully</p>
</blockquote>
<p>後者のコメントは単なる修正でオーサーの評価ではありません。
幸い、「あなた」という言葉を使わずにフィードバックを簡単に書き換えられます。</p>
<p><strong>選択肢1: 「あなた(you)」を「我々(we)」に置き換える</strong></p>
<blockquote>
<p>Can <strong>you</strong> rename this variable to something more descriptive, like <code>seconds_remaining</code>?</p>
<p>(この変数をもっとわかりやすく例えばseconds_remainingに変えられる?)</p>
</blockquote>
<p>これは</p>
<blockquote>
<p>Can <strong>we</strong> rename this variable to something more descriptive, like <code>seconds_remaining</code>?</p>
<p>(変数名をもっと分かりやすくなるように<code>seconds_remaining</code>としてはいかがでしょうか?)</p>
</blockquote>
<p>「我々(we)」という言葉はコードに対するチームの共同体としての責任であることを強調します。オーサーは別の会社に移動するかもしれませんし、あなたがそうなるかもしれません、しかし、このコードを持つチームはある形を維持するわけです。オーサーにしてほしいことを「我々は」と言うのは馬鹿馬鹿しいようにもみえますが、非難となるよりはましです。</p>
<p><img src="https://mtlynch.io/images/human-code-reviews-1/move-couch.png" alt="ソファーを動かす"></p>
<p><strong>選択肢2: 文から主語を取り除く</strong></p>
<p>「あなた」を使わないようにするその他の方法として、文から主語を省略する方法があります。</p>
<blockquote>
<p><code>seconds_remaining</code>といったように、もう少しわかりすくことをおすすめします。</p>
</blockquote>
<p>受動態を使うことによって同様の効果をえられます。私は技術文書で受動態を利用するのは一般的には避けるようにしてますが、「あなた」の周りに利用するのは有用です。</p>
<blockquote>
<p><code>seconds_remaining</code>といったように、もう少しわかりやすいように変数は名称を変更されるべきです。</p>
</blockquote>
<p>「〜はどうでしょう?」といった疑問形式にしてみる選択肢もあります。</p>
<blockquote>
<p><code>seconds_remaining</code>とうようにもう少しわかりやすい変数名としてはどうでしょうか?</p>
</blockquote>
<h5>フィードバックする際に命令するのではなく、お願いする</h5>
<p>コードレビューは、ディスカッションが個人への言及に脱線するリスクが高く、通常のコミュニケーションより気配りと配慮が必要です。レビュアーはレビューの際に丁寧であることを期待しますが、突飛なことで変な方向に向かってしまうことがあります。多くの人々は、同じ職場の人に、「そのホッチキスをとって、それからソーダを取ってきてください」とは決して言いません。しかし多くのレビュアーが「このクラスを他のファイルに移動してください」といった厚かましい言い方をしているのをみてきました。</p>
<p>フィードバックの際にはしつこいくらい丁寧にしましょう。コメントする際に命令するのではなく、お願いする、あるいはおすすめしてみてください。</p>
<p>次の2つのコメントを比べてみてください。</p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th style="text-align: left">命令形でフィードバックする</th>
<th style="text-align: left">お願いとしてフィードバックする</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: left"><code>Foo</code>クラスを別のファイルに移動してください</td>
<td style="text-align: left"><code>Foo</code>クラスを別のファイルに移動してはどうでしょうか?</td>
</tr>
</tbody>
</table>
<p>人は自分でコントロールできている状態を好みます。オーサーにお願いをすると自主性を持った感覚になります。</p>
<p>お願いはオーサーを礼儀正しい状態に戻しやすくなります。おそらく彼らは適切な判断をするでしょう。命令形でフィードバックすると、オーサーからの意見は反発しているように受け取られます。もしお願いあるいは疑問形式でフィードバックすれば、オーサーは単に答えれば良いことになります。</p>
<p>レビュアーが最初のコメントをどのようにつけるかによって、どんなに議論が喧嘩腰に見えるかを比べてみましょう。</p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th style="text-align: left">命令形でフィードバックする (喧嘩腰)</th>
<th style="text-align: left">お願いとしてフィードバックする (協力的)</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: left"><strong>レビュアー</strong>: <code>Foo</code>クラスを別のファイルに移動してください。</td>
<td style="text-align: left"><strong>レビュアー</strong>: <code>Foo</code>クラスを別のファイルに移動してはどうでしょうか?</td>
</tr>
<tr>
<td style="text-align: left"><strong>オーサー</strong>: <code>Bar</code>クラスと遠いため移動したくありません。 顧客はほとんどのケースで2つを一緒に利用するでしょう。</td>
<td style="text-align: left"><strong>オーサー</strong>: そのようにはできますが、<code>Bar</code>クラスとは遠い位置にあり顧客は概ね2つのクラスを一緒に使います。いかがでしょうか?</td>
</tr>
</tbody>
</table>
<p>命令する代わりにお願いする形でコメントすることで、どれだけやりとりに棘がなくなったかをご覧ください。</p>
<h5>意見ではなく原則に基づいてコメントをする</h5>
<p>オーサーにコメントを行う場合は、どのような変更が必要か、と変更の<em>理由</em>の両者を説明する必要があります。「このクラスを2つに分割してください」というのではなく、「現在のところ、このクラスはファイルのダウンロードとパースの両方の役割を担っています。これは<a href="https://en.wikipedia.org/wiki/Single_responsibility_principle">単一責任の原則</a>に基づいてダウンローダークラスとパーシングクラスに分割すべきです」という方が良いでしょう。</p>
<p>コメントをある原則に基づいて実施すると議論が建設的に進みます。次のような理由を引用した場合「クラスのpublicインターフェースを最小化するために関数をprivateにするべきです」、オーサーは単に「いいえ、私は私のやり方のほうが好みです」と答えることができません。実際には<em>答えられます</em>が、あなたが変更のゴールを述べているのに、好みについて述べたら馬鹿みたいに見えるでしょう。</p>
<p>ソフトウェア開発は芸術であり科学です。あなたは常に確立された原則に基づいて何が良くないかはっきりと正確に示せるわけではありません。コードが汚かったり直感的でなかったりするだけのこともありますし、これはなぜかを突き止めるのは困難です。このような場合には、客観性を保ち、あなたは何ができてるかを説明してみてください。「これは私には理解できません」というのは「これは混乱を招きます」という全ての人間に当てはまるかわからないものであるのに対し、少なくとも客観的な発言です。</p>
<p>リンクで論拠が補える場合は合わせて記載しましょう。チームのコーディング規約の該当の節へのリンクが一番実践しやすいものです。言語やライブラリのドキュメントへのリンクも利用できます。投票数の多い<a href="https://stackoverflow.com/">StackOverflow</a>の回答も有効ですが、権威あるドキュメントから離れれば離れるほど、エビデンスの信頼性は低くなります。</p>
<h4>パート2: �もうすぐです.</h4>
<p>2, 3週間以内に残りの半分の記事を公開する予定です。次のポイントを含む記事をお見逃しなく。</p>
<ul>
<li>あまりに大きなコードレビューに対応する</li>
<li>賞賛をつけるポイント</li>
<li>コードレビューのスコープに気をつける</li>
<li>行き詰った状態を和らげる方法</li>
</ul>
<p>編集: <a href="https://www.upwork.com/fl/samanthamason">Samantha Mason</a>、イラスト: <a href="https://www.linkedin.com/in/lolo-ology/">Loraine Yow</a>。この投稿の初期の頃から貴重なフィードバックをくれた <a href="https://twitter.com/global4g">@global4g</a>に感謝します。</p>
taka-h
https://yakst.com/ja/posts/4668
2017-08-09T10:59:02+09:00
2017-08-09T10:59:02+09:00
超高速な開発ができるわけ
<p>ある状況下において、特定の開発者たちが他の人の10倍生産性が高くなることがあるのはなぜかについて議論してみましょう。</p>
<p>ヒント : 開発者の話ではなく、状況が大きなカギ。</p>
<p>生産性が非常に高いことにウキウキした気分になるのはいつでしょうか。新しい機能が指先からあふれ出てくる時?それは、私たちが関わるツールのことを知り尽くしている時、あるいはもっと決定的に言うと、自分がシステムを変更しつつある時に起こるのです。自分のバックパック、それも自分で詰め込み、そしてひとつひとつの小袋の中まで何年にもわたる旅行を経て調整してきたバックパックの中身を知っているように、システムを知ることです。それぞれのモジュールの中身、それもそれがどんなもので、リファクタリング完了後にどうあって欲しいのか知ることです。システムの端っこまで知ること、つまり誰がそれぞれのAPIを使っているのか、どんな変更が誰に影響するのか。そしてあらゆる利害関係者と友達になるのです。基礎部分を知ること、つまりデータベースのどの列にインデックスがあるのか、何がもう使われていないのか、特別な扱いを要する値はどれか。インフラを知ること、つまり本番環境はどこで動いているのか、どうやってSSHしてそこに入るのか、テスト環境はどこで動いているのか、どのバージョンがデプロイされているのか、どんな時なら新しいものをプッシュしても安全なのか。出力を知ること、つまりログの何が正常を表していて、何が問題の手がかりなのか。私たちは、3台の本番インスタンス全部からログをtailしてきてターミナルに表示するワンライナースクリプトを作ったので、異常を発見することができます。</p>
<p>私たちはそれを知っています。なぜなら普通は自分たちでそれを書いたからです。すでにそこにあったシステムに対してこのような深い知識のレベルまで持つのは至難の技です。<a href="https://mitpress.mit.edu/books/vehicles">Braitenberg</a>はこれを、「下りの発明、登りの分析の法則(Law of Downhill Invention, Uphill Analysis)」と呼んでいます。複雑なシステムは、動き始めた後にそれを解明するよりも、作る方が簡単であるということを表しています。</p>
<p>私たちがそれを知っているのは、私たちがそれを変更しているから。システムは私たちの頭の中で生きているのです。これは共生関係のようなものです。システムが動き続け成長するのを私たちが手助けし、システムは私たちの望むように動いてくれる。1ヶ月か2ヶ月そこから離れて他のシステムとの関係を始めると、この魔法は失われてしまい、また親密さを取り戻すまでに時間がかかります。</p>
<p>ただし、私はここの記述に疑問があります。「私たち」は複数形です。このレベルのシステムとの親密さや快適さは、個人的なもの、つまり通常ひとりしかそういう人はいないのです。その人とは、解決策を考え出した人であり、現在の状態と今後の行き先の両方を頭に入れている人なのです。</p>
<p>もしあなたがそんな人なら、 <em>あなたがやっているような仕事ができる人は誰もいない</em> ということに気づいてください。他の人にとっては、何が起こるかわからないのであらゆる変更を加えるのが怖いのです。彼らは、それぞれの部分がどのように動くのか時間をかけて理解していき、それから経験を通じて確認するのに大変です。あなたがやったようにテストできるわけではないのです。彼らは、関係なさそうなログをざっと見たり、あなたがもう見もせずにスキップしてしまうようなログメッセージをひとつひとつ確認しています。時間が経って彼らが理解し始めた頃には、もうあなたは変更を加えてしまっています。彼らには、あなたが変更を加えるのと同じスピードでシステムの理解度を上げることはできないのです。彼らがシステムに変更を加える時には、何がどのような問題を引き起こすのかをよく知らないので、その変更の影響範囲を小さくするのに長い時間をかける必要があります。もしそれが失敗したなら、それは彼らがユーザーを知らないせいです。コミュニケーションは難しいのです。</p>
<p>もしあなたがそんな人なら、他の人にやさしくしてあげてください。あなたは合成化学者でDNAを内部から変えることができるのに、彼らは外科医であり皮膚に切り込みを入れて触ったこともない臓器を傷つけないように手術する必要があると考えればよいのです。</p>
<p>もしあなたがそんな人と仕事をすることになったら、残念なことです。それは大変なポジションで、常に劣等感を持ち、触るものすべてを壊しているかのような気分になるでしょう。私は、システムのある部分に関しては、今そんなところにいます。そのソフトウェアの作者であり操作者でもある共同作業者は、とてもいい人で協力的です。彼は、彼がやるのと同じような方法で仕事することを私に期待してきたりはしません。</p>
<p>もしあなたのチームがそんな風になったら、以下のステップをたどってみましょう。</p>
<ol>
<li>まず、(今のやり方自体は)変えないことです。これはソフトウェアを最も高速に開発する方法です。システムが一定規模より小さいなら、他の開発者と調整する必要がない開発者1人は、チームでやるよりもずっと素早く動けます。ただしこれは、システムをより大きくしようと考え始めるまでのことです!あるいは、そのシステムがビジネスに不可欠なものになる前までです!(たったひとりの人間だけがそういったシステムに対する権限を持っているのは許容できないリスクです)</li>
<li>あなたがそのシステムに熱中しているその人なら、「〜なだけ(just)」「簡単(easy)」「明白(obvious)」「単に(simple)」「分かりやすい(straightforward)」といった単語は辞書から消してしまいましょう。これらの単語には背景が必要で、その背景を理解している人などいないのです。</li>
<li>テストを書いてください。テストは、意図せず何かを壊してしまうことを恐れている人が、今からやろうとしていることを試す方法です。システムがどう動くかを学習するのに、実験してみるのはとても重要なことです。そしてテストはそういった実験を可能にしてくれます。またテストは、意図する動作とは何なのかを示すドキュメントとしても役に立ちます。</li>
<li>ペアプログラミングしましょう!システムに関する理解を他の人に教えるのに間違いなく一番いいのは、一緒にそのシステムを変更することです(あるいはチームみんなで一斉にプログラムに取り付いてみましょう!)。</li>
<li>他の開発者のためにREADMEを書きましょう。システムの目的を簡単に書き、どのように開発するか、どのようにテストするか、どのようにトラブルシューティングするかを書きましょう。テストを実行するコマンド、デプロイするコマンド、ログにアクセスするコマンドを書きましょう。必要なパスワードを知る方法を詳しく書きましょう。システムが動く全ての環境を書き、その環境を変更する方法を書きましょう。</li>
<li>ユーザーのことを誰よりも知っているのはあなたですか?それは改めましょう。他のチームメンバーを議論に参加させましょう(あるビジネスユニット内で開発者ひとりで仕事ができてしまう<a href="http://blog.jessitron.com/2014/08/the-power-of-embedded-developers.html">スイートスポット</a>が存在します。しかしソフトウェアがこのスケールに対しては重要すぎる存在になった時には、難しくなってきます)。全ての開発者がユーザーのことを知れるようにしましょう。ハッピーアワーもやりましょう。コミュニケーションチャネルを複数持ちましょう。あなたが知り得なかった形で効果があるはずです。</li>
<li>スピードを落としましょう。実際、プロジェクトであるひとりが全速力で開発していたら、それについていける人などいません。最高速で開発しつつ共同作業者を追加するのは無理です。誰か新しい人を連れてくるのが重要なら、ひとりでやってしまっていいことは何もないと考えましょう。なんでもペアリングしましょう。そう、そうすればあなたのスピードは落ちます。一方で、彼らのスピードを上げます。それでもあなたがひとりで作業するよりも全体としては遅いでしょう。これは、人間同士の調整が必要になる大規模なシステム特有の性質です。あなたとあなたのプログラムのことだけ考えればいい時よりもずっとオーバーヘッドがあるのです。でもそれでOKです。高速さから、安全とスケールを得るためのトレードオフです。</li>
</ol>
<p>他の人の10倍の生産性で動ける開発者と状況の組み合わせが本当にあり得るということを知っておきましょう。そしてそういう状況はスケールしないということを知っておきましょう。ローカルあるいは個別の自動化のスイートスポットの恩恵に預かれるのはいつなのか、<a href="https://en.wikipedia.org/wiki/Bus_factor">バス係数</a>(訳注 : 何人が「突然」いなくなってもプロジェクトが回るか)が1であるには重要すぎるシステムを作っているのはいつなのかの判断をしましょう。</p>
<p>変更スピードと素早い進路変更が重要な実験的プロトタイプと、後方互換性を保証することとドキュメントとそういったあらゆる深刻さが要求される本番アプリケーションとを区別しましょう。後者には、しっかりしたチームが必要です。</p>
<p>最も生産性高く開発できるのは珍しい場面であることを認識しましょう。多くの場合、既に誰かが書いたシステムを触る必要があります(「誰か」は「数ヶ月あるいは数年前の自分」の可能性もあります)。書き換えてしまえば理解できるので、書き換えたくなる衝動は大きいでしょう。</p>
<p>つまりは、10倍の生産性で開発するべき時と、チーム開発すべき時があるということです。真剣に開発したい時には、10倍の生産性で開発する開発者は邪魔になります。そういった時には、この記事に書かれた提案のことを考えてみてください。</p>
doublemarket
https://yakst.com/ja/posts/3594
2015-12-24T07:54:59+09:00
2017-06-18T21:02:18+09:00
こんなコーディングは退屈だ!
<p>開発者として、私は2年以上同じ仕事を続けた事がありません。</p>
<p>転職することは私にとって良いキャリアとなりました。私達の業界では転職を繰り返す事はごく一般的なことです。ところが、以前私が働いていた会社は、私の離職に難色をしめしました。中には、私を必死で引きとめようとする人もいました。しかし、私は仕事に飽きてしまっていたため、残ることはできませんでした。</p>
<p>(免責事項:私は多くのプログラマーよりも楽しいプログラミングの仕事をしていたと思います。仕事を変えることが常に最善の選択とは限りません。)</p>
<p>現在私は<a href="https://enki.com/" title="Enki">Enki</a>のco-founderで最高技術責任者(CTO)です。会社ではエンジニア文化の構築も行っています。つまり過去に私が陥ったように、エンジニアが仕事に飽きないようにする事も重要な仕事の一つなのです。</p>
<p>私たちは、チームの力を借りながらこの問題に対する対策を会社に打ってきましたので、その取組を共有したいと思います。</p>
<p>幸いなことにもEnkiは日々困難な問題にとりくんでいます。たくさんの実装したいコードと解決しなければならないパズルのような課題が十分にあります。つまり飽きるという事が緊急の課題になることは今はありません。しかし、最初からそうだったわけではありません。しかも、退屈というのは時間とともに蝕んでいき、最悪のタイミングであなたを襲います。</p>
<p>だから我々は早期に退屈しない文化づくりに取り組むようにしているのです。</p>
<p><img src="https://cdn-images-1.medium.com/max/1600/1*K2p_b1b8SMemFpxqtdLwug.jpeg" alt="image1"></p>
<h4>長過ぎ。学ぶものがもう無い。</h4>
<p>エンジニアが一番退屈するのは、長期間同じプロジェクトにいることです。</p>
<p>初めてついた仕事がまさにこれでした。私が入ったチームでは金融データを整形し、配信するAPIを作る仕事をしていました。データのスケールは大きく複雑でとてもエキサイティングでした。私は高性能なデータ分析APIの設計の技術を学びました。しかし、一年後も同じようなデータセットで同じような技術を使って仕事をしていたのです。まるで何かすごく限られた分野の専門家になったようでした。もう学ぶものが無くなってしまったのです。</p>
<p>長くいてしまったこともあり、私はチームにとって重要な人物になってしまいました。会社は私を他のチームやプロジェクトに移ることを許してくれなくなってしまったのです。世の中のデータやテクノロジーが速いスピードで進化している事は私も知っていました。私は会社に不満と飽きを表明しましたが受け入れてもらえなかったので、転職するしか無くなったのです。</p>
<h5>退屈の種を紡ぐことはできるのか</h5>
<p>我々は同じコードや同じ製品やデータセットを3ヶ月以上同じ人がさわり続け無いようにしています。これはちょっとやりすぎで、もしかすると大きな企業においては難しいかもしれません。しかし我々は速いスピードでローテーションすることの効果を信じています。</p>
<p>これを実現するために、我々はフルスタックの文化を促進しています。弊社のエンジニアはコードのどの部分でもいじることができます(もしくは迅速に学ぶことができます)。</p>
<p>そしてもう一つの要因が、この問題に対して常に議論する点です。私たちは毎週、一対一で直接話し合う機会を設けています。<strong>もしエンジニアが仕事が簡単すぎると感じていたり、もしくは専門的過ぎると感じていたら、それがプロジェクトをローテーションするタイミングなのです。</strong></p>
<h4>レガシーコードは触りたくない</h4>
<p>バグ修正の時間が90%を超え始めると、公式に宣言しているかは別として、そのプロジェクトはメンテナンスモードに入ったと言えるでしょう。
メンテナンスを避ける事は出来ないという意見もあります。古いコードにはサポートが必要だと。ソフトウエア開発は家を建てるのと似ている。時とともに古い家はメンテナンスして改装していく必要があるという意見です。
この意見はYESであり、NOです。大事なのは態度なのです。</p>
<p>私はかつてこの問題に対してシニカルなメンターがいました。彼は何もできる事は無いと、これがソフトウエア開発なんだと言いました。人生なんてそんなもんさ、慣れるしかないよと。
本当にどうにもならないのでしょうか?</p>
<p>メンテナンスモードは低い技術力と勇気のない決断が原因になる事が多いです。
複雑な依存関係を持つ巨大でモノリシックなコードはメンテナンスコストを増大させます。これとは対照的に良く設計されたマイクロサービスはもう少し柔軟です。マイクロサービスに障害が発生した場合、対象部分を交換する事が出来ます。新しい言語や技術を使ってスクラッチで書き直すことも出来ます。この方法なら新しい学びを得ることができるでしょう。そしてもし、現在の設計がそうなっていないなら、少しづつ設計を変えていく事でDevopsのスキルを身に着ける事もできるでしょう。</p>
<p>マイクロサービス戦略はエンジニアの「飽き」に対処できる唯一の方法です。賢いビルドツールを作ることで効率的で楽しくメンテナンスしようと試みている所もあります。例えば大量のPHPのコードを抱えるFacebookです。かれらはPHP上に独自の片付け言語を構築しそのコンパイラを作ることでメンテナンス効率を上げ、また技術的なやりがいを作りました。私はこれが本質的な問題を解決したとは思いませんが、仕事をより楽しい物にしたことは確かだと思います。</p>
<h4>コピペは退屈</h4>
<p>それはコーディングで、そしてこれもコーディングなのだが。。。</p>
<p>私は過去に実りの無いコードを書いていた時期もありました。例えば、データを統合させるためにGroovyやPythonのスクリプトを書いていました。データは複雑で、数十の一貫性の無いスキーマで構成され、自動化する事は出来ませんでした。沢山のコードを書く必要があったので、社内では私が沢山の学びを得ていると思われていました。</p>
<p>しかし現実は違いました。</p>
<p>コードの50%はStack Overflowからのコピペ。残りの40%はその他のソースからのコピペ。自分で書いたコードや同僚が書いたものからでした。
それの繰り返し。
ほんの少しの創造性と学びしか無かったのです。</p>
<p>我々はこの問題にどのように対処すれば良いのでしょうか?</p>
<p>他のチームメンバーが書いたコードを見る事が大切です。我々はこれをコードレビューと振返りを行う事で解決しています。もしも誰かが非クリエイティブなコードを一週間書いていたら、なぜそのような事になったのかを考えるようにしています。</p>
<p><img src="https://cdn-images-1.medium.com/max/1600/1*h4Z7DjCx4TfDnJw7_HEarA.jpeg" alt="image2"></p>
<p>時に、根底に技術的な問題が潜んでいる場合もあります。ちょっとした設定ファイルとスクリプトで解決できるかもしれません。自動化処理を追加する事で解決する事もあります。もちろんコピペをしなければならない状況もあるでしょう。そのような退屈な作業をしっかりと仲間で共有する事が大事なのです。</p>
<h4>社内ツールはだいたいつまらない</h4>
<p>我々は特別な課題を解決するためについつい社内ツールを作ってしまいがちです。新しいモノを作るのは楽しいですからね。それにきっちりカスタマイズされた製品のほうが既存の製品を組み合わせて使うより美しく見えてしまいます。しかしそのような独自のツールを学ぶことはオープンソースの技術を学ぶ事の10倍つまらないです。</p>
<p>なぜか?</p>
<p>それは、そのテクノロジーに関して友人に話すことができないからです。自慢もできません。Hacker Newsでそれに関して言及されることもありません。ハッカソンで使うこともできないし、家で作ってる秘密のプロジェクトで使うこともできないのです。</p>
<p>しかし、多くの企業はこの退屈で価値の無い物を作る罠にハマります。言い換えるなら、短期的なフラストレーションの解決をし、長期的なフラストレーションを産んでいるのです。</p>
<p>実際、以前の職場で直接経験しました。私は、大規模なデータ統合のために、その会社が独自で作っているDSLを使う事を強要されたのです。それはSQLの独自拡張のような言語でした。私にとってはSparkのようなオープンソースを学ぶ方がよっぽど良かったでしょう。もしそれなら私は10倍仕事に従事したでしょうし、コードは2倍冗長になってしまうかもしれないが、生産性は5倍になっていたでしょう。(数字は正確ではないかもしれないが、何が言いたいか、わかりますよね?)</p>
<p>どのような文化を形成すればこのようなことが防げるでしょう?</p>
<p>我々はオープンソースに強いバイアスをかけるようにしています。もし何か面白そうで利用できそうなものがあったら、我々は使います。最先端の技術を積極的に使うようにしています。我々のカスタムしたコードを置き換えることが可能なオープンソースが出てきた場合、すぐにオープンソースに置き換えます。また我々が作ったカスタムコードが十分にジェネリックなものになったら、オープンソースとして公開します。</p>
<p>もちろん失敗する時もあります。例えば、agenda.jsというバックエンドのジョブスケジュールを行うライブラリがモダンで面白そうに感じたので導入したことがあります。しかし作りがすごく複雑になってしまったので、古いツールに戻しました。より信頼性の高いツール(古き良きcron)に。しかし、貴重な学習体験になったので、我々は後悔していません。</p>
<h4>コードモンキーにはなりたくない</h4>
<p>ダメなマネジメントも、エンジニアを飽きさせる要因の一つでしょう。もう少し具体的に言うと、トップダウンで独裁的なマネジメントです。</p>
<p>優秀なマネージャーの場合、エンジニアに不満を抱かせずにそのようなスタイルの経営を実行する場合があります。特にプロジェクトが上手く回っていない時、もしくは納期間近の場合にうまくいきます。強いプレッシャーを受けている場合は、短い議論をカットし、ブレストの時間を減らし、ディベートや説明無しに何をやるべきかだけを伝えることは自然です。ただ時間を節約し、目的を達成するために。</p>
<p>理解力のあるマネージャーの場合、このぐらいはこなすでしょう。実際に一部の人々は(時々)シンプルに何をやるべきかを伝えられたほうが嬉しいでしょう。もちろんその内容が正しいと思っていると仮定してですが。</p>
<p>しかし、ここには隠れたコストがあります。</p>
<p>はじめから何を作るかを正確に知っている状態は、知的でクリエイティブな作業を、機械的な作業に変えてしまうという事です。つまり言われたものを作るだけのコードモンキーになるということなのです。</p>
<p>重要なのは、エンジニア自身が「理由」を知ることです。もちろんこれも極端なケースでワークさせるハックか、一時凌ぎの対策でしかありません。しかし、エンジニアが重要な意思決定やその背景にある理由を気にしなくなった時は、それは転職の準備が整ったという事です。</p>
<p>どうしたらこれを防げるのでしょうか?</p>
<p>最も大事なのはオープンな議論を推奨するカルチャーです。我々が定期的に開催しているフォーラムでは、チームが何をしていくかの戦略を議論しています。そしてこのカルチャーを維持するためには、チーム全員がこのカルチャーの維持を意識する事が大事です。</p>
<p>もし大変な時期(もしくは納期間近)の時は、メンティーは話したがっています。メンターは注意深く、その意見に耳を傾ける必要があります。</p>
<h3>日常はいつだって退屈</h3>
<p>大事なことを言い忘れてました。閉じられた環境でのルーチンワークが面白さを殺すという事です。</p>
<p>これはエンジニアやIT企業に限られた話ではありません。様々なバックオフィスの仕事にも言えることです。毎日同じ部屋、同じメンバー、同じ文化で同じ仕事… それは成長が速い環境で、これらの事が客観的に良さそうに見える場合でも、人々は良い部分を権利と感じ、悪い部分にフラストレーションを感じて行くのです。</p>
<p>どのようにこの問題に向き合えば良いのでしょう?</p>
<p>ここで重要となる成分に多様性があります(例えば我々のチームのうち6人はイギリス、フランス、ロシア、ギリシャの人です)。毎日同じメンバーを見る事も、それぞれが異なる文化を持ち込むと、より面白くなります。</p>
<p>また、我々は外の世界に出て行く機会も頻繁に作っています。</p>
<p>例えば、私たちはミートアップイベントやハッカソンに共に出かけます。またサイドプロジェクトを持ちオープンソースのツールに貢献しています。またテクニカルな仕事以外(雇用、マーケティング、流通など)も手伝います。これらの仕事に長けているわけではなく、変化を起こすためにやるのです。</p>
<p><img src="https://cdn-images-1.medium.com/max/2000/1*uwMg5NxWGGnx1MThcJjneg.jpeg" alt="image3"></p>
<p>また業務外で「どっきり映画鑑賞会」のような企画を組んだり、毎週アジェンダのない「enkithon」(訳注:enki社のハッカソンの意だと思われる)というものを開催しています。そこで時に何かをhackしたり、新しいアイデアをブレストしたり、League of Legendsをプレイするだけの時もあります。それか飲みに行くか。これの良さは、我々がみんなで決めるまで何も決まってないという事です。</p>
<p>このちょっとしたカオスが退屈に対するレシピの成分となります。そして、これらのどのレシピも、完璧になることはありません。何度も何度も微調整し、材料を調整することが大事なのです。</p>
wataru420
https://yakst.com/ja/posts/3576
2015-12-03T09:55:50+09:00
2017-06-18T21:02:18+09:00
プログラマにとっての悪夢とは?
<ul>
<li><p>本番だけでバグが発生し、ローカルでは再現できないか発現しない。</p></li>
<li><p>バグの発生確率が低いが、無視できるほどではない。</p></li>
<li><p>バグの原因が、高負荷時にのみ起こる競合状態に影響される。</p></li>
<li><p>バグの原因がわからない。</p></li>
<li><p>バグの原因になるコードを書いたのは自分ではないが、修正する責任がある立場にいる。コードを書いた人間は退職して会社にいない。</p></li>
<li><p>バグの原因となる問題が、99.9%の信頼性を持つどこかのライブラリーで、それだけに最後に確認するところだった。</p></li>
<li><p>多数の人間がデバッグしようと何年も頑張ったが、誰も成功しなかった。</p></li>
<li><p>何年にもわたって実行した後にのみ起こる論理的エラー。</p></li>
<li><p>デバッグには自分の何も知らない分野での経験が必要。</p></li>
<li><p>バグの修正のスケジュールに余裕がない。</p></li>
<li><p>自分の首がかかっているのでバグを無視できない。</p></li>
<li><p>Stack Overflowがダウンしている!</p></li>
<li><p>Stack Overflowに行って自分が答えが欲しいと思っているのと全く同じ質問を発見。1年前に質問が投稿され、いまだに答えが付いていない。(<a href="http://xkcd.com/979/">xkcd: Wisdom of the Ancients</a>)</p></li>
<li><p>セミコロンキーが壊れている。</p></li>
<li><p>見事にうまくいってるプロジェクトでコメントされていないコードを1年後に発見し、修正しながら叫ぶ。「俺はいったいなんでこんなことしたんだ?」「本当にこのコード書いたの俺かよ?」自分の家の中で迷子になった気分。</p></li>
<li><p>ドキュメントのないライブラリー。</p></li>
<li><p>要求仕様変更、再び。</p></li>
<li><p><code>==</code>の代わりに<code>=</code>を使ってしまう。</p></li>
<li><p>うぬぼれ。準備不足。見積が甘い。共感ではなく怒り。</p></li>
<li><p>Stack Overflowの質問数の限界に達する。</p></li>
<li><p>Internet Explorer (Web開発者の場合)</p></li>
<li><p>GitHubのマージがコンフリクトする。</p></li>
<li><p>意図したのと違うディレクトリで<code>rm -rf *</code>をタイプしてしまう。THE END. :(</p></li>
<li><p>「このコードは動くよ。なんでか知らんけど」</p></li>
<li><p>コミュニケーション不足 : プログラマーは自分が何を作っているか、それがどう使われるかを理解するべき。コンテキストを作る必要がある。これは、何かを作る場合には判断を下す必要のある時が100は存在するから。コンテキストを理解していれば判断が下せる。</p></li>
<li><p>コミュニケーションの取り過ぎ : 会議、会議、会議...会議はプログラマーを殺してしまう。</p></li>
<li><p>何かを明確にするのに1日かかる。「クライアント」が違うタイムゾーンにいるなど。</p></li>
<li><p>ドキュメントがないか、さらに悪いのはドキュメントが使い物にならない(例、明白なことが書いてある、コードについて記述がない)</p></li>
<li><p>インデントがぐちゃぐちゃで、合理的でない構造なのでデバッグができない。</p></li>
</ul>
doublemarket
https://yakst.com/ja/posts/3420
2015-10-30T09:33:01+09:00
2017-06-18T21:02:18+09:00
オブジェクト指向プログラミングとは? : スティーブ・ジョブズの答え
<p>オブジェクト指向プログラミングに関するいい説明にはなかなか出会えていませんでした。正式なエンジニアリングの教育を受けたわけではないけれど、いつも技術やデザイン、芸術といったやることすべてに明確なアイディアを持って説明する、ある人の言うことを聞くまでは。</p>
<p>ここに挙げるのは1994年の「ローリングストーン」のインタビューの引用で、スティーブ・ジョブスがオブジェクト指向プログラミングとは何かを説明しているものです。</p>
<hr>
<p><strong>Jeff Goodell</strong> : そもそもオブジェクト指向ソフトウェアとは何か、簡単な用語で説明していただけますか?</p>
<p><strong>Steve Jobs</strong> : オブジェクトとは人間のようなものだ。生きていて、何をどうすべきかという知識を自分の中に取り込み、物事を覚えていられるようにメモリーを持っている。非常に低いレベルの抽象度で彼らとやりとりをするというよりは、僕たちが今ここで話しているように、非常に高い抽象性を持って交流するものだ。</p>
<p>例えばこんなことだ。もし僕が君の洗濯屋(laundry)オブジェクトだとすると、君は僕に汚れ物を渡し、「服を洗濯してくれ」とメッセージを送ることができる。たまたまサンフランシスコで一番いいクリーニング屋がどこかを僕は知っている。僕は英語をしゃべり、ポケットにはお金も入っている。僕はタクシーを拾い、運転手にサンフランシスコのその場所へ行ってくれと伝える。服が洗濯されたらタクシーに飛び乗り、ここに戻って来る。きれいになった服を君に渡して「こちらが洗濯済みの服です」と僕は言う。どうやって僕が洗濯したかは君はわからない。クリーニング屋の場所もわからない。もしかしたら君はフランス語しかしゃべれなくて、タクシーを捕まえることもできないかもしれない。ポケットにはドルが入ってなくて代金を払えないかもしれない。一方で僕はやり方を全部知っている。君はそのやり方を知る必要はないんだ。すべての複雑なことは僕の中に隠されていて、僕たちは非常に高い抽象度でやりとりができる。これがオブジェクトが何かということだ。複雑さをカプセル化し、その複雑な部分とのインターフェースは高レベルなものなんだ。</p>
doublemarket
https://yakst.com/ja/posts/1569
2015-01-13T00:42:00+09:00
2017-06-18T21:02:17+09:00
バグを増やさないためにコードレビューのチェックリストを使う
<p>効果的な<a href="http://blog.fogcreek.com/effective-code-reviews-9-tips-from-a-converted-skeptic">コードレビュー</a>について書いた我々のブログ記事の中で、チェックリストを使う事を推奨した。チェックリストを使う事で、レビューが継続的にチーム全体でうまくはたらくようにできる。また、ありがちな問題を見つけたり解決したりするのを確実にする、簡単な方法でもある。</p>
<p>ソフトウェア工学研究所の研究によると、プログラマは15から20の良くある間違いをしてしまいがちだという。そういった間違いをチェックリストに追加しておく事で、問題が起こった時にそれを特定し、確実に駆逐するようにできる。</p>
<p>チェックリスト作りに取り掛かるに当たって、一般的な項目は以下のリストのようになるだろう。</p>
<h3>コードレビューチェックリスト</h3>
<h4>一般</h4>
<ul>
<li>コードは動作するか?想定した役割を果たすか、ロジックは正しいか、など。</li>
<li>全てのコードは理解しやすいか?</li>
<li>同意されているコード規約に従っているか?カッコの位置、変数名や関数名、行の長さ、インデントの数、フォーマット、コメントと言ったものが含まれる。</li>
<li>冗長あるいは重複したコードはないか?</li>
<li>可能な限りモジュール化されているか?</li>
<li>置き換え可能なグローバル変数はないか?</li>
<li>コメントアウトされたままのコードはないか?</li>
<li>ループは回数が決まっているか?あるいは終了条件は正しいか?</li>
<li>ライブラリ関数で置き換え可能なコードはないか?</li>
<li>ロギングあるいはデバッグ用のコードは削除されているか?</li>
</ul>
<h4>セキュリティ</h4>
<ul>
<li>全てのデータ入力はチェックされ(型、長さ、フォーマット、範囲が正しいかどうか)、エンコードされているか?</li>
<li>サードパーティ製のユーティリティを使っている部分では、返されるエラーを拾っているか?</li>
<li>出力値はチェックされ、エンコードされているか?</li>
<li>不正なパラメータ値の扱いが書かれているか?</li>
</ul>
<h4>ドキュメント</h4>
<ul>
<li>コメントは存在していて、かつコードの意図が記述されているか?</li>
<li>全ての関数にコメントが付いているか?</li>
<li>通常と違う振る舞いや、特殊な場合の扱いについて説明されているか?</li>
<li>サードパーティ製ライブラリを使っている事やその関数についてドキュメントに書かれているか?</li>
<li>データ構造や数値の単位は説明されているか?</li>
<li>中途半端になっているコードはないか?その場合、その部分は削除されるべきか?あるいは'TODO'のような適切な目印でフラグを立てておくべきか?</li>
</ul>
<h4>テスト</h4>
<ul>
<li>コードはテスト可能か?すなわち、依存性が強すぎたり隠されていたりしないか、オブジェクトが初期化できなくないか、テストフレームワークがメソッドを使えるか、など。</li>
<li>テストが存在しており、かつ理解できるものか?少なくとも、同意されているコードカバレッジを守る程度はあるか?</li>
<li>ユニットテストは、コードが意図した機能を実現するよう動作しているかどうかをテストしているか?</li>
<li>配列の「out-of-bound(範囲外のアクセス)」エラーはチェックされているか?</li>
<li>テストコードは既にあるAPIで置き換え可能ではないか?</li>
</ul>
<p>この他に、言語特有の問題の種になり得るものもチェックリストに追加したいところだろう。</p>
<p>このチェックリストは、ありうる問題を全部網羅しないように意図的に作っている。誰も使わないような長いリストなんて必要ないだろう。一般的な問題をカバーするだけでいいのだ。</p>
<h3>チェックリストを最適化しよう</h3>
<p>このチェックリストを始めの一歩にするとしても、それぞれのユースケースに合わせてリストを最適化した方がいいだろう。ある一定期間のコードレビューで上がってきた問題を記録しておくのが一番いい方法だ。その記録を元に、チーム内で起きがちな間違いを特定して、そこから自分たちのチェックリストを作る事ができる。再発しそうもない問題(セキュリティ関連の問題など、あまり起きそうもないがクリティカルなものは残しておきたいかもしれない)を除く事を忘れないように。</p>
<h3>同意を得よう、そして常に最新に保とう</h3>
<p>一般的なルールとして、チェックリストの全ての項目は明確で、さらに可能であれば、二択の判断ができるものになっていた方がよい。これが、判断のブレをなくす手助けになる。また、チェックリストをチーム内で共有し、内容についてメンバーの同意をとっておくのもよいだろう。各項目が意味のあるものであるかチェックするため、定期的にチェックリストを見返すのも忘れないように。</p>
<p>素晴らしいチェックリストを武器にすることで、コードレビューの際に見つけていた数々の不具合を取り上げる事ができるようになる。これによって、コーディングの基礎を引き上げ、コードレビューの品質のばらつきをなくすことができる。</p>
<p>Fog Creekでのコードレビューについてさらに知りたいなら、<a href="http://fast.wistia.net/embed/iframe/vigy79tuhq?popover=true">このビデオ</a>を見てみよう。</p>
doublemarket
https://yakst.com/ja/posts/1373
2014-12-09T00:26:00+09:00
2017-06-18T21:02:17+09:00
プログラミング初心者に言ってはいけないこと
<p>経験のあるプログラマと、プログラミングを習い始めたばかりの初心者の会話の例。</p>
<blockquote>
<p><strong>プログラマ</strong> : やあ、プログラミングの勉強を始めたんだって?いいじゃないか、何を勉強してるんだい?</p>
<p><strong>初心者</strong> : PHPとHTMLの基礎をやってるんです。MacでTextMateエディタを使ってます。</p>
<p><strong>プログラマ</strong> : ひええ、PHPなんて間抜けな言語かよ。Ruby on Railsを覚えて、Herokuにデプロイ、Vimでコーディングした方がいいよ。TextMateなんて初心者向きじゃないか。それから、Node.jsもやった方がいいな。あれはすっっっごくいいぜ。ノンブロッキングIOだからな。ヒャッハー!</p>
<p><strong>初心者</strong> : うーん、そうですか。</p>
</blockquote>
<p>こういうのを聞いたら、そのクソ野郎をすぐに殴ってやりたい。この類の言い方は、初心者のやる気をすっかりなくしてしまうからだ。この初心者には、尊敬する人が自分がやっていることを<em>軽視し</em>、一生懸命勉強している事は「本当のプログラミング」じゃないと思わせようとしているように聞こえるだろう。</p>
<p>君がプログラマなら、初心者に勉強して欲しい事を彼らが覚えていけるよう個人的に進んで膨大な時間をかけてあげるのでもない限り、彼らが今勉強しようとしている事を悪く言わないで欲しい。彼らの選んだ言語やツールが自分の使っているものと比べるといまいちだってことを、悪意に満ちた通りすがり気分でコメントするのは、彼らのモチベーションを失わせてしまうだろう。</p>
<p>もちろん、PHPやその他のどうしても悪口を言いたくなってしまうような言語を、機転の利いた言い方でdisってしまわないようにするのが難しいのは分かる。特に、言語、フレームワーク、ライブラリ、エディタ、ホスティング環境、エルゴノミックキーボード、スタンディングデスクなどなど自分の選んだもの達が、初心者の学ぼうとしているゴミのようなものと比べて、ハッカー魂の奥底からすっっっごく素晴らしいと<strong>分かっている</strong>が故だろう。でも、我慢して欲しい。</p>
<p>彼らには、プログラミングのとりこになるのにかけて、まずは<em>何かを</em>(何でもいいんだ!)学ばせて挙げよう。<em>それから</em>、彼らに現実を見せてあげればいいのだ。もし彼らが学んでいるものが本当にひどいものなら、うまく行かずにハマってしまい、もっと簡単な方法がないか泣きついてくるだろう。そんな場面になった時だけ、純粋な関数プログラミングやら健全なマクロやらに関する君の知識を披露してあげればいいのだ。</p>
<p>もちろん君は、彼ら初心者が話しかけた唯一のプログラマというわけではないかもしれない。多くのプログラマ(もちろんオンラインの掲示板とかで話す事もあり得る!)は、恐らく同じように人を傷つけてしまうようなコメントをするだろう。しかも、それぞれのお気に入りの言語、ライブラリ、フレームワーク、エディタ、ホスティング環境がマジでサイコーーーーーーーーと口々に言うだろう。それこそ、初心者が<strong>完全に</strong>混乱してしまうもとだ。彼らは、その時点ではちゃんと動いているように見えているのに、選んだツールがとにかくひどいものだと繰り返し言われる事になる。しかも自称専門家達は、それぞれ違うツールを学ぶように薦めてくるのだから手に負えない。本当に正しいのは誰なの!?次は何をすればいいんだ!?この手の果てしない欲求不満の詳細は、<a href="http://blog.freecodecamp.com/2014/11/a-cautionary-tale-of-learning-to-code.html">私自身の、プログラミングを学習する際の教訓(いかにしてバランスの取れていたはずの個人が道を踏み外しかけたか)</a>を読んで欲しい。</p>
<p>OK、冒頭の会話のより建設的なバージョンはこうなる。</p>
<blockquote>
<p><strong>プログラマ</strong> : やあ、プログラミングの勉強を始めたんだって?いいじゃないか、何を勉強してるんだい?</p>
<p><strong>初心者</strong> : PHPとHTMLの基礎をやってるんです。MacでTextMateエディタを使ってます。</p>
<p><strong>プログラマ</strong> : いいじゃないか、最初のPHPアプリケーションを動かせたら、カッコいいの見せてくれよ!基本的なWebプログラミングがある程度出来るようになったら、俺の好きなフレームワークのRuby on Railsを教えてあげるよ。そうすれば、PHPとRuby on Railsの同じところ、違うところが比較できるね。</p>
<p><strong>初心者</strong> : 激励の言葉どうもありがとうございます!勉強が進んだらまた連絡しますね。</p>
</blockquote>
<hr>
<p>追記 : この記事に対する違った見方を取り上げた、<a href="https://computinged.wordpress.com/">Mark Guzdial氏</a>への<a href="http://webyrd.net/zoo.html">CS Educational Zoo</a>のインタビューの抜粋も見てみるといい。自動再生されなければ、14:16までスキップしよう。</p>
<p><a href="https://www.youtube.com/watch?v=z1oTtPECHZI#t=856">https://www.youtube.com/watch?v=z1oTtPECHZI#t=856</a></p>
doublemarket