[Java] こういうときどうすればいいの?

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

[Java] こういうときどうすればいいの?

例えば、数値を分数のまま四則演算する有理数クラスが↓のようになっていたとします。

public class Rational {

    private int numerator = 0;
    private int denominator = 1;

    public Rational(int numerator, int denominator) { ... }

    public Rational add(Rational x) { ... }
    public Rational subtract(Rational x) { ... }
    public Rational multiply(Rational x) { ... }
    public Rational divide(Rational x) { ... }

}

当然、このクラスを使う側では↓のようなコードを書くわけですね。

Rational add(Rational x, Rational y) {
    return x.add(y);
}

このとき、使う側から「有理数だけじゃなくてBigDecimalで扱いたいなー」とか「複素数として扱いたいなー」とか「ベクトル使いたいなー」というような要望が来たとして、↓のようなクラスを書いたとします。

import java.math.BigDecimal;

public class Decimal {

    public Decimal add(Decimal x) { ... }
    public Decimal subtract(Decimal x) { ... }
    public Decimal multiply(Decimal x) { ... }
    public Decimal divide(Decimal x) { ... }

}

public class Complex { ... }
public class Vector  { ... }
public class Matrix  { ... }
...

んで、このときに使う側が↓のようなコードを書くのはあまりにスマートではないので、

Rational add(Rational x, Rational y) { return x.add(y); }
Decimal  add(Decimal  x, Decimal  y) { return x.add(y); }
Complex  add(Complex  x, Complex  y) { return x.add(y); }
Vector   add(Vector   x, Vector   y) { return x.add(y); }
Matrix   add(Matrix   x, Matrix   y) { return x.add(y); }


add(), subtract(), multiply(), divide()を備えたOperatableインターフェースを用意して、↓のように書きたいわけです。

Operatable add(Operatable x, Operatable y) {
    return x.add(y);
}

このとき、Operatableインターフェースっていうのはどう書けばいいんですかね?

問題は、RationalクラスはRationalクラス同士の演算ができればよく、他のクラスも同様に同じクラス同士で演算ができればよいという点。

↓のようにすると、

public interface Operatable {

    Operatable add(Operatable x);
    Operatable subtract(Operatable x);
    Operatable multiply(Operatable x);
    Operatable divide(Operatable x);

}

それぞれのクラスのメソッドが、異なる型との演算をがんばって実装しなきゃいけなくなる。Operatableを実装するクラスがどれだけ現れるかわからなかったらコードを書けないよね><

↓のようにするのはスマートじゃない上に現実的ではないし、

public interface Operatable {

    Rational add(Rational x);
    Decimal  add(Decimal  x);
    Complex  add(Complex  x);
    Vector   add(Vector   x);
    Matrix   add(Matrix   x);
    ...

}

↓のようにすると、「何のための静的型言語ですか?」という話になる。

public class Decimal implements Operatable {

    public Operatable add(Operatable x) throws TypeErrorException {
        if (!(x instanceof Decimal))
            throw new TypeErrorException("'Decimal' type required.");
    }
    ...

}

どうすればいいんだー><

こういう問題に対応するためのデザインパターンとかあるのかな?

Haskellみたいに型変数を使ってadd :: Operatable a => a -> aのように書ければいいのに><

スポンサーサイト

関連記事

トラックバック URL

http://liosk.blog103.fc2.com/tb.php/96-ace3713a

トラックバック

[Java]こういうときどうすればいいの?
どうすればいいんだー>< こういう問題に対応するためのデザインパターンとかあるのかな? Haskellみたいに型変数を使ってadd :: Operatable a => a -> aのように書ければいいのに>< [Java] こういうときどうすればいいの?[文系大学的IT系の悲哀] おもしろそう
  • 2008-03-31
  • 発信元: 矢野勉のはてな日記

コメント

コメントの投稿

お名前
コメント
編集キー
 
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。