Strategy パターン

2012 / 07 / 23 by
Filed under: Coding の素 
Bookmark this on Delicious
[`livedoor` not found]
[`yahoo` not found]

今回 wonderfl に投稿したのは、何の変哲もない、特筆すべきこともないピクセレート・プログラムです。

Pixelate by BitmapData#fillRect – wonderfl build flash online

このコードのオレ的ポイントは何かというと、コーディングに当たって Strategy パターン を意識したという点。
プログラム実行時に複数あるアルゴリズムを選択するパターンだそうですが、ボタンを押して表示形状を変えるところに Strategy パターンを導入しています。

このプログラムの流れは以下のとおりです。

  1. イメージファイルの読み込み
  2. 読み込んだイメージファイルから Vector 配列データを生成
  3. Vector 配列データをビジュアライズ

2. のステップは Pixelation クラスが担っています。
3. のステップは Drawer クラスが担っていますが、下部組織として実働部隊の Behavior クラス群があります。

Pixelation クラスでは、まず読み込んだ画像をグレイスケール、減色した後、BitmapData#getVector でカラーの Vector 配列を取得します。
例えば、6段階に減色した場合、カラー Vector 配列に格納された値は以下の6つのいずれかになります(グレイスケール化しているのでアルファ値以外のチャンネルのうちのどれか一つの値を列記します)。

0x00、0x33、0x66、0x99、0xCC、0xFF

このカラー Vector 配列の値を減色した段階の値に変換します。上の例でいうと以下のようになります。

0(0xFFの段階値)、1(0xCCの段階値)、2(0x99の段階値)、3(0x66の段階値)、4(0x33の段階値)、5(0x00の段階値)

Drawer クラスは Pixelation クラスが生成した段階値データを使って BitmapData#fillRect によってタイルを描画します。fillRect の引数となる Rectangle の width、height の設定に段階値データの値を使います。
0~5 の6段階の場合、タイルの辺の長さはそれぞれ 0、1、3、5、7、9 になるようにしていて、rect#width、rect#height にこの 0~9 の値をどのように代入するかによって、Horizontal になったり Vertical になったり、それらが交互に現れる Alter になったり、 Square になったりするわけです。
で、その rect#width、rect#height の計算部は Drawer クラス内で if 文スイッチしているのではありません。
各ふるまいごとの Behavior クラスを用意して、Drawer クラス内で切り替えています。この複数の Behavior クラスの切り替え、というのが Strategy パターンになるという認識で間違ってないですよね?

ところで GoF のデザインパターンには State パターンというものがあります。
それは「状態」をクラス化し、状態が切り替わったときに「状態クラス」が入れ替わる、という説明がしてあります。
でもこれって Strategy パターンと同じものですよね?

Strategy パターンは「アルゴリズム」に着目し、State パターンは「状態」に着目しているから別のパターンだ、と書籍やウェブなどに書いてありました。
でもこの2つのパターン、構造図はまったく同じだし、その本質も「状況に応じた処理アルゴリズムの入れ替え」という、まったく同じことを実現してるんじゃないかと思うんですよねぇ。

そんなわけで私は Strategy パターンと State パターンは同じものである、と断言したい。



Comments

Tell me what you're thinking...
and oh, if you want a pic to show with your comment, go get a gravatar!





WP-SpamFree by Pole Position Marketing