さらに調子に乗る
前回のエントリのさらに続き。前回の setValue を使うやり方だと、想定外によそで値を変えられてしまうかもしれないので、以下のようにしたらどうかと思いました。
public class EmployeeName { private String value; public EmployeeName(String value) { if (value == null || value.length() = 0) { // 例外をスロー } if (30 < value.length()) { // 例外をスロー } this.value = value; } public static EmpoyeeName valueOf(String value) { return new EmployeeName(value); } public String toString() { return value; } }
valueOf を作ったのは、java.lang.Integer なんかと同じ発想です。
Bean Validator は使ったことがないので、あんまり言えないですが、アノテーションを使ってバリデーションを楽にしたいですね。それから O/R マッパのことも考えないと。
さらに別な問題があって、これが根深い。
これを Web アプリケーションなどで使おうとした場合、View 層で入力フォームを作るために結局何文字入る様にしておけばいいのか知りたくなることもあるかと思います。これが難しい。EmployeeName 型のオブジェクト employeeName があるとすると、以下のような使い方ができるようなメソッドを作ればよくない? と一瞬思います。
// 最大文字数を取得 int len = employeeName.getMaxLength();
でも、これは違う。なぜかと言えば、最大文字数はオブジェクトの属性ではなく、クラスの属性だからです。つまり、インスタンス化しなくても何文字までかは決まっているのです。
なので
// 最大文字数を取得 int len = EmployeeName.MAX_LENGTH;
が意味的には正しいのです。しかし、透過的にオブジェクトを扱えるようにするためには getMaxLength() も欲しいわけでして、なんか、そのへんスマートじゃないなぁって思うんです。
そもそも、クラスの存在に最近違和感を感じるのです。特に DI を使うようになってからなのですが、クラス名と オブジェクト名が同じであることが多いんですね。Seasar の SMART Deploy を使っているなら Service クラスとかがそうなんですが。これは、寿命は違うけど結局 Singleton だってことですよね。
Singleton もそもそも変。1つしかインスタンスがないなら、クラスそのものがインスタンス(?)でいいのにって思うのです。
それから、オブジェクトの属性が、クラスの属性に昇華するという現象も変。
たとえば、動物クラスの哺乳類オブジェクトと昆虫オブジェクトがあって、get足の数()メソッドで、それぞれ4と6が返ってくるとします。足の数ってのはオブジェクトの属性だってことですね。ところが、動物クラスを継承して哺乳類クラスを作ると、足の数はクラスの属性になる。
継承クラスは、スーパーセットなんだから機能を限定させるのはおかしいという話もあるかもしれないけど、動物である以上、足の数は知りたいし、「哺乳類」よりも「動物」のほうが抽象的なんだからこの関係がそうそうおかしいとも思えない。
ということで、10数年前 AT&T Release だったころの C++ からはじまって、いまのいままで OPP をやってきたけど、なんか突然 OOP がわからなくなってきた感じです!
こういう疑問が新たな言語に乗り換えるきっかけ、ないしは新たな言語を作るきっかけになるのかなぁ。
このへんの問題を割と解決してくれそうなのが JavaScript なんですよ、私の知ってる言語の範囲では。でも、JavaScript は動的型付けだからなぁ。ソースの追いやすさや安全性を考えると、やっぱり静的型付けがいいんですよね。
ということで、じゃあ、型って何よってなると、static だろうが何だろうが、期待する属性や振る舞いを持っているかということですね。
うーん。これ以上は、体系立った学のない私にはうまくまとめられないです。