モジュール型プログラミングとは、コードベースの機能を独立したモジュールに整理することを重視するプログラミングパラダイムであり、各モジュールはコンピュータプログラム全体のある側面のみを提供し、他の側面は提供しない。
モジュールインターフェースは、モジュールが提供する要素と必要とする要素を表します。インターフェースで定義された要素は、他のモジュールから検出可能です。実装には、インターフェースで宣言された要素に対応する動作コードが含まれています。
サブシステム(特に入出力用)やソフトウェアライブラリの形でのモジュール型プログラミングは、コードの再利用のために使われていた初期のソフトウェアシステムにまで遡ります。モジュール性を目指したモジュール型プログラミングそのものは、1960年代後半から1970年代にかけて、構造化プログラミング(1960年代)の概念をより大規模に応用したものとして発展しました。「モジュール型プログラミング」という用語は、少なくとも1968年7月にラリー・コンスタンティンが情報システム研究所で開催したモジュール型プログラミングに関する全国シンポジウムにまで遡ります。その他の重要な概念としては、情報隠蔽(1972年)と関心の分離(SoC、1974年)がありました。
モジュールは、 ALGOL 68 (1968)の元の仕様には含まれていませんでしたが、初期の実装であるALGOL 68-R (1970) およびALGOL 68C (1970) の拡張機能として含まれ、後に形式化されました。[ 1 ]モジュール型プログラミングのために最初から設計された最初の言語の 1 つは、ニクラウス・ヴィルトによる短命のModula (1975)でした。もう 1 つの初期のモジュール型言語は、ゼロックス PARCによるMesa (1970 年代) で、ヴィルトは、後継のModula-2 (1978)で Mesa とオリジナルの Modula の両方を参考にし、特に後継のModula-3 (1980 年代)を通じて、後の言語に影響を与えました。 Modula のドット修飾名の使用 (モジュールからオブジェクトを参照する場合など) は、レコードのフィールド (オブジェクトの属性やメソッドについても同様) にアクセスするための表記法と一致しており、現在ではC++、C#、Dart、Go、Java、OCaml、Pythonなどで広く使用されています。モジュール プログラミングは 1980 年代から広く普及しました。オリジナルのPascal言語 (1970 年) にはモジュールは含まれていませんでしたが、後のバージョン、特にUCSD Pascal (1978 年) とTurbo Pascal (1983 年) では、「ユニット」の形でモジュールが含まれており、Pascal の影響を受けたAda (1980 年) も同様でした。Extended Pascal ISO 10206:1990 標準は、モジュール サポートに関して Modula2 により近いものとなっています。Standard ML (1984 年) [ 2 ]は、モジュール間のマッピングを行うファンクタ(パラメータ化されたモジュール)を含む、最も完全なモジュール システムの一つを備えています。M.aaM
1980年代と1990年代には、モジュール型プログラミングはオブジェクト指向プログラミングに影を潜め、しばしば混同されました。これは特にC++とJavaの人気によるものです。例えば、C言語ファミリーはC++(元々はC with Classes 、1980年)とObjective-C(1983年)でオブジェクトとクラスをサポートしていましたが、モジュールをサポートしたのは30年以上後のことでした。Java(1995年)はパッケージの形でモジュールをサポートしていますが、コード構成の主要単位はクラスです。しかし、Python(1991年)は最初からモジュールとオブジェクトの両方を積極的に使用し、モジュールをコード構成の主要単位として、「パッケージ」をより大きな単位として使用しました。Perl 5(1994年)もモジュールとオブジェクトの両方をサポートしており、CPAN(1993年)から膨大な数のモジュールが利用可能です。OCaml (1996年)はMLに続いてモジュールとファンクタをサポートしました。
モジュール型プログラミングは現在広く普及しており、1990年代以降に開発された主要なプログラミング言語のほぼすべてに見られます。モジュールの相対的な重要性は言語によって異なり、クラスベースのオブジェクト指向言語では、組織化とカプセル化の単位としてのクラスとの重複や混同が依然として見られますが、これらはどちらも明確に区別された概念として確立されています。
モジュールの代わりに、アセンブリ(C#、F#、Visual Basicなどの.NET言語の場合)またはパッケージ( Dart、Go、Javaの場合)という用語が使われることがあります。他の実装では、これらは異なる概念です。Pythonではパッケージはモジュールの集合ですが、Java 9で導入されたJavaプラットフォームモジュールシステム(JPMS)では、アクセス制御が強化されたパッケージの集合を含む新しいモジュール概念が実装されました。(これらのパッケージは、パッケージマネージャパッケージなど、ソフトウェアにおける他の種類のパッケージとは異なります。)
Javaでは、パッケージという用語はJava言語仕様のモジュール概念に使用されます。[ 3 ]パッケージの集合の一種であるモジュールは、Java 9で導入されました。
一部のPascal方言では、モジュールの概念を表すのに「ユニット」という用語が用いられる。
コンポーネントも同様の概念ですが、通常はより上位のレベルを指します。コンポーネントはシステム全体の一部であるのに対し、モジュールは個々のプログラムの一部です。「モジュール」という用語の規模は言語によって大きく異なります。Pythonでは非常に小規模で、各ファイルがモジュールですが、Java 9では大規模で、モジュールはパッケージの集合であり、パッケージはさらにファイルの集合です。
モジュール概念を正式にサポートする言語には、Ada、ALGOL、BlitzMax、C++、C#、Clojure、COBOL、Common Lisp、D、Dart、eC、Erlang、Elixir、Elm、F、F#、Fortran、Go、Haskell、IBM/360 Assembler、IBM System/38およびAS/400 Control Language (CL)、 IBM RPG 、Java、Julia、MATLAB、ML、Modula、Modula-2、Modula-3、Morpho、NEWP、Oberon、Oberon-2、Objective-C、OCaml、いくつかのPascal派生言語( Component Pascal、Object Pascal、Turbo Pascal、UCSD Pascal )、Perl、PHP、PL/I、PureBasic、Python、R、Ruby、[ 4]などがあります。 ] Rust、JavaScript、[ 5 ] Visual Basic (.NET)、WebDNA。
モジュールをサポートしていない言語の顕著な例としては、 Cと、その原型である C++ と Pascal が挙げられます。ただし、C と C++ では、コンパイルと宣言のインターフェースをヘッダー ファイルを使用して別々に指定することができ、これは一般的にモジュール化とみなされています。モジュールは iOS 7 (2013) で Objective-C に追加され、C ++ にはC++20で追加されました。[ 6 ] Pascal は、最初からモジュールを含むModulaとOberon 、およびモジュールを含むさまざまな派生言語に置き換えられました。JavaScriptはECMAScript 2015以降、ネイティブ モジュールを備えています。C ++ モジュールは、ヘッダー (「ヘッダー ユニット」を使用) との後方互換性を可能にしました。C の方言ではモジュールが使用可能で、たとえばClang はC 言語用のモジュールをサポートしていますが、[ 7 ] Clang の C モジュールの構文と意味は C++ モジュールとは異なります。
モジュール型プログラミングは、C言語のように、名前付きモジュールをサポートするための明示的な構文機能がプログラミング言語に備わっていない場合でも実行できます。これは、既存の言語機能と、コーディング規約、プログラミング慣用表現、物理的なコード構造などを組み合わせることで実現されます。IBM iも、統合言語環境(ILE)でプログラミングを行う際にモジュールを使用します。
モジュール型プログラミングでは、関心事が分離され、モジュールは論理的に独立した機能を実行し、明確に定義されたインターフェースを介して相互作用します。多くの場合、モジュールは有向非巡回グラフ(DAG)を形成します。この場合、モジュール間の循環依存関係は、それらが単一のモジュールであるべきことを示すものとみなされます。モジュールがDAGを形成する場合、階層構造として配置することができ、最下位レベルのモジュールは独立しており、他のモジュールに依存しません。一方、上位レベルのモジュールは下位レベルのモジュールに依存します。特定のプログラムやライブラリは、自身の階層構造における最上位レベルのモジュールですが、さらに上位レベルのプログラム、ライブラリ、またはシステムの下位レベルのモジュールとみなすこともできます。
モジュール型システムを作成する場合、最小構成要素が全体となるようなモノリシックなアプリケーションを作成する代わりに、複数の小さなモジュールを個別に作成し、それらを組み合わせることで実行可能なアプリケーションプログラムを構築します。通常、これらのモジュールは個別にコンパイルされ、リンカによってリンクされます。ジャストインタイムコンパイラは、実行時にこの構築処理の一部を「オンザフライ」で実行する場合があります。
これらの独立した機能は、一般的にプログラム制御機能と特定タスク機能に分類されます。プログラム制御機能は、単一のプログラム向けに設計されています。一方、特定タスク機能は、様々なプログラムに適用できるよう綿密に準備されています。
モジュール設計のシステムは、正しく構築されれば、従来のモノリシック設計よりもはるかに再利用性が高い。なぜなら、これらのモジュールのすべて(または多く)を(変更せずに)他のプロジェクトで再利用できるからである。また、これにより、プロジェクトを複数の小さなプロジェクトに「分割」することも容易になる。理論的には、モジュール化されたソフトウェアプロジェクトは、チームメンバーがシステム全体を作成する必要がなく、システム全体について知る必要すらないという点で、大規模なチームでも容易に組み立てられる。各メンバーは、割り当てられた小さなタスクだけに集中できるのだ。