バージョンによってモジュールの依存性を管理する

2014年10月30日(木)
Jaroslav Tulach(ヤロスラフ・ツゥラッハ)柴田 芳樹(しばた よしき)
APIデザインの極意 Java/NetBeansアーキテクト探究ノート
NetBeans開発プロジェクト10年超の蓄積!API設計の経験や考察をまとめた一冊Amazon詳細ページへ

この記事は、書籍『APIデザインの極意 Java/NetBeansアーキテクト探究ノート』の内容を、Think IT向けに特別公開しているものです。

直線ではないバージョン付け

最もよく使用されているソフトウェアの番号付けの方法は、自然数を基にはしていません。代わりに、ドットで区切られた10進システムを使用します。これは、ソフトウェア開発における非直線、つまり、単一方向への開発ではなく、バグ修正リリースやバグ修正リリースのバグ修正リリースなどを表す多くのブランチへ対応するために必要です。図1で示すように、バージョン2よりも機能が少ないと想定される1.1.1などのバージョンが、実際にはバージョン2より後にリリースされる可能性もあります。

図1: ツリーになっているバージョン付け

モジュール方式のアプリケーションの個々の部品はバージョン番号を持っており、たいていは、1.34.8などのようにドットで区切られた自然数から構成されます。新たなバージョンがリリースされた場合には、1.34.10、1.35.1、2.0などのように新たな(辞書順に)大きなバージョン番号を持つことになります。

モジュール方式のシステムでは、他のコンポーネントへの依存は、依存先コンポーネントの識別名と必要な最低バージョンを示すことで表現することができます。XML(Extensible Markup Language)パーサ、インストールされているデータベースのドライバ、テキストエディタ、あるいは、ウェブブラウザが存在することを要求できますし、それぞれが提供しているインタフェースの特定のバージョンを要求することもできます。たとえば、機能のある部分は、バージョンが3.0以上のxmlparserや1.5以上のwebbrowserといったものを必要とするかもしれません。これは、完全な互換性を想定しています。すなわち、組み立てられたシステムは、その構成モジュールの新たなバージョンを使用してもうまく機能すると期待されています。

ライブラリ変更の全部の履歴を単一のバージョン番号で表すことは、ちょっとばかばかしく思えます。それにもかかわらず、それは適度に実用的であり、最も重要なことは、各ライブラリの個々の開発者が変更内容を番号付けされたバージョンへまとめる機会を与え、そのバージョンは容易に認識できる一方で、みなさんが完全に無知になることを可能にしてくれることです。

依存状態管理は、何らかの規則に従う場合にだけ機能します。最初の規則は、新たなバージョンがリリースされたなら、前のバージョンで機能していたすべての契約は、同様に新たなバージョンでも機能するということです。もちろん、言うは易く行うは難しです。そうでなければ、品質保証部門を誰も必要としないでしょう。第2の規則は、外部への依存内容が変更になったら、すぐにそのことを伝える必要があるということです。したがって、モジュール方式のシステムの一部がHTMLエディタの新たな機能に依存することになったら、バージョン1.0以上のhtmleditorへ新たに依存していることを付け加える必要があります。また、バージョン1.7で導入されたウェブブラウザの新たな機能を使用し始めたのであれば、1.7以上のwebbrowserが必要であるように依存状態を更新する必要があります。

コンポーネントのバージョンによっては、回避策が必要なバグを含んでいる可能性があります。そのため、実装バージョンである2つの目のバージョンが、たいていはコンポーネントと関連付けられています。仕様バージョンと異なり、これは、多くの場合、Build20050611などの文字列であり、同じ値の文字列であるかを検査できるだけです。多くの場合、これはバグを回避するためには優れています。なぜなら、バグが、(仕様)バージョン3.1に含まれているからと言って、バージョン3.2にも含まれていることを意味していないからです。したがって、ライブラリに実装バージョンを関連付けることが、あるバージョンのバグ修正や特別な扱いのために役立ちます。

バージョンと依存性の管理では、システム内部の全部品のすべての要件が満たされることを保証するためにマネージャを必要とします。そのようなマネージャは、各部品がインストールされた際にシステム内のすべてが一貫性を保っていることを検査できます。DebianパッケージやRPMパッケージが、Linuxディストリビューションで機能しているやり方です。そこでは、dpkgコマンドとrpmコマンドが、ソフトウェアパッケージのインストールとアンインストールで使用されています。しかし、実行中にある種の実行時状態を処理するために依存性を使用することもできます。

たとえば、NetBeansに基づくアプリケーションは、実行時にロードされるモジュールで構成されています。NetBeansのモジュールシステムは、宣言された依存性を使用して、コンポーネントが必要とするものが存在するかを知るだけでなく、各モジュールに対して親クラスローダが必要であるかも決定します。そうすることで、コンポーネントの選択を、コンポーネントのクラスパスの構成から隔離します。このシステムは、各コンポーネントに対して個別のクラスローダも提供し、独立したモジュールのクラスパス隔離を保証しています。また、各コンポーネントの宣言された依存性を強制もしています。つまり、モジュールは、外部モジュールに対する依存性を宣言しなければその外部モジュール内のコードを呼び出すことができず、その依存性のいくつかが満足できなければ全くロードもされません。

この記事のもとになった書籍
APIデザインの極意 Java/NetBeansアーキテクト探究ノート

Jaroslav Tulach 著/柴田 芳樹 訳
価格:3,200円+税
発売日:2014年05月23日発売
ISBN:978-4-8443-3591-7
発行:インプレスジャパン

APIデザインの極意 Java/NetBeansアーキテクト探究ノート

なぜ、設計の良くないAPIを持つソフトウェアが量産されるのでしょう。エンジニアが良いAPI・悪いAPIについて分かっていない、あるいは、適切なレビューを受けていないからかもしれません。本書では、NetBeansアーキテクトの著者が遭遇してきた様々な誤りを解説し、APIの発展を考慮した設計について詳しく説明。あまり語られることがなかったAPI設計について、貴重な10年間の経験をベースに幅広くノウハウを披露。API設計の技術や知見の水平線を押し広げることができる稀有な一冊です。

Amazon詳細ページへImpress詳細ページへ

著者
Jaroslav Tulach(ヤロスラフ・ツゥラッハ)
NetBeansの生みの親で、初期のアーキテクト。NetBeansは当初、Java統合開発環境として開発され、現在はJavaScript・Ruby・PHP・C/C++などにも対応。今も、オープンソースプロジェクトで開発が続けられている。著者は、NetBeansを支える技術の生みの親として、このオープンソースプロジェクトの成功に貢献。現在も、プログラマーの設計スキルを向上させる新たな方法を探求しつつ、このプロジェクトに参加している。
著者
柴田 芳樹(しばた よしき)
1959年生まれ。九州工業大学情報工学科で情報工学を学び、1984年同大学大学院で情報工学修士課程を修了。以来、様々なソフトウェア開発に従事。ゼロックス社のパロアルト研究所を含め、5年間米国に駐在してソフトウェア開発に携わる。現在はソフトウェア開発、教育、コンサルテーションなどを業務としている。 本書の翻訳を担当。

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています