モジュール化と選択的無知の実現、そして後方互換性の維持へ[2ページ目]

分散開発への問題に対する技術的答えは、アプリケーションのモジュール化です。すべての構成単位が他の構成単位と直接干渉するように強く結び付いてしまっている一体化された塊と比較すると、モジュール方式のアプリケーションは、分離された小さなコードの塊から構成されます。それらの塊はきちんと隔離され、一意に特定され、他のコードが使用する明確なインタフェースを公開し、正しく機能するために必要な環境(他のコンポーネントや構成単位が正しく機能するために必要な環境)を注意深く記述しています。離れたチームが自分たちのサイクルとスケジュールで担当部分を開発できると考えられていますし、Linuxディストリビューションベンダによっても示されています。そして、1つの中心的な機関(ディストリビュータ)が成果物を組み立てることができます。そして、この方式は、スケジュールとチームが離れていることに起因するリスクを最小化することに役立ちます。また、無知モードでの運営も可能にします。つまり、構成単位を作り出す開発者が依存性を正しく記述すれば、組み立てる人達はコンポーネントの内部についての知識をほとんど必要としませんし、それでも、最終アプリケーションをうまく組み立てられます。

しかし、新たな問題が発生します。コンポーネントは、発展するのです。コンポーネントは、静止しているのではなく、変化していきます。バグ修正、機能向上、新たな機能の追加などにより、APIは絶え間なく変化する可能性があります。そして、結果的に、APIを一意に特定する名前だけを使用するのでは十分ではありません。独立したコンポーネント群が一緒に機能することを保証するためには、コンポーネントが実際に提供しているAPIがどれであるかを特定する必要があります。

たとえば、String.contains(String)を参照するクラスがJavaで書かれていたとしたら、Stringクラスにそのメソッドを提供しているJavaのバージョンは5なので、そのクラスはJava 5で動作できます。しかし、Java 6でも同じメソッドを利用できますので、Java 6でも動作できます。Javaチームの互換性方針により、Java 7の最新ビルドでも利用できます。一方で、このようなクラスは、そのメソッドを提供していない古いバージョンのJavaでは動作できません。したがって、古いバージョンのJavaでは、正しくリンクできません。

実際、クラスやアプリケーションの正確な要件を知る必要がある場合には、呼び出しているすべてのメソッド、および、参照しているすべてのクラスとフィールドを列挙する必要があります。もちろん、依存性の記述は、冗長で、読みにくく、時には、実際のソースコード自身より大きかったりします。クラスが、「私には、コンストラクタとlengthメソッドとindexOfメソッドを持つjava.lang.Stringを提供しているJavaのバージョンが必要です。そして、私のクラスはjava.io.Serializableにも依存しており、それを実装しています」などと言うことを想像してみてください。実際、このようなコンポーネントの実際のバージョンの詳細な仕様は、私が強調したい無知の方式には真っ向から反しています。コンピュータがこのような制約を自動的に検証したとしても、人間にとっては、難しすぎて使用できません。人間は単純な方法を好みます。たとえば、自然数を使用して、コンポーネントの各リビジョンに番号を付けます。そうすれば、「Java 5であれば私のライブラリは問題ありません」と単純に言うことができます。

しかし、単純に番号を使用することは、物事を複雑にする可能性もあります。図2-1に示されるように、(Java 5へ依存している)コンポーネントAと(Java 6へ依存している)コンポーネントBからアプリケーションを組み立てることを想像してみてください。この場合、AとBの両方を実行できる1つのバージョンのJavaが存在する可能性があるので、問題はどのバージョンを使用するかです。この問題を解くために、ほとんどのAPI開発モデルは、互換性という概念を用いてうまくいくようになっています。普通の場合、何らかのAPIがバージョンNで導入されたら、その後のバージョンN+1、N+2、N+3などでもそのAPIは存在することを意味しています。これは、図2-1の例を解決してくれ、組み立てられたアプリケーションはJava 6で実行されるべきだということです。コンポーネントBは明示的にJava 6を必要としていますし、コンポーネントAはJava 5を必要としているだけですが、Javaの2つのバージョン間の互換性のおかげでJava 6でも動作します。実際、そのことで、最終アプリケーションを組み立てる人達の労力をかなり減らしてくれます。彼らは、組み立てる際に、かなり無知になることができます。すべては、1つの「小さな」前提条件を必要とするだけです。それは、後方互換性を維持するということです。後方互換性を維持することは、全く小さな仕事ではありません。かなり複雑であり、何も知らずに行えることではありません。したがって、それが、この本全体を通して私達の関心事そのものなのです。それは、私達が注力する必要がある「選択的無知」の一部です。分散したチームにより作成されたコンポーネントから大きなアプリケーションを組み立てる際に私達の無知を最大化するためには、各チームが個々のコンポーネントとそのAPIを注意深く開発する必要があり、なおその上で、互換性がある方法で行う必要があります。

図1: 1度に2つの異なるバージョンのコンポーネントを必要とするアプリケーション

この記事のもとになった書籍
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詳細ページへ

この記事のキーワード :

人気記事トップ10

人気記事ランキングをもっと見る

企画広告も役立つ情報バッチリ! Sponsored

ClickHouse Cloudが実現した広告運用SaaS「ATOM」のデータ基盤革新、パフォーマンスを向上しながら、運用負荷とコストを削減 11月11日 6:20 AIで開発が加速する時代、品質保証はどう変わる? Tricentisが示すAIエージェント活用の実像 11月9日 6:45 悪用までの猶予が「1分」に迫るフロンティアAI時代に開発と本番を貫く脆弱性管理が必要 10月29日 8:30 欧州CRA対応とSBOM運用。AI生成コードのOSS混入問題の対策とは ――スニペット単位で検出する「FossID」「Insignary Clarity」によるSBOM運用 9月16日 6:40 PostgreSQLからTiDBへ、稼働中SaaSで進める段階的DB移行の実践と再設計への展望 9月7日 6:30 機能安全開発におけるGoogleTestの活用を支援!「Parasoft C/C++test CT」で実現する効率化&AI連携 4月14日 6:30 【CNDW2025】Grafanaが明かす「オブザーバビリティの哲学」ー最小限の労力で実用的なインサイトを得るには 1月23日 6:30 【CNDW2025】プロダクト急増に備える基盤刷新 ーウェルスナビがECSからEKSへの移行で得た知見とは 1月15日 6:30 【CNDW2025】250環境を5人で運用、構築時間は30分に ーKINTOテクノロジーズが語るインフラ基盤組織の作り方 2025年12月18日 6:30 新たな自動化で熱視線! AIエージェントの「推論能力」を支える2つのコンポーネントとは? 2025年11月28日 6:30