[Java] こういうときどうすればいいの?
- 2008-03-25
- カテゴリ: その他のプログラミング
- タグ: 安易な発想 Java Haskell
例えば、数値を分数のまま四則演算する有理数クラスが↓のようになっていたとします。
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
1 件のトラックバック
- [Java]こういうときどうすればいいの?
-
どうすればいいんだー>< こういう問題に対応するためのデザインパターンとかあるのかな? Haskellみたいに型変数を使ってadd :: Operatable a => a -> aのように書ければいいのに>< [Java] こういうときどうすればいいの?[文系大学的IT系の悲哀] おもしろそう
- 2008-03-31
- 発信元: 矢野勉のはてな日記

