プロジェクト
これまでファイル単位で説明してきましたが、クラスやファイルという単位は細かすぎて、依存管理には不向きです(管理しきれない)。もう少し大きな単位で区切る必要があって、これが「プロジェクト」を作る動機です。
プロジェクト内のファイルやクラスに関しては、依存関係をあまり気にする必要はありません。仕組み上は、どれだけ複雑な依存関係を持っていても構いません。
(ただし、もちろん、「最初は1つのプロジェクトとして作ってしまったけども、この部分は汎用的に使えそうだから抜き出して別プロジェクトにしよう」というようなこともよくあるので、プロジェクト内であっても依存関係には気をつけておいた方が後々よい結果になることはあります。)
一方で、プロジェクト間の依存関係はきちんと考えないと行けません。ここをサボると、何かを抜き出して使いたい時に、芋づる式にいろいろなものが必要になって困ることがあります。必要な物が増える事による問題の例をいくつか挙げると、以下のようなものがあります。
- 必要なコードが増えて、最終的なプログラムのサイズが肥大化する
- 依存先がアップデートされたときの追従が大変になる
- 動かせないリスク、例えば、「Windowsプログラムで今まで動いていたコードをiOSアプリで使いたい」とか言う時に動かせない可能性が高まる(依存先すべてがiOS実行に対応していないといけない)
プロジェクトの成果物
プロジェクト内のファイルは個別に切り出して使うことをあまり想定しません。プロジェクトというものが、プログラム、あるいは、プログラムを作るための部品の最小単位です。そのため、プロジェクトによって得られる成果物は、1つのファイルにまとめたりします。
C#など、.NET言語の場合は、複数のソースコードのコンパイル結果を最初から1つのファイルにまとめて出力します。(他のプログラミング言語では、バラバラに出力されたコンパイル結果を ZIP 形式ファイルなどにまとめたりするものもあります。) 出力されるファイルは以下のいずれかです。
- ライブラリ … 単体で実行できない。他のプログラムから参照して使う部品。拡張子dll(dymamic link library。dymamicとかlinkとかの言葉の意味はまた別の機会に)。
- 実行可能ファイル … 単体で実行できるプ プログラム。拡張子exe。
.NET の場合、dllでもexeでも中身はほとんど同じ(exeの方にはプログラムの開始地点の情報が多い程度)です。これらは合わせて、アセンブリ(assembly: (組み立て)部品)といいます。
プロジェクトの分け方
プロジェクトを分ける(プログラムを部品化する)1番の動機は、いろんなプログラム、いろんな環境から使いたいというものです。
いろんなプログラムから1つの部品を使う
最初にゲームっぽい例を出したついでですし、ここでもゲームを作ることを考えましょう。
今どきはどんなゲームもオンラインでつながっています。ゲーム本体と同じコードをサーバー側で共有したいことも多いでしょう。また、ゲーム自体のプログラムの他にも、テスト用や、企画者向けのプログラムが必要になったりします。
- ゲーム本体 … ゲーム専用ハードウェア上で動かしたりします。今どきだとiPhoneやAndroid向けも多いです。
- ゲーム サーバー … 複数のプレイヤー間でゲーム本体からのデータを中継するだけの簡単なものから、ゲームの核となる処理がすべてサーバー上で動いている場合まであります。
- テスト用プログラム … ゲーム中の特定の部位だけを抜き出して、そこを重点的にデバッグしたりすることがあります。
- 企画者向けツール … ゲーム中のデータを作ったりバランス調整したりするため、開発者以外の人でも動作を確認しつつデータを編集できるツールが必要になります。
こういう場合、このいずれからも使う部分を別プロジェクトに切り出して、全部から参照して使います。
いろんな環境から1つの部品を使う
Windowsに限って言っても、組み込み製品、デスクトップ、サーバー、ゲーム機など、要件の異なるいろいろな機器の上で動きます。スマホやタブレットでいうと、iOSやAndroidとシェアが分かれていて、そのどちらにも対応したプログラムを書く必要がある場面は多いです。そして、こういう環境が変わると、使える機能(参照できるアセンブリ)が違ってきます。
こういう場合、環境によらず共通して使える部分と、それぞれの環境に応じた(それぞれの専用のフレームワークに依存した)部分に分かれます。