日々常々

ふつうのプログラマがあたりまえにしたいこと。

誤った共通化

前に書いた キョウミタコード と同系列のネタです。

「コードは共通化するべきである」

これ自体に真っ向から全否定することはまーないかなと思います。例えばこんな感じで処理A1-3から処理Bを呼ぶのパターンはよくあります。

コードの共通化。いいですねー。同じような処理をまとめておくとメンテコストがぐぐっと下がる気がします。これをしなきゃ、どんどんコピペされたメソッドが増えていくことでしょう。同じような処理はまとめていくことは重要です。

ところでこの図を見てください。

……わかります?一度処理をまとめているにもかかわらず、まとめた処理がまた枝分かれしています。それもまとめる前と同じ単位で。コードで書くとこうなります。

class A {
  void method1() {
    B.method(1);
  }

  void method2() {
    B.method(2);
  }

  void method3() {
    B.method(3);
  }
}

class B {
  static void method(int kbn) {
    if (kbn == 1) {
      C.method1();
      // 他にも色々
    } else if (kbn == 2) {
      C.method2();
      // 他にも色々
    } else {
      C.method3();
      // 他にも色々
    }
  }
}

class C {
  static void method1() { /* なんか */ }
  static void method2() { /* なんか */ }
  static void method3() { /* なんか */ }
}

とても残念な感じですね。正直冗談にしか思えませんよね?
その感覚が正しいと思います。こういうバカバカしいコードですが、書いた本人は大真面目。ややもすれば、ここで言うBを共通化とうたったりします。Cが無ければ目立ちにくいのでタチが悪い。

どうしてこうなった

幾つか理由はあると思います。私が想像もつかない理由もあるかもしれません。

  • 単純な知識不足
  • 誤ったパッケージ構成
  • 存在価値の謎な設計書
単純な知識不足

これは比較的簡単な原因。単に継承とか知らないの。そんな輩がプロとしてコード書いてるのもどうなのとか思うのですが。

誤ったパッケージ構成

根が深い問題です。不快な問題でもあります。パッケージスコープが意味をなしていない原因でもあります。

上記のA,B,Cがそれぞれ別のパッケージに配置されているパターンです。例えば action, controller, dao... なんて名前のパッケージが作られている場合。クラスの役割によって置く場所が決められているシステムは何故か多い。原因の根本がどこにあるのかは知りませんが、Strutsとかではよく見ました。そのパッケージ構成は誰が嬉しいんだー。

存在価値の謎な設計書

あまり話題にしたくないSIerあるあるネタ

設計書にクラス名、メソッド名を記述しなくてはいけないのです。クラスや設計書を作るためには、所定の用紙に戻り値とか引数とか書きます。許可が出るのは数日後です。設計変更ですからね。

こうなると何が起こるかと言うと、なるべくクラスやメソッドを追加しないようになります。また、無名クラスとかも作ってはいけないことになります。こんな世界だと、全部staticの方が生きやすい。

まとめ

そもそもこれって「共通化」じゃないんですよね。だから「誤った」。こうすることである程度効率の良くなるところもあるんですが、問題に対する解決方法が誤ってるわけで。結局コピペになったりするし。

何よりもの問題は、こういうコードを見て「そう言うもんだ」と思ってしまう存在。居るんですよ。だって知らないんですもん。割れ窓と言うか、腐ったミカンと言うか、悪貨良貨と言うか。


リーダブルコードとか話題になってますが*1、多分それ以前のお話。

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)

コードそのものよりも姿勢とかだと思うんで、この辺。

達人プログラマー―システム開発の職人から名匠への道

達人プログラマー―システム開発の職人から名匠への道

  • 作者: アンドリューハント,デビッドトーマス,Andrew Hunt,David Thomas,村上雅章
  • 出版社/メーカー: ピアソンエデュケーション
  • 発売日: 2000/11
  • メディア: 単行本
  • 購入: 42人 クリック: 1,099回
  • この商品を含むブログ (347件) を見る
Code Craft ~エクセレントなコードを書くための実践的技法~

Code Craft ~エクセレントなコードを書くための実践的技法~

ほそく - 2012/07/10 22:04追記

なんてものを書こうと思ったんですが、@mike_neckさんがなんか書いてるんでちゃんと見てないけどその紹介で代用。
mike、mikeなるままに…: その設計は適切ですか?
Javaが言語的に不自由なわけでもなく……いや確かに手間なんですけど……上記の例なんてのはなんとでもなる問題。ただ、対象のドメインやその他諸々のコンテキストで最適解はかわると思います。変わるんだってば。とりあえず「ないわー」な実在するコードのお話。この手のコードの間接的な影響はみんな受けてたりする。困ったもんです。

*1:私はまだ読んでなかったり……。