サンプルコードの模倣

あまりレイザーラモン住谷には関係が無いのですが、このエントリを読んで少し思ったことがあるので書いておく。
プログラミングとは模倣の繰り返しとかバートランド・メイヤーは書いていたように思う。*1そこで今日はサンプルコードの模倣について少し考えてみる。
今までの私はロッド・ジョンソンが「実践J2EEシステムデザイン」で書かれていたように「サンプルとして不適切なものがエンタープライズ開発には役立つはずが無い」という意見に賛同していた。PetStoreでのパラメータ名や変数名に意味の無い変数名が書かれていたり、Connectionをクローズし忘れたりなどの重大な欠陥などを例としてあげているようだ。前者は良いコーディングプラクティスではないのでサンプルとして不適切だと感じるが後者はどうだろうか?*2
例えば以下のようによく見かけるJDBC APIを用いたデータベースアクセスのサンプルコードの場合はどうか?


try {
Class.forName(driverclass);

Connection con =
DriverManager.getConnection(url,
username,
password);
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(sql);
while(rs.next()){
int column1 = rs.getInt("column1");
String column2 = rs.getString("column2");
System.out.println(column1 + " " + column2);
}
stmt.close();
con.close();
} catch (Exception e) {
e.printStackTrace();
}

こういったプログラムが仮にエンタープライズアプリケーション開発に模倣される場合には以下のような問題がある。

  • Connectionの取得はDriverManager経由では行わずに、プーリングされたDataSourceから行うべきである。なぜならデータベース接続にはコストがかかるためである。
  • Statementを用いずにPreparedStatementを使うべきだ。理由はPreparedStatementがSQLを事前にプリペアするのに対してStatementではプリペアを行わないので実行速度に影響がある。
  • この例もあるサイトにあったサンプルコードを模倣して作ったわけだが、例のごとく例外発生時のConnectionのクローズが漏れている。
  • エンタープライズアプリケーションでJDBC APIを生で使わせるだろうか?フレームワークを導入していていればHibernateなどのO/RマッパーやSpringのJDBC TemplateなどでJDBC APIを抽象化させて使用するだろうから逆にJDBC APIを使う必要は無い。

上の3つの問題はソースコードを修正すれば問題は無いが一番下はどうだろうか?エンタープライズアプリケーションでは一般的にフレームワークを導入するだろうから個々の開発者にJDBC APIを直に触らせる必要は無いし逆に触られては困る場合の方が多いように思う。上記のサンプルコードを書いて公開した方はそこまでの場合を考えてはおらず、おそらくJDBC APIとはこういうものだということを説明したかったのだろう。上記のように考えてみるとサンプルコードは目的によって作られているわけだからその目的に応じて模倣すべきだし、何も考えずにコピペしてエンタープライズアプリケーションの納品コードに貼り付けるプログラマをビルドプロセスで対処すべきではないかと思った。逆にサンプルへ過度な期待をかけるのはどうだろうか?*3
元のロッドの話に戻ると、確かにサンプルアプリケーションではきっちりとConnectionをクローズされてるのが理想的だが、Connectionのクローズ漏れのようなシステムに致命的なダメージを与える重大な欠陥が運用環境になってから判明する状況が問題ではないだろうか?ちなみにFindBugsなどを用いると問題を発見可能だから、エンタープライズアプリケーション開発のビルドプロセスにFindBugsなどを導入すべきだと思われる。理想的にはDriverManagerやStatementを利用しているとビルドプロセス中で警告をするようにCheckStyle等を設定するのが良いと思いました。
まとめ

  • サンプルコードには目的があるのでその目的を意識して模倣すること。お願いだからサンプルコードを何も考えずにコピペしてエンタープライズアプリケーションの納品コードに貼り付けないでくれ!
  • ビルドプロセスをきっちり設計していれば、Connectionのクローズ漏れなどの重大な欠陥があるコードを発見することができる。

*1:書籍が手元に無いためにあやふやな記憶

*2:ちなみにConnectionのクローズ漏れを推奨しているわけではない。

*3:確かにPetStoreはJ2EE開発の雛形という目的があるから、その目的を考えるとConnectionのクローズ漏れは重大な欠陥だとは思います。