String非推奨の勧め 海外編

先日、String非推奨の勧め - minghaiの日記という記事を書いたのだが、海外で同じような問題を議論していたので紹介する。


JavalobbyにてStringは汎用データ型として良くないというBlogが紹介されている。

http://www.javalobby.org/java/forums/t82715.html

オリジナルはPeter Veentjerさんの次の記事だ。
String is not a good universal datatype | Blog of Peter Veentjer


まずPeterさんの主張を引用しよう。

1. operations on the strings are scattered all over the place. If you need a function to format a phonenumber, it often is created adhoc instead of in a suitable class. This makes logic very hard to find back and the consequence is that you get more code-duplication.
2. it is easy to get inconsistent data: a phonenumber of 20 digits for example is not possible, but you can store anything in a String. This makes it very difficult to control the consistency of the data.
3. you don’t have any typesafeness: you could pass a telephonenumber to a bankaccount format function. Using a specific datatype instead of a String, makes it possible to get compiletie typesafeness and this is a good way to decrease developmenttime.
4. it is more difficult to understand what a field means (especially if the documentation is not that great): if you have a field of type String and name imsi, how can you tell it contains a phonenumber? If the field is of type Phonenumber, you know at least it is a phonenumber.

1に関しては皆同意できるだろう。Stringを基礎型に用いれば、特に日本式にCompositなID文字列を採用した場合に、String演算の式はそこら中に存在することになるだろう。これは明確にDRYの原則に反する。


2も私の主張と同じだ。Stringを引数に取れば、例え20桁の文字列を期待しようと何桁の文字列でも渡しうる。ここで流れにそっているからとチェックを怠れば必ず障害が発生するし、ただのStringではチェック式も1と同じくDRYに反してコピペの大量発生が存在する。この場合に仕様変更が発生するととても痛いし、変更漏れの危険が大きい。


3に関しても同意だ。Stringを用いれば電話番号に顧客番号を渡すことも用意に可能だ。Joshua Blochも*1にてAPIの設計においてStringの乱用を戒めている。


4も3に順ずる。Stringばかり使えばAPIはわかりにくくなり、潜在的なバグは多くなる。これはJavaScriptのような引数に型のない言語で開発を行った経験があれば良くわかるはずだ。C言語のstrcpyの引数順で障害発生した経験がある人も多いだろう。

コメント欄への感想

紹介記事からして次のように始まり、軽いショックを受けた。

I personally disagree and find Strings more useful especially when storing information in the db

何が便利なのか書いていないが、メリットに対してデメリットがあることを気にするかどうかで主張は変わるだろう。


次にオリジナルの記事の最初のコメントでさらに強いショックを覚えることになった。

It is obvious you don’t have much real world experience. Beginners feel this way and design each data type separately. Then after the project is late (or cancelled) because they have to make so many custom classes to support the custom types, they learn that quite often, it is OK to use Strings and accept that there might be bad data.

海外でもいるんだなぁ、というのが感想だ。
こういう「現実での経験」などという言葉を持ち出す人には大した技術者がいないというのが私の実感だ。
このような人たちにはより良い解が存在するという仮定が頭から抜けていて、思考停止に陥っていることが多い。
日本でもクラスが多くなることをやたらと嫌がる人がいるが、これはクラスの設計に一貫性がなかったり、粒度が細かすぎたりするからだろう。
そうではない。
オリジナルの記事のコメント欄でもJavaLobbyのコメント欄でも似たような議論が繰り返されているが、Stringの単なる継承を作るのが本意ではない。
まともなクラス設計を行えば、必ずテーブルレベルの大きさになるはずだ。
学習曲線がどうのという意見も見られたが、まともなBean(POJO)を作る場合にそんなことは問題にならないはずだ。
実際、オリジナルのコメントは2,3,4と続いて「RealWorld」のプロフェッショナル氏に対する反論が続く。


6はもう少し丁寧な反論だが、Stringなら開発期間が短く済むというのが解せない。単純に直感によるもので実際と異なるのではないだろうか。
Peterも私も、デバッグと障害対応を足したら恐らくまともな型設定を行ったほうが短いと思っているはずだ。特に私のように障害多発プロジェクトに後から入れられる経験が多い者としてはStringばかり使うプログラムに怒りを感じる。決まってNullPointer、IndexOutOfBoundsの例外、それにDBでの桁あふれを引き起こしているのだ。


こういうものに正解はないかもしれない。しかし規模の問題が、各自の前提条件の違いとなり、議論にまとまりが出ていないようにも感じる。
前回の記事でも書いたとおり、Stringの乱用は上記の問題だけに留まらず、intの10倍近いメモリー消費など他の問題も存在する。
私はこれからもデータ型にStringはなるべく非推奨にすることをお勧めする。