2015年8月18日火曜日

喜びの瞬間を捉えよう

Googleを語った書籍の広告が、JRの車内にありました。
ここではあえてその内容には触れませんが、購買力をあげるなかなか興味深いコピーがならんでいます。
昨日のニュースでは、Googleの共同創業者でもありCEOのラリー・ペイジが新しい会社を起業し、その傘下にGoogleを置くという話題がありました。
Googleは巨大になり過ぎたのです。

さて、仕事は楽しいですか?
もしかしたら、大半の人が冗談じゃないと声を荒げるかもしれません。

では、コードを書くのは楽しいですか?
またもや、もうへとへとだよ。深夜帯も休日も返上してコードを書いていて楽しいわけがない。という声をあるかもしれません。
仮にある刹那を切り取ってみましょう。きっと生き生きとコードを書いている瞬間が必ずあるはずです。食事を摂るのもわずらわしいほどにタイピングの指の動きが止まらない瞬間があるかもしれません。もし、そのような瞬間に幸運にも出会えたら、あるいは、心当たりがあるならば、そのボルテージの高まりへのストーリーを想像してみてください。

また、このように捉えることも出来ます。
私たちは日々コードを書き続け、クラスを定義し、組み合わせ、そして走らせるわけです。もっとも緊張する瞬間ですが、想定どおりの動きを目の前で展開された瞬間は、きっと喜びに満ちているはずです。

2015年8月17日月曜日

MBA教材としての清掃サービス

新幹線の車内清掃サービスをご覧になったことがある方は、もしかすると案外多いのかもしれません。
いまや世界的にも注目されているこの仕事は、ハーバード大の経営大学院の教材としても取り扱われるほどです。
以前は、3K職場などと揶揄された時代もありました。
清掃の現場はカーテンで閉ざされ、クローズされた車内空間で戦闘が繰り広げられていました。これが、以前のメンタリティなのです。ところが、現在ではひとつの パフォーマンス として捉えることが可能なほどに、メカニカルで想像力溢れる作業効率を実現、かつ、追及して7分間の Show としてまとめられています。 この変化はどこから来たのでしょう?
米流に考えるならば、成果を上げれば報酬で評価し、あるいはその逆であれば罰則を強化する。ところが我が国の文化はまったく違ったようです。新幹線の車掌も、あるいはグリーンアテンダントも清掃スタッフも、お客様に見られることを意識したマインドセットを重視したそうです。これは、オープンであることの重要性だと思います。
しかしながら、ここまでの技術に昇華するには様々な紆余曲折があったことは容易に想像できます。ここにポイントが隠されてると思います。経営サイドや運営陣ではなく、現場から能動的に発信される改善案には必ず明確な根拠があることの重要性を、しっかりと受け止めるまでに成熟した文化が根付いたことの証だと思います。私たちもそこから学ぶべきことは少なくないはずです。

2015年8月6日木曜日

抽象的な工場の提案

ファクトリ(Abstract Factory)は極めて応用力の高い実装パターンです。
昨日にも書いたように、もし、if文の入れ子構造があまりにも深いのであればリファクタリングの兆候です。
同様にif文のコンビネーションの中で階層表現として扱われる問題は、結局は同じシリーズであるわけです。ただ、ほんの少しだけ条件が変わるだけなので、そういう場合は頭を冷やすなり、もう一歩引いた視点で俯瞰する必要があります。

これは決して難しい問題ではありません。
たとえば、ある車を生産する工場があったとします。その工場ではたったひとつの車種を生産します。しかしながらオプションの種類が多彩で、その都度生産条件を変更してやる必要があります。まさに if文で判定するわけです。
しかし、その方法ではおそらくすぐに限界がやってきて作業ミスが多発する問題は避けがたくなるだろうと思われます。
この問題をどのように回避したらよいでしょうか。

先にも書いたように、もし○○○であれば、XXXのオプションを追加するという考え方をやめてしまうのです。そして、そのパラダイムをXXXのオプションで○○○を実施するという方向にシフトします。

工場はいろいろな条件でモノを生産します。
条件が違うだけで、ベースになるものは同じです。つまり、生産物はシリーズであるわけです。であるならば、ベースになる部分をごく抽象的なインタフェースでルールのみを定義してやることにより、オプションで肉付けをすることが可能になります。
これがアブストラクト・ファクトリの基本的な考え方です。

2015年8月5日水曜日

実務に即したファクトリ実装

もし、○○○ならば、XXXをする。

これは極めてソフトウェア工学の中ではポピュラーなモノの考え方です。
常に通奏低音のように鳴り響き、まるで呪縛のように私たちを取り巻いている、ひとつの習慣として醸成されています。

今回はここを取り崩そうと考えています。

上の if文 の中でさらに条件を想定して、もし、△△△ならば、□□□をする。というような構造を考えてみます。いわゆる入れ子構造です。

ここまでを整理します。
すると以下のような構造が見えてくると思います。

if ○○○ {
     if  △△△ {
          □□□
     }
     else {
          XXX
     }
}
else {
     // 何もしない。
}

ここでは、3つの処理系が存在することがわかります。
さらに、もし、△△△ならば… という条件下でさらに入れ子になる構造… と考えたところで、うんざりしますね。そしてバグの不安に駆られます。このような構造が(そう、構造そのものなのです!)ソースコードの平面的な世界観の中で表現された場合、人間の頭の中ではどのくらいの階層まで把握、管理ができるでしょうか?

いいえ、このような発想は、おそらくナンセンスなのでしょう。
もっと、シンプルに整理、管理できないのか? ということに頭を使ったほうが、余程世のためなのだと思います。

皆さんであれば、どのような工夫をするでしょうか。

このように整理してみます。

if ○○○ {
     if  △△△ {
          □□□ Aの処理系
     }
     else {
          XXX  Bの処理系
     }
}
else {
     // 何もしない。Cの処理系
}

この構造を階層で表現せずに、バラバラにしてまずはコンテキストで表します。
(表現が冗長になるのためコンストラクタの記述は割愛します)

まずは、AとBの処置系
class ABClass implements IFactory {
     public void Execute() {
          if △△△ {
               // Aの処理をする。
          }
          else {
               // Bの処理をする。
          }
     }
}

次にCの処理系
class CClass implements IFactory {
     public void Execute() {
          // Cの処理をする。
     }
}

この段階でAとBの処理系をドライブする表現を記述します。

IFactory target = null;
if ○○○ {
     target = new ABClass();
     target.Execute():
}
else {
     target = new CClass();
     target.Execute():
}

if文の入れ子構造をひとつ減らすことができました。
ポイントは、もし、○○○ならば、XXXをする という考え方から脱却して、XXXという条件で○○○をする というように捉え直します。
いわゆるポリモフィズムの実務に即した応用です。

2015年7月28日火曜日

Test First ?

以前、テストに基づいて仕様を考えることを試してみた結果という観点での内容の文章を書きましたが、これはそれほど難しい考え方ではないということを皆さんも薄々気がついていることだと思います。
ただ、重厚長大な形式主義や単なる習慣が、こういった逆転の発想を打ち消してしまうのは少々もったいないようにも思います。

依然として、要件をまとめて、機能仕様を作成し、さらに詳細設計書まで落とし込んでやっと楽しい実装に入れるという流れも、そろそろ限界を迎えてるのではないかと、いや、とっくに限界なんだろうと考えるわけです。
なぜなら、プロジェクト後半にもなるとせっかく作成した先の成果物は、だんだんと現実から乖離してメンテナンスもままならず、役に立たなくなることがあまりにも多い。
最終的にはどうなるのか?というと、実装者の裁量にまかされるわけです。
本末転倒な話です。

さて、では、視点を変えてテスト項目から洗い出してゆくとどうなるのか?
結局は同じことなのです。
ユーザ視点になるとテストの項目で表され、開発者の視点で見ると仕様書になるわけです。
つまり、これは表裏一体。結局、同一、同じものを言っているわけです。
両者ともにウォーターフォールのV字型機構で対応して表され、インプットとアウトプットで対になるわけですから、ごく自然なことだと思います。

そのことのひとつの証明として何日間かかけてドメインを中心軸として、左右対称の形を描くユニットテスト、モックアップなどを取り上げてきたわけです。
いずれの思想も根底にあるのは、通常の習慣とは逆にモノゴトを観察する知恵なのです。

2015年7月27日月曜日

オニオンスライスのオートメーション

ふだん単体テストのオートメーションにあまりなじみのない方のために、少し具体的な話をしてみようと思います。
そして例によって具体例は先週の続きです。
以下のレコードをデータベースから取得して画面に表示するためのコンテキストをテストします。

<朝食>
     <食べたものリスト>
          <食べたもの>トースト</食べたもの>
          <食べたもの>ハムエッグ</食べたもの>
          <食べたもの>ひよこ豆とレタスとトマトのサラダ</食べたもの>
     </食べたものリスト>
     <飲み物>コーヒー</飲み物>
</朝食>

1)まずは、期待値を構成します。
listと飲み物はprivateスコープです。
var expected = new 朝食();

このオブジェクトはコンストラクタの中で次のように初期化されます。
this.list = new 食べたものリスト()
list.Add( new 食べたもの("トースト") );
list.Add( new 食べたもの("ハムエッグ") );
list.Add( new 食べたもの("ひよこ豆とレタスとトマトのサラダ") );
this.Set飲み物 ( "コーヒー" );

2) 次に被検クラスを起動して、返される値をキャッチします。
var target = ある朝に食べた朝食() ;
朝食 actual = target.Find();

3)最後に期待値と実測値が同じであるか判定します。
for ( 朝食 a : actual ) {
     for ( 朝食 e : expected ) {
          assertEquals( e.Get食べたもの, a.Get食べたもの );
          assertEquals( e.Get食べたもの, a.Get食べたもの );
          assertEquals( e.Get食べたもの, a.Get食べたもの );
     }
}
assertEquals( expected.Get飲み物, actual.Get飲み物 );

ここではじめてに期待したオブジェクトとデータベースから返却された実測値が同一であること、つまり、期待に沿ったものであるかを判定しています。
assertでかかれた比較がイコールで結ばれればテストは成功なので、グリーンシグナルとなるわけです。
ただし、正確に言うと、Listは投入された要素の順番が保証されないので、ここはもっと別の記述になるはずですが、テストの流れをシンプルにご紹介するために、あえてこのように書きましたことを注意してください。

こうやって見てみると意外と簡単ですね。
とは言え、このテストではデータベースに直接接続していますから、本来はもっと工夫が必要ですし、これでは不充分です。
加えて仕様が変化したときに、当然、このテストコードでは整合しなくなるわけですから、もっと柔軟な展開も頭の中に入れておかなければなりません。
と、いろいろ考えることは多々ありますが、それでも、この方法には価値あることが少なからずあると思います。
それを知るには実際的な体験が必要です。

よくテストコードのメンテナンスが大変だ、という意見も聞かれますが、それはテストとしての構造設計がうまくできていないことに原因があることが大半です。
変化に強い実装コードのノウハウは、そのままテストコードの柔軟性にも同じように展開できるはずです。平面的な構造設計だけでは、そもそも実装コードのメンテナンスもままなりません。ぜひ、このような視点に注意を払って挑戦してみてください。
そこではじめて単体テストのオートメーションの価値に気がつくと思います。

2015年7月24日金曜日

オニオンスライスの単体テスト

昨日はヘキサゴナル・アーキテクチャの紹介でした。
この実装パターンは実はモックアップの導入だけではなく、ほかの部分でも効果を発揮します。今回はそのことについて少し書こうと思いますが。

しかしながら、賛否両論の多いアイディアでもあります。

昨日、モックアップは本番実装の鏡影だということを書きましたが、ということは、ほぼ同じような特性を持ったエンティティクラスにも展開が可能だということが容易に推測できます。

それは、つまり、ユニットテストにおいてです。
たとえば、本番に使用するエンティティとして、昨日使用した 朝食クラス を使います。
このクラスはデータベースの検索結果を格納して、データベースのアクセスレイヤーを構成するモデル -> 上位のパーシステンス -> そして、画面直下のプレゼンテーション層までハンドリングされる、データの保持という役割をもったオブジェクトです。

それでは、プレゼンテーションの下層を位置づけるメソッドをテストすることを考えてみます。画面の背後で動作するこのコンテキストは、任意の朝食データを検索して返す というように動作するはずです。
このコンテキストの期待動作を確かめるにあたって、その正当性を判定するには、返されるはずの朝食オブジェクトの内容と同一のデータを保持するオブジェクトを期待値クラスとして定義すると思います。
これは、つまりユニットテストの期待値に相当します。データベースから返される実測値は、本番実装の朝食エンティティクラスのオブジェクトです。
この2つのオブジェクトが同一であれば… 同じ内容のデータを保持していて、AssertEqualで結ばれれば被検対象のコンテキストは正しく動作し、グリーンシグナルが点るはずです。

ここで気がついた方はするどいです。
被検対象のコンテキストを軸に(つまり、ここはドメインとなります)expected と actual はまったく同様のデータになる、という特性が得られます。
これがオニオンスライス、または ヘキサゴナル・アーキテクチャの特性でもあります。
ドメインは常に中心軸として捉えられ、その左右の線対称の部分に、expected のインプット(期待するデータ)と actual(実測結果)が配置され、同一の重量配分の元にバランスします。したがって、テストが成功したことを表します。
これがユニットテストにおける、ひとつの合理性とその実践アイディアです。

おそらく、なんて面倒な! と感じる方もいらっしゃるかもしれません。
そのために賛否両論が巻き起こるテーマとなり得るわけです。

このテクニックが現場の実装で成り立つのか? という議論は、少々本質を逸脱すると思いますので、それはまたの機会に。