エクストリーム・プログラミングという手法を実践する上で必要と考えられる12個の項目について、それぞれをまとめておきます。
(内容の重みに差があろうかと思います。ご容赦ください。)
計画ゲーム
「計画」というと、あれをやって、次にこれをやって、その次に...と立てるでしょうか。その際に見落としがちなのが「失敗の計画を立てること」です。
「成功の計画」を立てることは至極当然ですが、それよりも大切なのが「失敗の計画」なのです。
デザイン(設計)はフォルム(形)の実現にあるのではなく、ミスフィット(ぴったりしないもの)の排除にある。 ── Alexander[2]
わざわざ時間を割いて失敗の計画を立てるなど無駄ではないか、と一時の私は思ったものですが、とんでもありません。事前に落とし穴を見つけることが、どれほど有用なことかは自明です。
短期リリース
p.15のスライド「ソフトウェアをドライブする」より
車の運転は、常に小さな変更をし続けることなのよ。こっちに少し向いてしまったら、あっちに少し修正する。運転している間中、こっちへあっちへとね。
車を運転するという行為自体は非常に高度なことで、その場の状況へ柔軟に対処し続けることで初めて成り立つのです。
それとは相反するように「設計はこれで決まり」「実装終わった」「納品できた」と言って、一発決め打ち型で成し遂げられるほど、ソフトウェア開発は安易なものなのでしょうか。
もちろん、それが「一筋縄に行かぬ大変困難な行為」であることは、技術者にとってみれば明らかなことで、まさに車の運転と同じであるということも理解できるはずです。
にもかからわず、実際のプロジェクトではどうでしょう。俗に言うウォーターフォールモデルでは、各工程を決め打ちで進めるのではないでしょうか。
ゴールが見えたからと言って、その場所から目を閉じて歩くのですか、恐ろしい。目を開けてみたらゴールはいずこ...なんてことが多いはずです。
最初から完全な計画を打ち立てねばならないのは、いうなれば顧客や自社上層部に安心してもらうこと(つまり信頼を獲得すること)が目的でしょう。
信頼を得ることが大切なことだとは思いますが、その方法以外にも信頼は獲得できるはずです。それが「短期リリース」です。
こまめにリリース(現状の進捗報告)を行うことで、顧客側や上層部から「おぉ、ちゃんと仕事進んでるね」と信頼を獲得できるのです。
仕事をさぼったりはしていない、と証明して信頼を得る良い手段として活用したいものです。(後の「オンサイトのユーザ」と合わせると効果的でしょう。)
蛇足ですが、この類似例として「機能安全」や「本質安全」という言葉にも繋がりましょう。
日本では信号機が一つしかないような場面で、例えばアメリカならいくつもの信号機が同じ色を示して同じように動いているのです。
日本は「壊れない信号機」を用いることで安全を確保しています。アメリカは壊れるかもしれない信号機を「いくつも冗長に用いること」で安全を確保しています。
壊れない信号機が現実に存在するのであれば、日本のやり方は無駄が無くて良いように思いますが、果たしてそんな理想的というか夢物語のような信号機が存在するかと問えば、
おそらく渋々「無い」と答えるほか無いでしょう。
しかし、やい「コスト」だの「リスク」だのという言葉を盾に、この冗長化を避けようとする人たちが居るようです。
そんな「リスクにうるさい人々」は、わざわざ大変危険なリスクを持つ方向へ走っているかもしれない、ということに気付いているのでしょうか。目先のリスクに踊らされてはいないでしょうか。
上の決め打ちに見られる「完璧主義」などというものは、本当は存在する問題点(致命的リスク)を黙殺して虚偽の理想郷を描いているに過ぎず、もはや時代遅れも甚だしいと私は感じます。
複線を敷いて冗長に事を進めるためには、確かに相当のコストが必要になるでしょう。
しかしながら、単線で乗り切るという夢を見て取り返しの付かない事態に陥ることの方が、その企業にとってよほど致命的なコストに繋がるとは思いませんか。
もはや賭博ではありませんか。目先の敵キャラ(目先のリスク)に力を使い果たして、ラスボス(致命的リスク)に対抗できるはずもありません。
「理想」で会社は成り立たないと言う割に、「理想」を盾に逃避しているようにも見えるのです。
ソフトウェア開発だの車の運転だの人生だの、その題目・式次(プログラム)など永遠に定まるはずもなく。
この「現実」を受け入れずして、「現実的なソフトウェア開発」が可能になるとは到底思えません。
メタファ(隠喩)
(意味世界(提喩・包含)と現実世界(換喩・隣接)とを結びつける要所。(via パワーランチ「レトリック 2」 2012.05.30)
とかく、意味付け(関連付け)の役割を果たすもの。「ヒルのような唇」など。
本稿の各項の説明では、何かしらの喩えを用いているけど、それもまたメタファ。その効用は?)
のろまな人を「亀」と言ったり、私のことを「カメラキチガイ」と言ったり。
ある名称を用いて暗に別のものを指し示す比喩表現「隠喩(暗喩)」ですが、実はプログラミングにも深く関わることだったりするのです。
例えば、関数の手続きに名称(関数名)を与えることも、メモリ上の特定領域に名称(変数名)を与えることも、隠喩と捉えることができるのです。
後のコーディング規約でも触れるように、人は類推力を頼りにプログラムを読み進めたり活用したりするものです。
それゆえに上手い比喩表現を用いれば、読み手が理解しやすいプログラムになります。つまり、比喩表現などのレトリックを使いこなせるようになることが、プログラミング上達の要ともなるのです。
(特に意表を突くような隠喩は印象に残って覚えやすいものです。「ヒルのような唇」など。プログラミングにも同じことが言えます。)
補足ですが、隠喩(類似性)が、提喩(包含性、意味世界)と換喩(隣接性、現実世界)とを結びつけるものであるということも学んだのだ、ということを記録しておきます。(パワーランチ「レトリック2」にて)
シンプルな設計
田中さんに好きな食べ物を尋ねてみました。
私は、ステーキが好きです。
それと、山田さんにも好きな食べ物を尋ねてみました。
ちょうど先週の木曜日に田中さんと食べに行ったレストランで注文した、インド米使用の特製カレーライスは私の実家のものと味が似ていたので好きです。
設計とは、その開発における「一番大切なこと」を明らかにするものであり、その設計を見た人に「一番大切なこと」が伝わらなければ意味がありません。
何が言いたいのかを把握するためには、シンプルな方が良いということが上の例で明らかになったと思います。
ソフトウェア開発でUMLなどの図を拵えることもあろうかと思いますが、その際、あまり細かいことに拘って複雑な描き方をすると、
もはや設計としての役目から逸脱することになります。大切なことに絞って記載するよう努めねばなりません。
テスティング
テスティングは、これから自分の作ろうとするものの仕様を明確にし、実装の手助けをしてくれる大切なものです。
まず、ある手続きを次の3つの構造に区分けしますが、その中心となるのが「本体(do)」で、その手続きの主体となる処理を行います。
その本体の前に設ける「表明(assert)」は、本体処理を行うための前提条件を満たしているかをチェックする部分です。
本体の後には「確証(ensure)」を置き、本体の処理の結果が当初予定していた内容に合致することを保証するための部分です。
テスティングは、この表明と確証の部分を作成することに相当します。つまり、どのようなものが入力され、どのようなものが出力されるのかを明らかにするのです。
未だ小さな例でしか体感していませんが、それでもこの表明と確証とを作成しておくと、最後に本体を実装する際に気分が楽になります。
もし入力値がこんなのだったらどうしよう...などという余計な心配をすることもなく、本体として実現すべき処理の実装に集中することができるのです。
実装に対する環境整備が「表明」で、応答に対する環境整備が「確証」という具合でしょうか。
新しく取り組むことであっても、心づもり(環境整備)さえ整っておれば落ち着いて事を進めることができるものですが、プログラミングもまた然り。
リファクタリング
システムの振る舞いを変更することなく、部品の品質を向上させる。
上の言葉に「部品の品質を向上させる」とありますが、これは「部品」として取り出せるような構造にしていることが前提となります。
部品として取り出すことも難しいようなプログラム(凝集性の低いプログラム)では、まず何を変更するにも全体への影響を考えねばなりませんし、
そのコストは無視できるものではないはずです。
「システムの振る舞いを変更することなく」という部分に変わりはありませんが、凝集性の低いプログラムであれば「部品の品質を向上させる」ことよりも、まず「凝集性を上げる」ことが先決でしょう。
もつれ合った複雑な構造を見ながら手を入れる(リファクタリングする)など、さらなる混乱を生みかねませんので。
数学で喩えるなら「因数分解」がその一例となりましょう。共通項(共通機能)を括りだすことで全体をコンパクトにしたり、見通しを良くすることができるのです。
ただし、下手に因数分解して手足が出なくなることがあるように、ソフトウェアプログラムのリファクタリングにも慎重さが欠かせませんので、注意が必要です。
ペアプログラミング
ペアプログラミングとは、その文字通り二人でプログラミングを執り行うことを言います。かたや先輩かたや後輩。先輩が学んできた落とし穴(失敗談)を、先輩本人からの口伝によって後輩は学ぶことができますし、
また逆に後輩に口伝することを通して先輩自身も知識を定着させたり、新たな発見があったりするものです。
また、教科書や専門書からは伝わらないことを伝えることができます。「プログラムの発生と進化の過程」がその代表格と言えるでしょう。
料理のレシピ本には、必要な材料や完成イメージだけでなく、さらに調理の手順も記載されています。だからこそ、その料理再現できるわけですが、プログラミングではどうでしょう。
その手の専門書にはプログラムのソースコードがまるまる載っていることも少なくありませんが、それはレシピ本で言うところの完成イメージ(青写真)に過ぎません。
プログラムを書き認めるとき、きっと自分なりの組み立て方があろうかと思いますが、果たしてその作者独自の組み立て方の手順が、プログラムをまるまる載せているような本から伝わるでしょうか。
その本を読んだからと言って、さようなソースコードを頭の中で再構築できるでしょうか。
目で見て理解したとしても、それを行解に移さない限り、本当の意味での会得には至りません。
「プログラムを丸写しすること」ではなく、「頭の中でどのような思考過程を経ればそのプログラムに至るのかを考えること」が、本来のプログラミングの学びです。
ペアプログラミングは、その本来の学びのために有用な手法となりましょう。
共同所有
「馬の耳に念仏」とは、よく言ったもの。どれだけ有り難い説法を聞かせたところで、馬や鹿にはわかりっこないのです。そしてそれはソフトウェアプログラムにおいても全く同じこと。
どれだけ有用なプログラムを公開(オープン)しておいたところで、それをきちんと会得して使いこなせるようなウマシカなど居ないのです。
たとえ10人に教え諭したとて、ものになる者はひとりかふたり、とあります[3]。
そんな世の中で、公開されているプログラムを勝手に理解して勝手に使いこなせるような人間が果たしてそれほど居るのかどうか。
もし、さような人間が現れたとすれば、むしろチャンスと捉え、是非ともその人とお近づきになるべきなのです。その人はきっと優秀で有能な技術者なのでしょうから。
(その「繋がり」を会社の利益として捉えられないものか、と。)ある種、優秀な人材を捜す糸口にもなるのです。
「わかる人にはわかる、わからない人にはわからない」という考え方を、何か他の例に写像したならきっとピンとくるはずですが、繰り返します、それはソフトウェアプログラムにおいても同じことです。
共用のリポジトリに入れることも然り、Webページを拵えることも然り。その人の取り組みを外部にアウトプットすることで、自身のモチベーションはもちろん、周囲に良い意味での刺激を与えることにつながります。
そして先に述べたように、その活動を理解してくれる有能な人たちと「共創」という関係を創り出すことができるのです。
自分の強みを活かしつつ(外在化しつつ)、わからぬ事は先人に訊いて自らの強みとして会得する。まさに「共創」のなす業。「Linux」も、その最たる例となりましょう。
オープンにすることによるリスクも当然あるのでしょうが、メリットのことをもっと真剣に考えてみてはいかがでしょう。もっと先を見通しませんか。
継続した結合
何か問題が生じたとき、その問題だけを切り離して対処を施そうとすることがあると思います。確かに、その方がスッキリしていて見通しやすく、問題解決も楽になると感じるはずです。
が、実際に生じる問題というものは、その場の環境によって再現されるものであり、その場から切り離して別環境でテストやデバッグを施しても、再現性に欠ける場合があるのです。
つまり、全く意味のないテスト・デバッグとなりかねないのです。
そのため、可能であれば「切り離す」ということを避けたいものです。テストやデバッグの話で言えば、テストプログラムと本体プログラムは常に一緒にしておくことです。
PBEという言葉があります。Programming By Example ── 例題(テストプログラム)を基盤として実装を進めてゆくやり方ですが、まさに「継続した結合」の良い例でしょう。
テストプログラムを付随するなど、格好が悪いように感じるかもしれませんが、テストプログラム自体は、本体プログラムの正しさを証明するものであり、切り離すなど勿体ない話なのです。
「繋がり」に付随する「意味」は、切り離した時点で失われます。その「繋がり」にある価値を無駄にしないようにしたいですね。
40時間労働
仕事が終わらないからと言って、自身の体を無理にこき使ってはいませんか。若いうちは無理したって平気だと思っていませんか。そもそも、「平気」とか「平気ではない」などという問題ではないのですが...。
体に休息を与えることは、もはや「権利」ではなく「義務」と言っても過言ではありません。殊に食品製造や調理の話に喩えれば明らかです。
どんどん作りたいからと言って、定期点検も消毒もろくに行わずして、品質の良い食品が製造できるでしょうか。錆びた包丁で料理を作るのですか。なんと悪質な。
プログラミングとて同じこと。モノを作る立場であれば、道具のメンテナンスを日々欠かさないことは当然であり、
無理して頑張ったとしてもそれは決して褒められたことではありません。
自身の体とて、プログラミングに必要不可欠な道具なのです。定期メンテナンス(休息)を充分に行い、品質の良いプログラムを作らねばなりません。
(さもなくば、悪質なプログラムによって自分の首を絞めかねませんので...)
参考として、師の言葉を引用します。週間BCN 視点:プログラマは「書く」よりも「読む」
オンサイトのユーザ
既に短期リリースの項でも述べましたが、ソフトウェア開発は常に軌道修正を行わねばならないような高度な作業です。
もし現場にユーザが居たらば、すぐに意見を求めることができ、より精密な軌道修正が可能となるでしょう。
その意味で、オンサイトユーザ(現場のユーザ)が居ると嬉しいですね。
コーディング規約
プログラムの書き方、殊に変数名や関数名の付け方は統一されているべきであり、複数の文化を混用するべきではありません。
Yesterdayは、high schoolのfriendとbaseballをwatched。
まあ読みづらいったら...。単純に考えても保守性に影響を及ぼすことがわかるとおもいます。
もう少し考えてみると、これは既存の資産を活用できるか否かにも関わってきます。統一感があれば、
- createPassword
- getPassword
- setPassword
...という具合に、先頭の単語以外が一致していて、一目で何をするものかがわかるのと同時に、「Password」と検索すればパスワード関係の処理をすべて見つけることができるでしょう。
比べて、統一感が無い場合、
- createPassword
- pasuwado
- setpwd
...という具合に、キャメルケースで書く人、ローマ字表記で書く人、略称を用いて書く人などが混在します。
「createPassword」を作った人が、パスワードを取得する関数を必要としたとき「get」や「Password」で検索するでしょう。
しかし該当項目が見つからないため「なんだ、まだ作ってないのか。じゃ、作ろう。」と言って、「pasuwado」と同じ機能を持つ「getPassword」を生みかねません。
明らかに無駄ですよね。
プログラムを書くときは、それを読む人・使う人に対して気遣うべきです。類推によって他の部品を見つけ出すことができるように命名を工夫し、無駄を生むリスクを下げることが望まれます。
[2] 形の合成に関するノート, Christopher Alexander, 稲葉武司 訳, 鹿島出版会
[3] 資料のp.13。「約5年間、10人に教えたとしても、ものになる者は、ひとりかふたり。教わる人は、教える人を、なかなか追い越すことができない。」