2012年6月19日

型破りと型無し

「型破り」という言葉と「型無し」という言葉がある。

「型破り」は「型」の中から外側に向かって型に収まらないことをやってのける。
すなわちしっかりと型ができている人間のすることである。

対して「型無し」とは「型」ができていない、基礎のできていない人間が、
自分勝手に型破り風なことをすることを言う。

周回遅れエンジニアは基本「型無し」ですが、
ある程度の基礎はつけていないと「型破り」なことをできないということにはすごく共感できました。

よく出会う「カイゼン」のつもりでもただの手抜きのようなことが多々あります。
これは「型無し」なのですね。

2012年6月17日

SimpleDateFormatで日付チェック

文字列をDate型に変換してくれるステキなクラス SimpleDateFormat。
こんな感じで定義していみます。
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
    SimpleDateFormat displayFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS");

検証メソッドはこちら。いったんDate型に変換して、また文字列に戻します。
    private static void parse(String dateString) {
        try {
            System.out.println(displayFormat.format(sdf.parse(dateString)));
        } catch (ParseException e) {
            System.out.println("パース失敗:" + dateString);
        }
    }

SimpleDateFormat(Calendarクラスも?)気が利きすぎているので、あり得ない日付を指定すると、勝手にいい感じで変換してくれます。(コメントは処理結果)
        parse("2000/13/1");      // 2001/01/01 00:00:00.000
        parse("2000/2/30");      // 2000/03/01 00:00:00.000

でも、SimpleDateFormat#setLenient(false)を指定すると、厳密にチェックしてくれます。
        sdf.setLenient(false);

        parse("2000/13/1");      // パース失敗:2000/13/1
        parse("2000/2/30");      // パース失敗:2000/2/30

厳密チェックといっても、0埋めとかはチェックしてくれません。イマイチ気が利かない。
        parse("2000/1/1");      // 2000/01/01 00:00:00.000
        parse("1/1/1");         // 0001/01/01 00:00:00.000

さらに実験。
        parse("0/1/1");         // パース失敗
        parse("-1/1/1");        // パース失敗
これは失敗するんですね。

厳密チェックをやめてみます。
        sdf.setLenient(true);

        parse("1/1/1");         // 0001/01/01 00:00:00.000
        parse("0/1/1");         // 0001/01/01 00:00:00.000
        parse("-1/1/1");        // 0002/01/01 00:00:00.000
0年ってのは無いのですね。

結果が一緒だったので、フォーマットを変更して、再実行。
    displayFormat = new SimpleDateFormat("G yyyy/MM/dd HH:mm:ss.SSS")

0年が紀元前1年になるんですね。
西暦 2000/01/01 00:00:00.000
西暦 0001/01/01 00:00:00.000
紀元前 0001/01/01 00:00:00.000
紀元前 0002/01/01 00:00:00.000

ちなみにフォーマットに指定されなかったものは「0」が設定されるようです。
年を指定しなかったら1970年になります。
        SimpleDateFormat sdf2 = new SimpleDateFormat("MM/dd");
        sdf2.setLenient(false);
        System.out.println(displayFormat.format(sdf2.parse("01/01")));  // 西暦 1970/01/01 00:00:00.000

未設定の値を気にせずに使っちゃうかもしれないので注意が必要ですね。

詳細設計書は必要か?

周回遅れエンジニアはプログラムを作ることがよくあるのですが、
基本設計はあまりやらせてもらうことがなく、
詳細設計からプロジェクトに参加することがほとんどです。

でも、詳細設計書をまともに書けたことがありません。
書けないのです。
(この時点で周回遅れっていうか、10周ぐらい遅れていますね。。。)


周回遅れエンジニアとしては、この詳細設計書が嫌いです。
なぜ嫌いか。

ちゃんと書けないから。。。

というのもありますが、邪魔でしょうがないのです。


どういった点が邪魔か。


・クラス名、メソッド名まで書かないといけない。privateメソッドまで書かせるものもある
リファクタリングしづらい。メソッド名は実態に合っていないとソースコードが読みづらくなるので、作ってる途中で変えたくなります。privateメソッドなんて、処理が長くなったり、共通化できたりしてポコポコできたりするものではないでしょうか?

・設計漏れ・誤りがある
周回遅れエンジニアがやるようなプロジェクトでは、完璧な詳細設計書なぞできません。(世の中に実在するかどうか、私は知りません)なので、必ず設計漏れ・誤りが存在します。基本設計から間違っていることだってあります。それがプログラムを作っているときに発覚します。そうすると、どうなるか。プログラムを修正して、設計書も修正するか、または修正されずに放置されるか。たいていの場合、設計書はとりあえず放置されます。


最初作るときはあってうれしいのですが、作っている間にだんだんと邪魔になってくるのです。
基本設計書+補足資料でいいんじゃないか、と思うのです。
詳細設計書なんていらないんじゃないですか、と。


でも、こんな反論がきます。

1.詳細設計書が無くて、何を元にコーディングして、何を元にテストするのか。
2.詳細設計をしないで作るなんてありえない。いきあたりばったりで作る気か。
3.詳細設計書は納品物です。


さて、どうやって倒そう。
あなただったらどうやって倒しますか?


周回遅れエンジニアは倒せてないんですけどね。。。。

「1.」に関しては、基本設計書と補足資料ですかねぇ。。。
「2.」関して言えば、詳細設計書を作らないだけで、方式設計や補足資料はできてきます。それに周囲のエンジニアのレベルですと、作ってみないとわかららないことがたくさんあるのです。そんな人たちに完璧な設計書をつくれと?それは無理です。
「3.」・・・これはJavaDocで我慢してもらいましょう。。。JavaDocはちゃんと書きますよ、ええ、クラスとpublicメソッドは。


世の中のプロジェクトはどうなっているのでしょう。
ダメダメな周回遅れエンジニアに教授してほしいです。