ありがちな例ですが考えて見ましょう。ソートはアルゴリズムの基本です。種類も色々ありますが、
最初にソートの勉強を始めたときは、どのソートを使えばいいのか良く分からなかったりします。
そうでなくても、勉強として色々なソートを比較したい時もあると思います。Strategyパターンを使えば、
違うソートアルゴリズムをプログラムの途中で入れ替える事が可能です。
アルゴリズムを入れ替えるには、そのアルゴリズムのインタフェースを表すものが必要です。
今回は「ソートアルゴリズム」という大きな意味を持つSortインタフェースを定義し、
それを実装する、バブルソートを表す「BubbleSort」と、選択ソートを表す「SelectSort」クラスを定義します。
ここではソートアルゴリズムについては説明しませんが、どちらも基本的なアルゴリズムです。
この2つのソートアルゴリズムを実行中に切り替えることにしましょう。
必要なクラスを表にまとめると下の表のようになります。
Sort |
「ソートアルゴリズム」を表すインタフェース |
BubbleSort |
「バブルソ−ト」を表すクラス |
SelectSort |
「選択ソ−ト」を表すクラス |
ソートアルゴリズムのインタフェースであるSortでは、ソートを実行するsortメソッドと、
アルゴリズムの比較のためにshowStateメソッドを用意します。
showStateメソッドでは、ソートした結果と、比較回数、交換回数を表示します。
BubbleSortクラスとSelectSortクラスの実装は簡単なものなので、ソースを見ていただければ分かるかと思います。
インタフェースを使ったプログラムなので、メインクラスではSort型の変数にBubbleSortクラスと
SelectSortクラスを代入しています。こうすることで、それぞれの実装クラスの詳細にとらわれずに
プログラムを構築することが可能です。
ソースに関して少しだけ説明を加えておきます。メインクラスではjava.util.Randomクラスを使って
乱数を生成しています。その乱数データをdataに代入しているんですが、2つのソートを比較するには
2つの乱数データがなくてはなりません。これはJavaが配列を値ではなく、アドレスで参照しているからです。
Cで言えばポインタとして渡しているってことですね。ですから、片方のクラスにdataを渡してソートを
行うと、メインクラスにあるdataもソート済みになってしまいます。そこで全く別のint型の配列を宣言して、
それぞれを別のクラスに渡しています。また、公平を期すために、乱数データは全く同じものにしています。
アルゴリズムを入れ替える必要というのはなかなかないと思いますが、例えばテトリスのようなゲームを作って、
ユーザが難易度を選択できるようにする時にはこのパターンが役立つでしょう。デザインパターン全般に言える
ことだと思いますが、本当に適切かどうかをよく検討してから導入するのがいいと思います。
|