今日は昨日の題材を使ってオニオンスライス・パターンを考えてみたいと思います。
オニオンスライスは後ほど説明するとして、目指すのはモックアップの作成です。
こんなことを想定してみます。
・明日までに任意の日に食べた朝食の内容を画面に表示するようなプレゼンが見たい。
・ただし、データベースがまだ構築されていない。
・しかしながらサンプル画面を作るのではなく、そのまま本番に流用できる精度が欲しい。
・なぜなら時間がないし、手戻りを生み出したくないから。
本当に勝手なものです。
この程度のことであれば、サクッと画面を作ってボタンか何かを押したタイミングで画面に情報が表示されるような「サンプル画面」の実装を作ってしまえるでしょう。
そこを、ほぼ同じような手軽さで、ある程度の構造を持ち、すぐに本番に流用できるようなメカニズムを考えてみましょう。
パラメータやデータベースのアクセスレイヤーは、今回の本質ではないので割愛します。
それでは、思い出す意味で、ボタンを押して画面に展開するデータは昨日提示したオブジェクトを使用します。
<朝食>
<食べたものリスト>
<食べたもの>トースト</食べたもの>
<食べたもの>ハムエッグ</食べたもの>
<食べたもの>ひよこ豆とレタスとトマトのサラダ</食べたもの>
</食べたものリスト>
<飲み物>コーヒー</飲み物>
</朝食>
こんな感じです。
このオブジェクトは本番用に使うとしてモックアップのデータオブジェクトのクラスを考えます。
class 朝食モックアップ extends 朝食 { … }
こんな感じです。
ついでに、朝食クラスはこんな風に定義します。
class 朝食 implements I朝食
モックアップは、本番用の朝食クラスを継承して同じ構成の朝食モックアップを定義します。
当然ながらコンストラクタはこのようになります。
public 朝食モックアップ() { super() }
つまり、実態は本番と同じということになります。
これを返却用のオブジェクトとして使用することにします。
次にビヘイビア(ふるまい)を表す検索用オブジェクトを考えてみます。
まず、本番用はこのようになります。
class ある朝に食べた朝食() implements I食事 { … }
そして、こんな検索メソッドを持ちます。
public virtual I朝食 Find() { return 本来はデータベースから取り出すのだ! }
次にモックアップ用のビヘイビアを定義します。
class ある朝に食べた朝食モックアップ() extends ある朝に食べた朝食() { … }
本番用のビヘイビアを継承するわけです。
したがって、検索メソッドはオーバーライドされ、朝食を表すモックアップエンティティを返すように定義します。
public overrides I朝食 Find() {
return new 朝食モックアップ()
}
この部分で、つまり、朝食モックアップのコンストラクタの中で、画面にプレゼン用として表示すべきデータを与えて初期化します。
ここまでで本番用とモックアップ用の2種類の検索メカニズムを定義しました。
2種類とはいえ、構造的にはまったく同様のことを表現しています。
これを比喩的なメタファーとして、オニオンスライスと言います。
または、ちょうど鏡を挟んで線対称として捉えることができることから、ヘキサゴナル・アーキテクチャと呼ばれたりもします。
本質は、モックアップは本番の鏡影として表します。
さて、最終段階として画面に結果として表示するコンテキスト(文脈)の部分を定義します。
class I朝食 朝食Repository(I食事 behavior) { … }
このコンテキストはこんな風に使います。
まずは、モックアップを使う場合。
var context = new 朝食Repository( new ある朝に食べた朝食モックアップ() );
var 結果 = context.Find();
これで、モックアップの朝食を表すエンティティが返されるので、それを使って画面に描きます。これで明日のプレゼンは乗り切ることができますね。
本番に切り替えるときは、以下のようになります。
var context = new 朝食Repository( new ある朝に食べた朝食() );
var 結果 = context.Find();
パラメータとして渡すビヘイビアを変更するだけです。
画面の中も変更する必要もないし、ビジネスロジックも変更する必要はありません。
そもそも本番とモックアップを分岐させる If DEBUG のようなロジックさえ存在しません。
コンテキスト、ビヘイビア、エンティティの構造に置き換えられてしまったのです。
このように大局的な視点でロジックを構造に置き換える作業は、データベースシステムだけではなく、制御などの分野でも有効です。
ぜひ、試してみてください。