見出し画像

コードにうまく歳を取らせる

English version.

IT業界で働いていると「うまく歳を取れていない」コードをよく目にすると思います。

どういう意味かと言うと、設計などの問題から、月日が経つにつれ、運用保守や機能開発などがどんどん難しくなるようなコードのことです。自分の経験から具体例を上げると…

  • 利用しているバージョンのRubyがハードウェアのアップグレードにより互換性がなくなり、古いバージョンのRubyを独自コンパイルしないといけない。

  • もう開発が終わっている言語を書くために独自フォントをインストールしないといけない(実際にそういう言語あります)。

  • 自分のデスクの下に古いSolarisマシンを置いて、Solarisでしか動かないレガシーシステムを動かさないといけない。

理想から、かなりかけ離れた状況ですが、いずれも実際に起きた話ですし、みなさんの身の回りでも起こり得ると思います。

ただ、最初に開発していたエンジニアが少し考えるだけで、その後保守運用をするエンジニアが助かるような工夫ができるのでは、と思っています。この記事では自分の経験を元に2つほどそういった工夫を紹介したいと思います。

1. 依存関係を固定する

最近の開発では1つのソフトウェアを作る場合にも依存関係がたくさん存在し、その管理も大変です。ある特定のライブラリがGitHubから突然消えたり、利用している関数の定義が変わってしまったりする可能性があります。また、ソフトウェアの下層に位置するOSなどのインフラも依存関係と考えられます。OSがアップデートされて、ソフトウェアとの非互換が崩れてしまうのが良い例ですね。

こういう場合には依存関係を固定することが重要になってきます。例えば、

  • Dockerなどを利用してコンテナ化を行い、OSとライブラリの依存関係を固定する。

  • Vendoring することにより依存ライブラリをプロジェクト内に組み込んで固定する。

  • 依存関係管理ツールを使って、ライブラリの依存関係を固定する。

などですが、実用ではこういうのを組み合わせて行うことが多いです。

自分の例を上げると、以前JRuby上で構築されたオープンソースソフトウェアを使ったETLシステムを構築したことがあるのですが、実行するための要件はかなり厳しく、特定のバージョンのJVMと特定のバージョンのGem(Rubyライブラリ)を使わないと動かないものでした。1つでもズレると、ソフトウェアは動作しません。
この問題を避けるため、上に書いたような方法を組み合わせました。必要なJVMバージョンが入ったDockerイメージをベースにしつつ、必要なGemをインストールするDockerfileを書き、それで作成したイメージを使ってコンテナを稼働させました。この構成で3年以上運用していますが、イメージに手を入れることはありませんでした。

このように依存関係を固定することで、依存関係の設定ミスや突然のインフラ変更による動作不具合を避けられます。

2. 設定で変更できるようにする

ソフトウェアはどこかの段階で変更が必要になることが多く、大抵の場合はコード変更を伴います。ソフトウェア・エンジニアの方にとっては当たり前のことなのですが、コードは変更をすればするほどバグが入る危険性が高くなります。そのためコード変更は必要最小限に抑えることが重要です。

コード変更を抑える1つの方法として「設定を設ける」という方法があります。サーバーサイド、フロントエンド、モバイルアプリといったほとんどの主要フレームワークには、データベース接続情報、ホスト名、デプロイ環境(本番、ステージング等)などは「設定」で指定・変更できるようなしくみが良いされています。

自分が思うに「設定可能」にするべきものは上記のようなものだけでなく、変わりうるものはできる限り「設定可能」にするべきだと思います。

先程のETLシステムですが、データを1つのデータベースから別のデータベースに移すだけでなく、「個人情報保護の観点から特定の列を削除する」という要件もありました。
特定の列のときだけコピーしないようなロジックをコードに書いてしまうことも可能だったのですが、個人情報が入り込む可能性がある列は増えることが容易に想像できたため、 列名のリストを別ファイルに外部化し、ソフトウェアがその別ファイルを読み込んで列を削除するよう実装しました。
この仕組みが実際に結構有効で、新しい列を追加する際にコードを変更する必要がなく、テキストファイルの更新だけで済むようになりました。

このように将来的な変更が予想される部分は、できる限りコードにハードコードせずに「設定で変更できる」形を検討することをオススメします。

ちょっとした仕組み化でうまい歳の取り方を

上記のように少し仕組み化ができるだけで、後でソフトウェアを運用保守しないといけないエンジニアにとって、少しでも作業が楽になり、タイトルに有るコードに「うまく歳を取らせること」ができると思います。うまく歳と取らせれば、後々の運用管理で時間を大幅に節約できると思います。

是非、参考にしてみてください。みなさんが古いRubyのコンパイルをしないで済むことを願っています 😄

この記事が気に入ったらサポートをしてみませんか?