依存関係
Dependency
あるプログラムやシステムが正常に動作するために、外部の別のプログラム、ライブラリ、モジュールなどを必要とする状態(頼っている関係性)のこと。一方が変更されると、もう一方にも影響が及ぶ性質を持ちます。
🐾 猫で例えると?
手足が絡まる2匹を、相手の状態に影響される関係に見立てています。ただし依存は必ず双方向ではありません。「茶トラがアメショを必要とする」なら、茶トラからアメショへの一方向の依存として表せます。
💻 IT現場における「依存関係」とは?
現代のアプリやWeb開発において、すべてのプログラムを自分たちでゼロから書くことはまずありません。カレンダーを表示する機能や画像を加工する機能などは、世界中の誰かが作ってくれた便利な「ライブラリ」や「フレームワーク」を読み込んで使います。
つまり、自分の作ったプログラムAは、誰かが作ったライブラリBに「依存」して動いていることになります。さらに厄介なことに、そのライブラリB自体も別のライブラリCに依存していることがほとんどです。現場では、この複雑に絡み合った依存関係の糸を管理するために「パッケージマネージャー」という専用のツールを駆使して開発を進めます。
⚠️ 「依存地獄」の恐怖と注意点
依存する部品同士のバージョン条件が両立しないなど、更新や導入が難しくなる状態は「依存地獄(Dependency Hell)」です。
たとえば二つのパッケージが、同じライブラリの互換性のない版を要求すると調整が必要です。別々の版を同時に配置できるパッケージ管理方式もあるため、最新版へ更新しただけで必ず全体が停止するわけではありません。peer dependencyなど、共有が必要な条件も確認します。
package.json(Node.js環境での依存関係の定義例)
次は依存のつながりを示す模式図です。直接使うものだけでなく、その先の間接依存も更新や障害の影響範囲に含まれます。
アプリ
├ 画像処理ライブラリA(直接依存)
│ └ 圧縮ライブラリC(間接依存)
└ UIライブラリB(直接依存)
宣言する許容バージョン:package.jsonなど
解決された依存ツリー:package-lock.jsonなど バージョン範囲の宣言と、実際に解決した版の記録は役割が異なります。npmではロックファイルを管理し、CIでnpm ciなどを使うと再現しやすくなります。ただしOSやランタイム、ビルド設定などの差までロックファイル一つで消えるわけではありません。
🛠️ 依存関係を賢く管理するためのポイント
システムを安全に、長く運用していくためには、依存関係を適切にコントロールする技術が求められます。
- 疎結合(そけつごう)を目指す: プログラム同士の結びつきを弱くし、片方を別のものに差し替えてもシステム全体に影響が出ないような設計を心がけます。基本は一人でも生きていける独立したプロセスが理想です。
- バージョンをロックする: 開発環境と本番環境で異なるバージョンのライブラリが読み込まれないよう、ロックファイルを使用して、依存するバージョンを完全に固定します。
- 依存先の状態を確認: 更新頻度だけで良否を決めず、対応する実行環境、既知の問題、保守方針、ライセンス、代替への移行難度を確認します。成熟して変更が少ない場合と、必要な修正が放置されている場合を区別します。
寄り添う2匹のように、プログラムも別の部品に支えられています。更新するときは直接使うライブラリだけでなく、その先の依存関係や対応バージョンも確認しましょう。依存をなくすことより、どこに何を頼っているかが分かることが大切です。