凪瀬 Blog
Programming SHOT BAR

目次

Blog 利用状況
  • 投稿数 - 260
  • 記事 - 0
  • コメント - 46605
  • トラックバック - 192
ニュース
広告
  • Java開発者募集中
  • 経歴不問
  • 腕に自信のある方
  • 富山市内
  • (株)凪瀬アーキテクツ
アクセサリ
  • あわせて読みたい
凪瀬悠輝(なぎせ ゆうき)
  • Java技術者
  • お茶好き。カクテル好き。
  • 所属は(株)凪瀬アーキテクツ
  • Twitter:@nagise

書庫

日記カテゴリ

 

前回は振りだけでしたが、 今回からデザインパターンとの絡ませ方を紹介してきます。

Strategyパターンの実例

Strategyパターンの実例として java.lang.Comparator および System.Collections.Generic.IComparer によるソートを取り上げます。

Strategyパターンによって切り替わるのは、ソートのアルゴリズムではなく、二つのオブジェクトの比較方法です。 ここではUserというオブジェクトを想定してみます。

Java public class User {
    public String name;
    public int age;
}

このUserのListがあるとして、これを名前(name)順にソートするのか、あるいは年齢(age)順に ソートするのかといったことをStrategyパターンで切り替えるわけです。

そのためのStrategyのインターフェースが先に挙げた java.lang.Comparator および System.Collections.Generic.IComparer となるわけです。

これらの実装クラスをStrategyとしてソートのメソッドに渡すことで、ソート処理の動きを切り替えることが出来ているわけです。

Java Strategyの実装 public class UserNameComparator implements Comparator<User{
    public int compare(User user1, User user2) {
        return user1.name.compareTo(user2.name);
    }
}

Java ソート処理の呼び出し         List<User> list = new ArrayList<User>();
        list.add(new User("ABC"10));
        list.add(new User("BCD"12));
        list.add(new User("CDE"8));
        Collections.sort(list, new UserNameComparator());

C# Strategyの実装     public class UserNameComparer : IComparer<User>
    {
        public int Compare(User user1, User user2)
        {
            return user1.name.CompareTo(user2);
        }
    }

C# ソート処理の呼び出し             List<User> list = new List<User>();
            list.add(new User("ABC"10));
            list.add(new User("BCD"12));
            list.add(new User("CDE"8));
            list.Sort(new UserNameComparer());

ジェネリクスによる具象化

さて、ここでジェネリクスによる具象化がどこで行われるかを見てみましょう。

まずはソート処理を呼び出す部分。こちらではListに入るオブジェクト型を明示しています。 ここのソースコード状ではジェネリクス型パラメータは具象化されているわけです。

そして呼び出されたソート処理の中身、つまるところクラスライブラリ内では当然ながら StrategyであるComparatorやIComparerのジェネリクス型は具象化されない状態で処理されます。 ですから、ソートのアルゴリズム中ではListのオブジェクトが何型かを意識してはいけません。 動的にinstanceofとかで調べることはできますが、覗き見はしてはダメ。

そして、実際のStrategyの具象型部分。ここでは比較を行うオブジェクトは具体化されています。 型が具体化されているのでキャストなどは不要で、Listに格納される型に合わせた処理をそのまま記述できます。

キセルのような中抜きの抽象化

ジェネリクスがない場合、Strategyの実装クラスでキャストしなくてはなりません。 事実、ジェネリクス搭載前のJavaではそのようにコードを書かざるを得ませんでした。

ソートのアルゴリズムを抽象化したら、比較のアルゴリズムの引数まで抽象型(Object型)に なってしまっていたのです。これをジェネリクスによって具象化することができるようになりました。

中間のソートのアルゴリズム中では型は抽象的に、呼び出し部分およびStrategyの実装部分では具体的に というわがままな抽象化がジェネリクスによって可能となったのです。

投稿日時 : 2008年5月30日 17:59
コメント
タイトル
名前
Url
コメント