関心の分離(SoC)は、コンピュータサイエンスとソフトウェアエンジニアリングにおける設計原則であり、複雑な問題を、たとえ同じシステムに属していても個別に分析、対処、管理できる明確な関心事(側面または問題)に分割すべきであるという考え方です。これにより、一度に1つの問題に集中することができ、認知負荷と複雑さを軽減できます。[ 1 ]
関心の分離は、時間的(ソフトウェアライフサイクルにおけるアクティビティの順序付けなど)、品質的(正確性と効率性を別々に扱うなど[ 2 ])、視点的(データフローと制御フローを別々に分析するなど)、またはサイズ(モジュール性)[ 1 ]など、いくつかの方法で実現できます。
モジュール性とは、システムコンポーネントへの関心の分離(サイズによる分離)の具体的な適用方法です。モジュール型システムでは、各モジュールが単一の関心をカプセル化し、モジュールはより大きなシステムに組み込む前に、個別に設計、実装、理解されます。モジュール性はコード構造におけるSoCの最も一般的で認識しやすい具体化ですが、関心の分離の原則はより広範です。例えば、プロジェクトのタイムラインで要件分析と実装を分離したり、仕様書で機能要件と非機能要件を分離したりすることは、必ずしもモジュール設計を必要としない、関心の分離の有効な形態です。
エドガー・W・ダイクストラは、 1974年の論文「科学的思考の役割について」[ 2 ]の中で、ソフトウェアの正確性や効率性などの品質に関連して関心の分離という用語を作り出した。
カルロ・ゲッツィは著書「ソフトウェアエンジニアリングの基礎」[ 1 ]の中で、ソフトウェア生産における継承された複雑さに対処する主要な方法として関心の分離を提唱している。
Philippe Kruchten は、論文「Architectural Blueprints—The “4+1” View Model of Software Architecture」[ 3 ]の中で、大規模なアーキテクチャに対応するために 5 つの主要なビューで構成されるモデルを使用しました。これは基本的にビューベースの関心の分離であり、各ビューはアーキテクチャの異なる側面に焦点を当てています。
カルロ・ゲッツィによれば、ソフトウェアのモジュール化の主な利点は、関心の分離の原則をシステムコンポーネント、つまり「モジュール」に適用できる点にある。モジュールの詳細は個別に扱うことができ、さらにモジュールの統合は、ソフトウェアモジュールの全体的な特性とそれらの関係性を扱う独立した関心事として扱われる。
フィリップ・ラプラント氏も、関心の分離はソフトウェア設計、コーディング、時間、ソフトウェア品質に適用できると述べている。[ 4 ]
関心の分離という用語は、おそらくエドガー・W・ダイクストラが1974年の論文「科学的思考の役割について」の中で造語したと思われる。[ 2 ]
私が考える、あらゆる知的な思考の特徴を説明してみましょう。それは、主題のある側面を、その一貫性を保つために、孤立させて深く研究しようとする姿勢です。そして、自分が取り組んでいるのは、その側面の一つに過ぎないということを常に意識しているのです。プログラムは正しくなければならないことは分かっていますし、その観点からのみ研究することができます。また、プログラムは効率的でなければならないことも分かっていますし、その効率性については、いわば別の日に研究すればよいのです。別の気分で、そのプログラムが望ましいかどうか、そしてもし望ましいなら、なぜなのかを自問することもあるでしょう。しかし、これらの様々な側面を同時に扱っても、何も得られません。むしろ逆効果です。これは私が時々「関心の分離」と呼んでいるもので、完全に可能ではないとしても、私が知る限り、思考を効果的に整理するための唯一の有効な手法です。私が「ある側面に注意を集中する」と言うのは、まさにこのことを意味します。他の側面を無視するということではなく、ある側面の観点からすれば、他の側面は無関係であるという事実を正当に扱うということです。それは、単一の目標と複数の目標を同時に意識することである。
15年後、関心の分離という概念が広く受け入れられるようになったことは明らかでした。1989年、クリス・リードは『関数型プログラミングの要素』[ 5 ]という本を執筆し、その中でSoCについて説明しています。
プログラマーは同時にいくつかのことをしなければならない。すなわち、
- 計算対象を記述する。
- 計算処理の順序を小さなステップに分割する。
- 計算中のメモリ管理を整理する。
リード氏は続けてこう述べている。
理想的には、プログラマーは3つのタスクのうち最初のタスク(計算対象を記述すること)に集中でき、他の2つの管理的なタスクに気を取られないことが望ましい。もちろん、管理業務は重要だが、それを主要なタスクから分離することで、より信頼性の高い結果が得られる可能性が高くなり、管理業務の多くを自動化することでプログラミング上の問題を軽減できる。
SoCには他にも利点があります。例えば、プログラムからシーケンス処理やメモリ管理の詳細が省略されると、プログラムの検証がはるかに容易になります。さらに、異なるマシンアーキテクチャで評価される場合、計算対象の説明には、その実行方法に関する詳細な手順説明を含めるべきではありません。数千個のプロセッサがマシン全体に分散され、グローバルストレージではなくローカルストレージを備えた高度並列マシンを使用する場合、ストアに格納されたデータオブジェクトへの小さな変更のシーケンスは、計算方法の説明として不適切である可能性があります。
管理面を自動化するということは、言語実装者がそれらに対応する必要があることを意味するが、その分、異なるマシンアーキテクチャを用いた非常に多様な計算メカニズムを活用できる機会が大幅に増える。
SoC(セキュリティ・オーバーヘッド)はインターネットの設計において極めて重要です。インターネットプロトコル群では、懸念事項を明確に定義されたレイヤーに分離するために多大な努力が払われてきました。これにより、プロトコル設計者は1つのレイヤーの懸念事項に集中し、他のレイヤーを無視することができます。たとえば、アプリケーション層プロトコルであるSMTPは、信頼性の高いトランスポートサービス(通常はTCP )上で電子メールセッションを実行するためのあらゆる詳細に関心を持ちますが、トランスポートサービスがどのようにしてそのサービスを信頼できるものにするかについては全く関心を持ちません。同様に、TCPはデータパケットのルーティングには関心を持たず、ルーティングはインターネット層で処理されます。
HTML、CSS、JavaScriptは、ウェブページやウェブサイトの開発において相互補完的に用いられる言語です。HTMLは主にウェブページの内容構成に、CSSはコンテンツの表示スタイルを定義するために、そしてJavaScriptはコンテンツがユーザーとどのようにインタラクトし、どのように動作するかを定義するために用いられます。歴史的には、CSSが導入される以前は、HTMLがセマンティクスとスタイルの両方を定義する役割を担っていました。
主題指向プログラミングでは、個別の関心事をそれぞれ独立したソフトウェア構成要素として扱い、それぞれを同等の立場で扱うことができます。各関心事は、共通のオブジェクトを整理するための独自のクラス構造を提供し、互いに交差する部分では、状態とメソッドを合成結果に提供します。対応ルールは、さまざまな関心事内のクラスとメソッドが相互作用する箇所でどのように関連しているかを記述し、複数の関心事からメソッドの合成動作を導き出すことを可能にします。多次元SoCでは、関心事の分析と構成を多次元「マトリックス」として操作できます。このマトリックスでは、各関心事がさまざまな選択ポイントを列挙する次元を提供し、マトリックスのセルには適切なソフトウェア成果物が格納されます。
アスペクト指向プログラミングでは、横断的な関心事を主要な関心事として扱うことができます。たとえば、ほとんどのプログラムには何らかのセキュリティとログ記録が必要です。セキュリティとログ記録は二次的な関心事であることが多く、主要な関心事はビジネス目標の達成です。しかし、プログラムを設計する際には、セキュリティを二次的な関心事として扱うのではなく、設計の最初から組み込む必要があります。後からセキュリティを適用すると、セキュリティモデルが不十分になり、将来の攻撃に対して多くのギャップが残ってしまうことがよくあります。これは、アスペクト指向プログラミングで解決できます。たとえば、特定のAPIへの呼び出しが常にログに記録されるように、またはプログラムの手続き型コードが例外を処理するか伝播するかに関係なく、例外がスローされたときにエラーが常にログに記録されるように、アスペクトを作成できます。[ 6 ]
認知科学や人工知能の分野では、デイビッド・マーの分析レベルを参照することが一般的です。研究者は、知能の特定の側面が何を計算する必要があるのか、どのようなアルゴリズムが用いられているのか、あるいはそのアルゴリズムがハードウェア上でどのように実装されているのかといった点に焦点を当てている場合があります。このような関心の分離は、ソフトウェアおよびハードウェア工学におけるインターフェースと実装の区別と類似しています。