マニュアル駆動開発。
もちろん造語である。そしてまだどこにも存在していないものと思われる。
以前から結合テストとシステムテストの中間的なドキュメント(もちろんテスト仕様になるわけだ)を先に作成して、その後に実装に入るということを何度か試している。
これは、案外 良好なスタイルだと思っていて、かなりの精度で見えない部分をあぶりだすことにも効果があるし、設計のブレを抑制することに一定の効果を上げることを確認している。
しかしながら、万全というわけにもいかないということも体験的にわかっている。
システムやソフトウェアの特性に左右される部分が大きいからだ。特性とは性格を表す内部特性ではなくビジネスゴールにおける特性だ。
リリースされる成果物はきまぐれで、時として根幹を揺るがすような強力な反乱部隊を送り込んでくることがある。つまり、外観的な視覚特性が明らかになったところで、夢を語りだす悪魔が身を潜めていることに注意しなければならないということだ。
「この機能は、ここをチェックしてこっちのボタンをクリックしたときのほうがいいなぁ。」
現代の実装はできるだけスコープを狭く、シナリオでクローズすることが望ましいとされる。そのような工夫が、この時点で仇となり一気に反乱を起こすということだ。
この時点で実装を見直さなければならないことが高確率で予想できるし、テストで確認した点がすべて無効となるわけだ。
このような問題に関する有効な回答を探していたところで、ふと思いついたのが冒頭の言葉である。
マニュアル、つまり「取扱説明書」をまず先に作る。
ふざけているだろうか?
もちろん効果も確認していないし、精度も測定していない。第一試してみたこともない。
しかし、目の前に取扱説明書が提示されたなら、具体的なイメージを余すところなく掴めるはずだ。これはエンドユーザのみならず我々作る側の人間も同じだと思う。
作るものの明確なゴールが見えたところで、もっと突っ込んだ話ができるのも大きな利点だと思う。
それは、セキュリティ、ポテンシャル、スケール、耐久性、拡張性 といった非機能要件である。
この部分を具体的に詰めるのはとても難しい。
プロジェクトによってはざっくり切り捨てなんてことも珍しくないだろう。
そのような中で最も効果が上がるのを期待しているのは
見積もりである。
2015年7月14日火曜日
2015年7月11日土曜日
ニューウェーブ
技術を習得すること自体、実はそれほど難しいことではありません。
ほんの少しのやる気と、根気があれば、年齢を問わず学び続けていくことは可能です。それに加えて体系立てた技術として習得することすら困難ではありません。
しかし、その技術を使って仕事をする以上、これは本質ではありません。
習得した技術をどのように生かしたらよいでしょう。
いろいろな技術には、向き不向きがあるのは当然で、どのようなバックグランドのもとにそのような技術が生まれてきたのか、を知ることは重要なことです。
ここを見誤ると、新しい技術を試してみたいがために大きな失敗を起こしてしまうことにもなりかねません。
しかし、だからと言って新しい技術の習得に及び腰になるのも、とても残念なことです。
技術の本質をつかみとるのは難しいことではありますが、ぜひとも、そういう視点を持ち続けて学んでほしいと思います。
このような背景の中で新しい技術に目を向けていくのは、技術者にとってとても刺激になる体験となると思います。
ほんの少しのやる気と、根気があれば、年齢を問わず学び続けていくことは可能です。それに加えて体系立てた技術として習得することすら困難ではありません。
しかし、その技術を使って仕事をする以上、これは本質ではありません。
習得した技術をどのように生かしたらよいでしょう。
いろいろな技術には、向き不向きがあるのは当然で、どのようなバックグランドのもとにそのような技術が生まれてきたのか、を知ることは重要なことです。
ここを見誤ると、新しい技術を試してみたいがために大きな失敗を起こしてしまうことにもなりかねません。
しかし、だからと言って新しい技術の習得に及び腰になるのも、とても残念なことです。
技術の本質をつかみとるのは難しいことではありますが、ぜひとも、そういう視点を持ち続けて学んでほしいと思います。
このような背景の中で新しい技術に目を向けていくのは、技術者にとってとても刺激になる体験となると思います。
2015年7月10日金曜日
発行者と購読者
現代の実装は確実にスコープを狭めるという方向に向かっています。
この言葉に、ピンと来ない方は少し視点をずらして構造を観察してみることをお薦めします。コードの観察ではなく、構造の観察です。
pub-sub実装は、もしかしたら、おそろく気がつかないところでその恩恵を受けていると言ってもいいと思います。
たとえば、XAMLで画面を作成する場合、この種の作り方としては最も鋭角的なスタイルの実装になるかもしれません。ここではデータの流れをラッピングする形で覆い隠してしまいます。まるで細かいことに固執するなよと言わんばかりです。
たとえば、JavaScriptのMVVM系の一連のスタックは非常にしなやかにデータの流れを隠しています。ここにはアウトプットの「視点」は存在しません。と言ったら言い過ぎかもしれませんが、非常にうまくラッピングされてると言えます。
これらの構造は、GoFのカタログにある古典的なオブザーバー・パターンの思想がベースになっています。まさに先人たちの知恵の賜物です。
現代の要求は非常に複雑になっています。従来のような命令を発行してパラメータを渡す。命令の中はブラックボックスでやがて返却値として回答が返る。受け取った回答をたとえば画面に反映する。と言ったような一連の流れでは難しくなり過ぎています。
この難題を確実に解決するにはどのような工夫が効果を上げるでしょうか?
冒頭に示したようにスコープの分断が有効な手段であることを確認してみてください。
つまり、画面からの入力はパラメータとして処理のブラックボックスに渡します。ここで気を使うべきは、いかに正しい入力をブラックボックスに渡すか?という一点です。
何が返されるか? といったシナリオの終着点は最早存在しません。なぜならスコープの外だからです。
そしてもうひとつの視点が返却されたデータです。ここでは回答が取り出される部分がインプットにあたるという立場をとります。画面には、たとえば DataSource のようなインスタンスの参照を持ち、取り出された回答は DataSource にインプットします。考え方としては入力という視点です。画面にどのように反映されるのかは、ここでは注意を払いません。
画面の制御は極めて難しいものと言っていいと思います。その複雑さにおいて人が注意を払える限界点を超えたところでバグに汚染されてゆくのです。
したがって、私たちはその複雑さを軽減すべく、スコープを分断して注意を払うべき対象を狭めていくのが現代の工夫なのです。
この言葉に、ピンと来ない方は少し視点をずらして構造を観察してみることをお薦めします。コードの観察ではなく、構造の観察です。
pub-sub実装は、もしかしたら、おそろく気がつかないところでその恩恵を受けていると言ってもいいと思います。
たとえば、XAMLで画面を作成する場合、この種の作り方としては最も鋭角的なスタイルの実装になるかもしれません。ここではデータの流れをラッピングする形で覆い隠してしまいます。まるで細かいことに固執するなよと言わんばかりです。
たとえば、JavaScriptのMVVM系の一連のスタックは非常にしなやかにデータの流れを隠しています。ここにはアウトプットの「視点」は存在しません。と言ったら言い過ぎかもしれませんが、非常にうまくラッピングされてると言えます。
これらの構造は、GoFのカタログにある古典的なオブザーバー・パターンの思想がベースになっています。まさに先人たちの知恵の賜物です。
現代の要求は非常に複雑になっています。従来のような命令を発行してパラメータを渡す。命令の中はブラックボックスでやがて返却値として回答が返る。受け取った回答をたとえば画面に反映する。と言ったような一連の流れでは難しくなり過ぎています。
この難題を確実に解決するにはどのような工夫が効果を上げるでしょうか?
冒頭に示したようにスコープの分断が有効な手段であることを確認してみてください。
つまり、画面からの入力はパラメータとして処理のブラックボックスに渡します。ここで気を使うべきは、いかに正しい入力をブラックボックスに渡すか?という一点です。
何が返されるか? といったシナリオの終着点は最早存在しません。なぜならスコープの外だからです。
そしてもうひとつの視点が返却されたデータです。ここでは回答が取り出される部分がインプットにあたるという立場をとります。画面には、たとえば DataSource のようなインスタンスの参照を持ち、取り出された回答は DataSource にインプットします。考え方としては入力という視点です。画面にどのように反映されるのかは、ここでは注意を払いません。
画面の制御は極めて難しいものと言っていいと思います。その複雑さにおいて人が注意を払える限界点を超えたところでバグに汚染されてゆくのです。
したがって、私たちはその複雑さを軽減すべく、スコープを分断して注意を払うべき対象を狭めていくのが現代の工夫なのです。
2015年7月8日水曜日
恣意的なロギングの価値とは?
よく恣意的なログを見かけることがあります。
まるで粒度が揃っていなくて何に主眼を置いているのか理解に苦しむ類です。
さらに悪いことに、巷では通称エラーログと呼ばれたりもします。
果たしてこのようなログが役に立つのでしょうか。
エラーを抑え込んでログとして担保されているのであれば、論理的に障害など起こるはずがないと考えるのは、実は自然なことです。
システムやソフトウェアに何か予期しない障害が起きて、ログを調べることが多くあると思いますが、「なんでこんなにも役に立たない情報ばかり出力しているんだ!」と憤然とした経験を持っている方も多いと思います。
このような事象の原因は多くの場合ロギングポリシーを策定していないことが大半だと思われます。そのような状況で各実装の担当者に頼りきってしまえば、属人的なロギングコードが記述されるのは明らかです。チームプレーの場合は悲惨です。
そもそもログにはどんな情報を出力するのが有益でしょうか。
エラー時の内容を示す文言でしょうか。
果たして、エラーとは何を示すものなのでしょうか。
想定した値を得られず処理を中断してユーザにメッセージを導出するプロセスを考えてみた場合、概ねこのような現象をエラーとして取り扱うことが多いと思います。
ユーザ視点で立てばこのような考え方は間違いないと思います。では、ロギングの観点で考えてみた場合、これは果たして適切なのでしょうか。
たとえば、上記の想定で処理は中断されエラー・パスを通り、想定通りユーザにメッセージを通知しました。そして、ログにはそのような手続きの結果を文言として具体的な内容を出力しました。
このような充分想定されたパスを踏んだ手続きをログから読み取ったところで、どのような意味があるのでしょう。確かに、ユーザ向けにエラーとして処理されました。という証拠にはなるでしょう。
しかし、ログの重要性や有益性はもっと別なところにあるはずです。
想定しない制御が起こり、調べる段階でこのようなわかりきった記録を読んだところで、実際はほとんど役に立つことがありません。
なぜならば、客観性に乏しい記録に他ならないからです。
そうです。ロギングのポイントはシステム内のデータを客観的な視点で淡々と出力することが望ましいのです。
おそらくここが難しいポイントでもあるのだろうと思います。
開発者の視点でロギングコードを記述すると、つい当たり前のポイントに目がいかなくなります。障害というのは当たり前のデータの流れの中で起こるものなのです。その当たり前だろうと思っている材料を失うと、それは大きな損失に繋がります。
ぜひ、皆さんも自身のチームのロギングポリシーをいまいちど考察してみてください。
まるで粒度が揃っていなくて何に主眼を置いているのか理解に苦しむ類です。
さらに悪いことに、巷では通称エラーログと呼ばれたりもします。
果たしてこのようなログが役に立つのでしょうか。
エラーを抑え込んでログとして担保されているのであれば、論理的に障害など起こるはずがないと考えるのは、実は自然なことです。
システムやソフトウェアに何か予期しない障害が起きて、ログを調べることが多くあると思いますが、「なんでこんなにも役に立たない情報ばかり出力しているんだ!」と憤然とした経験を持っている方も多いと思います。
このような事象の原因は多くの場合ロギングポリシーを策定していないことが大半だと思われます。そのような状況で各実装の担当者に頼りきってしまえば、属人的なロギングコードが記述されるのは明らかです。チームプレーの場合は悲惨です。
そもそもログにはどんな情報を出力するのが有益でしょうか。
エラー時の内容を示す文言でしょうか。
果たして、エラーとは何を示すものなのでしょうか。
想定した値を得られず処理を中断してユーザにメッセージを導出するプロセスを考えてみた場合、概ねこのような現象をエラーとして取り扱うことが多いと思います。
ユーザ視点で立てばこのような考え方は間違いないと思います。では、ロギングの観点で考えてみた場合、これは果たして適切なのでしょうか。
たとえば、上記の想定で処理は中断されエラー・パスを通り、想定通りユーザにメッセージを通知しました。そして、ログにはそのような手続きの結果を文言として具体的な内容を出力しました。
このような充分想定されたパスを踏んだ手続きをログから読み取ったところで、どのような意味があるのでしょう。確かに、ユーザ向けにエラーとして処理されました。という証拠にはなるでしょう。
しかし、ログの重要性や有益性はもっと別なところにあるはずです。
想定しない制御が起こり、調べる段階でこのようなわかりきった記録を読んだところで、実際はほとんど役に立つことがありません。
なぜならば、客観性に乏しい記録に他ならないからです。
そうです。ロギングのポイントはシステム内のデータを客観的な視点で淡々と出力することが望ましいのです。
おそらくここが難しいポイントでもあるのだろうと思います。
開発者の視点でロギングコードを記述すると、つい当たり前のポイントに目がいかなくなります。障害というのは当たり前のデータの流れの中で起こるものなのです。その当たり前だろうと思っている材料を失うと、それは大きな損失に繋がります。
ぜひ、皆さんも自身のチームのロギングポリシーをいまいちど考察してみてください。
テストの終わりとは?
よくこんな相談を持ち掛けられます。
「どこでテストを終えればよいのか?」
「品質の可否はどこで見極めればよいのか?」
実は、これは見当違いな質問に思えます。
なぜならば、テストは極めて能動的な行為であるからです。
正確に言うならばテストに終わりはありません。理論的には、いつかは、どこかのポイントで終わりを迎えることになると思いますが、そこまでに到達するには天文学的なテストケースを導き出さないとならないでしょう。
もちろん、これは現実的ではありません。
では、最初の質問にあえて答えるとするならば、テストの終わりはどこにあるのでしょうか。
テストの終わりははじめに決めておくべきことなのです。
別の表現を借りるならば、この答えはテストの方針です。品質のスコープと着地点を明確にしておかなければ可否の判断などできないのです。
しかし、ある人は 「それでは、本当に品質をクリアしているのか判断できないではないか。」 と言うかもしれません。
合理的な根拠をもった指標を決めないと、こういう意見がでるのも当然だと思います。さらに言うならば、テストのモニターを怠っているからこその感覚だとも言えます。
もう一度言います。テストは極めて能動的な行為なので、テストをこなしさえすれば品質を稼げるという発想は止めるべきです。
システムやソフトウェアに完璧な状態などあり得ないのです。そのためにポイントを明確にした品質の観点や領域で少しでも指標に近づく努力に力を注ぐべきなのです。
「どこでテストを終えればよいのか?」
「品質の可否はどこで見極めればよいのか?」
実は、これは見当違いな質問に思えます。
なぜならば、テストは極めて能動的な行為であるからです。
正確に言うならばテストに終わりはありません。理論的には、いつかは、どこかのポイントで終わりを迎えることになると思いますが、そこまでに到達するには天文学的なテストケースを導き出さないとならないでしょう。
もちろん、これは現実的ではありません。
では、最初の質問にあえて答えるとするならば、テストの終わりはどこにあるのでしょうか。
テストの終わりははじめに決めておくべきことなのです。
別の表現を借りるならば、この答えはテストの方針です。品質のスコープと着地点を明確にしておかなければ可否の判断などできないのです。
しかし、ある人は 「それでは、本当に品質をクリアしているのか判断できないではないか。」 と言うかもしれません。
合理的な根拠をもった指標を決めないと、こういう意見がでるのも当然だと思います。さらに言うならば、テストのモニターを怠っているからこその感覚だとも言えます。
もう一度言います。テストは極めて能動的な行為なので、テストをこなしさえすれば品質を稼げるという発想は止めるべきです。
システムやソフトウェアに完璧な状態などあり得ないのです。そのためにポイントを明確にした品質の観点や領域で少しでも指標に近づく努力に力を注ぐべきなのです。
2015年7月7日火曜日
あせるべからず…
仮に Result オブジェクトで任意の情報(もちろん結果)をプレゼンテーションに返却することを仮定してみます。
Result オブジェクトにはフィールドとして ResultType を保持しているとします。その ResultType が取り得る値は、
Unknown: 初期値
Success: 成功
Failure: 失敗
と定義するとします。
さらに Result オブジェクトは、Results<IEntity> というパブリックアクセサを通じて、内部に保持する「結果」のコレクションにアクセスすることを定義します。
つまり、これらの情報によりプレゼンテーションでは、問い合わせの成功/失敗、そして得られた結果の集合を取得できるようになりました。
一見、理路整然とした構造のように見えます。
では、Aさんにプレゼンテーション層の実装をお願いして、Bさんにモデル層の実装をお願いすることにします。
例題として、蔵書管理の中から任意の作家に関する書籍のレコードの集合を取り出すことを考えてみます。
正常系として、想定した書籍のレコード群が取り出されるわけですが、当然ながら 0件以上 n件 というレコードの集合が取り出されることが考えられます。
では、まずプレゼンテーション担当のAさんの視点で捉えてみます。
たとえば、10件のレコードを取得することができました。ResultType = Success で結果は成功です。同様に1件のレコードのみを取得できました。これも成功です。ここまでは何も問題はありません。
次に0件のレコード、すなわち、検索の結果がマッチせずに結果が返されることを想定します。レコードが返されないので処理は失敗とみなし、ResultType = Failure と考えました。
同じシナリオを、今度はモデル層を担当するBさんの視点で捉えてみます。Bさんは何件のレコードを取得できようが結果は Success で定義できる、という考えをポリシーとして持っていました。つまり、結果0件であろうと、処理そのものを失敗しているわけではないので、ResultType には Success をセットしたのです。
ここに1件のバグが入り込みました。
この場合、どちらの実装が正しいのでしょうか?
答えは、どちらも正しいです。
そして、どちらも間違っています。
両者には、大局的な視点での実装方針を確認しあう 「ゆとり」 が、ほんの少しだけ欠けていたのです。
Result オブジェクトにはフィールドとして ResultType を保持しているとします。その ResultType が取り得る値は、
Unknown: 初期値
Success: 成功
Failure: 失敗
と定義するとします。
さらに Result オブジェクトは、Results<IEntity> というパブリックアクセサを通じて、内部に保持する「結果」のコレクションにアクセスすることを定義します。
つまり、これらの情報によりプレゼンテーションでは、問い合わせの成功/失敗、そして得られた結果の集合を取得できるようになりました。
一見、理路整然とした構造のように見えます。
では、Aさんにプレゼンテーション層の実装をお願いして、Bさんにモデル層の実装をお願いすることにします。
例題として、蔵書管理の中から任意の作家に関する書籍のレコードの集合を取り出すことを考えてみます。
正常系として、想定した書籍のレコード群が取り出されるわけですが、当然ながら 0件以上 n件 というレコードの集合が取り出されることが考えられます。
では、まずプレゼンテーション担当のAさんの視点で捉えてみます。
たとえば、10件のレコードを取得することができました。ResultType = Success で結果は成功です。同様に1件のレコードのみを取得できました。これも成功です。ここまでは何も問題はありません。
次に0件のレコード、すなわち、検索の結果がマッチせずに結果が返されることを想定します。レコードが返されないので処理は失敗とみなし、ResultType = Failure と考えました。
同じシナリオを、今度はモデル層を担当するBさんの視点で捉えてみます。Bさんは何件のレコードを取得できようが結果は Success で定義できる、という考えをポリシーとして持っていました。つまり、結果0件であろうと、処理そのものを失敗しているわけではないので、ResultType には Success をセットしたのです。
ここに1件のバグが入り込みました。
この場合、どちらの実装が正しいのでしょうか?
答えは、どちらも正しいです。
そして、どちらも間違っています。
両者には、大局的な視点での実装方針を確認しあう 「ゆとり」 が、ほんの少しだけ欠けていたのです。
2015年7月4日土曜日
失敗の経験値
経験を積むとはいったいどういうことなのでしょうか。
たとえば、何かのプロジェクトに参画をしたことにより、それは経験につながるのでしょうか。
正確に言うと、経験を積むとは失敗を重ねるということに他なりません。
ただし、注意しなければならないのは、失敗を重ねることの字面をそのまま受け取ってはいけないということです。失敗は単なる失敗でしかないからです。
重要なのは、失敗の背後にはたくさんのヒントが隠れていることを認識することだと思います。
わかりやすく言えば、失敗の経験を基に成功が導き出されるのです。逆の言い方をすれば、つまり、失敗は成功の根拠になるのです。
成功を表すには根拠が必要です。その根拠とは失敗の裏返しです。
何かの仕事で成功を勝ち取ったとしましょう。しかし、その根拠を言い表すことが出来なければ単なる「まぐれ」です。失敗の理由すらそこから導き出すことはできません。
言い換えると、それは経験には至っていないと考えなければなりません。
もし、皆さんが現在従事しているプロジェクトがあるならば、その仕事を終えたときに、チームのメンバーとともに、ぜひとも反省会を開いてみてください。
そして出来るだけたくさんの失敗談を列挙してみてください。
その失敗はなぜ起こったのか? どこに原因があるのか? 必ず分析をしてみてください。
そこではじめて経験を積んだことになるのです。
たとえば、何かのプロジェクトに参画をしたことにより、それは経験につながるのでしょうか。
正確に言うと、経験を積むとは失敗を重ねるということに他なりません。
ただし、注意しなければならないのは、失敗を重ねることの字面をそのまま受け取ってはいけないということです。失敗は単なる失敗でしかないからです。
重要なのは、失敗の背後にはたくさんのヒントが隠れていることを認識することだと思います。
わかりやすく言えば、失敗の経験を基に成功が導き出されるのです。逆の言い方をすれば、つまり、失敗は成功の根拠になるのです。
成功を表すには根拠が必要です。その根拠とは失敗の裏返しです。
何かの仕事で成功を勝ち取ったとしましょう。しかし、その根拠を言い表すことが出来なければ単なる「まぐれ」です。失敗の理由すらそこから導き出すことはできません。
言い換えると、それは経験には至っていないと考えなければなりません。
もし、皆さんが現在従事しているプロジェクトがあるならば、その仕事を終えたときに、チームのメンバーとともに、ぜひとも反省会を開いてみてください。
そして出来るだけたくさんの失敗談を列挙してみてください。
その失敗はなぜ起こったのか? どこに原因があるのか? 必ず分析をしてみてください。
そこではじめて経験を積んだことになるのです。
登録:
投稿
(
Atom
)