はじめに
エンジニアの世界では「車輪の再発明」1を避けるべきだという格言があります。しかし、保守では、稀に出くわすことがあります。
今回は、独自実装に苦戦させられた経験をお話できればと思います。
独自実装という名の「負債」
私が保守を担当したのは、Javaで構築されたシステムの保守でした。当時としても徐々にレガシー化が進んでいた構成でしたが、ソースコードを読み進める中で奇妙なクラスに遭遇します。
それは、標準的なライブラリ(JSONICやJackson、Gsonなど)を使わず、文字列操作を組み合わせて構築された独自実装のJSON解析処理でした。
開発当時でも、すでにJSONライブラリが存在していたのに、なぜあえて独自に実装したのか。当時の意図は不明ですが、その「独自の車輪」がついに悲鳴を上げることになります。
発見されたバグとその代償
ある日、特定の入力パターンにおいてJSONの解析に失敗するというバグが発見されました。
調査を進めると、以下のような課題が浮き彫りになりました。
- 処理の複雑化: エスケープ文字や入れ子構造の対応が不完全で、修正しようにも正規表現と文字列操作が複雑に絡み合い、影響範囲の特定が困難。
- テストの欠如: 独自実装部分に対するユニットテストが乏しく、修正がデグレを引き起こすリスクが高い。
このまま場当たり的な修正を繰り返せば、将来的にさらなる工数を食いつぶすことは明白でした。そこで、独自実装を廃止し、信頼性の高い既存ライブラリへ移行することになりました。
移行を阻む「環境」の壁
ライブラリの導入自体は単純な作業に思えましたが、レガシー環境特有のハードルが立ちはだかりました。
-
ビルドツールの不在: MavenやGradleといった依存関係管理ツールが導入されておらず、すべてのjarファイルを物理的に
libディレクトリへ配置し、クラスパスを通す必要がありました。 - 古いJavaバージョン: 実行環境のJavaバージョンが古く、最新のライブラリが動作しません。古いバージョンのJavaに対応したライブラリのアーカイブを探し出し、依存する他のjarとの競合が発生しないか、一つずつ手作業で検証する作業を強いられました。
「ライブラリを1つ入れる」という現代では当たり前の作業に、多大な時間と神経を費やす結果となりました。
まとめ:再発明された車輪の末路
この経験から得た教訓は、 「再発明された車輪のメンテナンスコストは、時間の経過とともに雪だるま的に増大する」 ということです。
もちろん、ライセンスやセキュリティーポリシーや学習コストなど、諸般の事情でライブラリを導入できない場面もあると思います。
やむを得ず、独自に実装しなければいけないこともあるでしょうが、その場合は以下のリスクは無視できません。
- コミュニティによる検証の欠如: 独自実装は、世界中の開発者に揉まれているオープンソースライブラリの堅牢性には決して勝てません。
- ドキュメントとスキルの非共通化: 独自実装の仕様は、そのコードを読んだ人にしか理解できません。一方で、標準的なライブラリであれば、新しく入ったメンバーもこれまでの知見を活かせます。
もし、開発の段階で「車輪が再発明されようとしている」とき、それが「負債」にならないか、慎重に検討する必要があります。保守側にとって、最もありがたいのは、よく整備され、知見が蓄えられ、交換も容易な「既製品の車輪」なのです。
移行するにしても、調査等で相応のコストを強いられることになります(運開しているシステムの場合は特に)。
今回の体験談が皆様の参考になれば幸いです。
ここまでお読みいただきありがとうございました。
-
広く利用・確立されている技術を一から作ること(無知か故意の無視かは問わない) ↩