システム アーキテクチャ: レイヤード アーキテクチャ

プライマー

システムが 0 から 1 の段階にある場合、製品を迅速にオンラインにできるようにするために、システムの階層化は一般的にソフトウェア開発の主要な領域ではありません.コードが絡み合って結合されているため、この時点ではロジックが不明確になります. モジュールは相互に依存しており、スケーラビリティが低く、1つの部分を変更するだけで全身に影響を与える.

システムが 1 から 100...0 になると、システムは特に複雑になり、この時点でシステムの階層化が議題に上りますが、階層化とは何ですか? なぜ重ね着?ソフトウェアを階層化するには?ソフトウェアレイヤリングの指針となる原則は何ですか? この記事では、答えを 1 つずつ見つけることができます。

レイヤード アーキテクチャとは

レイヤード アーキテクチャは、分割統治型の設計思想であり、レイヤーベースのアーキテクチャ パラダイムです。通常、開発者は、分割統治の考え方に基づいてシステムを複数のモジュールまたはサブシステムに分割し、分割されたモジュールを業務レベルに応じて関連する依存関係および階層関係のグループに分割し、機能グループに応じた機能を実現します。結合された分離。このパラダイムをレイヤード アーキテクチャ パラダイムと呼びます。

レイヤード アーキテクチャの例

図 1 Android システム アーキテクチャ図
図 2 Android アーキテクチャ レイヤーの関係図

レイヤード アーキテクチャの最も典型的な例は、Linux ベースのモバイル オープン ソース オペレーションである Android オペレーティング システムです. Android システムは、トップダウンのレイヤード パラダイムを採用しています. 図 1 は、Google が提供する公式の Android システム アーキテクチャ図です。図 2 は、Android システム図の 5 つのレイヤー間の関係です。

Android オペレーティング システム アーキテクチャの 5 つのレイヤーは次のとおりです。

  • アプリケーション層アプリケーション
  • アプリケーション フレームワーク レイヤー フレームワーク
  • システム ランタイム レイヤー ネイティブ c/c++ ライブラリ/android ランタイム
  • ハードウェア抽象化レイヤー ハードウェア抽象化レイヤー
  • Linux カーネル層Linux カーネル

なぜ重ね着?

ソフトウェア開発の 0 から 1 の段階では、開発者は通常、モジュールの分離を通じてビジネスの分離を達成します. この時点で、モジュールの分離はソフトウェアの分離の「焦点」であり、システムが 1 から 100...0 になると、なぜなら.システムは超大規模な状態にあり、モジュールによる分離はもはや実用的ではありません。現在、ほとんどすべてのソフトウェアは、さまざまな要件の変更に対応するためにレイヤーを介して「懸念事項」を分離しているため、そのような変更を個別に実行できるため、開発者には次のような利点があります。

  • 高い結束: 階層化された設計によりシステム設計が簡素化され、さまざまな層がそれぞれのビジネスに集中できるようになります
  • 低結合: レイヤーはインターフェイスまたは API を介して対話し、依存側は依存側の詳細を知る必要はありません。
  • リユース:重ね塗りで高いリユース性を実現
  • スケーラビリティ: 階層化されたアーキテクチャにより、水平方向の拡張が容易になります

さらに、レイヤード アーキテクチャ パラダイムは、ビジネスの複雑さと技術的な複雑さを分離するための強力なツールでもあります。

コード ベースが大きな泥の塊になってドメイン モデルの整合性が損なわれ、最終的には使いやすさが損なわれるのを避けるために、システム アーキテクチャはドメインの複雑さから技術的な複雑さを分離することをサポートする必要があります。技術的な実装の変更の理由は、ドメイン ロジックの変更の理由とは明らかに異なります。これは、異なる速度で変化するインフラストラクチャとドメイン ロジックの問題につながります。

ここでの「異なる速度での変更」とは、実際には変更の理由が異なることを意味し、これはたまたま単一責任の原則 (SRP) の具現化であり、ビジネスとインフラストラクチャを分離する必要がある理由です。それらの変更は異なります。

要約すると、階層化されたパラダイムの本質は、複雑な問題を単純化し、コードの各層に単一責任の原則に基づいてその役割を実行させ、「高」の設計思想に基づいて関連する層オブジェクト間の相互作用を実現することです。凝集性と低カップリング」。これにより、コードの保守性とスケーラビリティが向上します。小規模なソフトウェアでは、責任の分離の焦点はモジュールまたはクラスです. 大規模なソフトウェア設計では、責任の分離の焦点はレイヤーです. ソフトウェアのレイヤー化の最終的な目標である、レイヤーを介して変更を分離します.

重ね方は?

ソフトウェアの階層化には多くの原則がありますが、ここでは、最初にソフトウェア階層化の 4 つの原則を分析して紹介し、次に「パターン指向のソフトウェア アーキテクチャ: 第 1 巻 (パターン システム)」で提案されている徐々に洗練された階層化を紹介します。 .

指導原則

ソフトウェアを階層化する必要がある理由は、実際には私たちの無意識の認識ルール、つまりマシン指向、ユーザー指向です。マシンはソフトウェアが実行される基盤であり、私たちが構築するシステムはユーザーにサービスを提供します。階層化されたアーキテクチャのレベルが高いほど、その抽象化レベルはビジネス指向およびユーザー指向であり、階層化されたアーキテクチャのレベルが低いほど、抽象化レベルはより統一され、デバイス指向になります。従来の 3 層アーキテクチャは、この認知ルールから派生しています。上位層はユーザー エクスペリエンスと対話に重点を置いており、中間層はアプリケーションとビジネス ロジックに重点を置いており、下位層は外部リソースとデバイスに重点を置いています。したがって、階層化の第一の原則は、さまざまなビジネスを懸念事項に基づいて階層化することです。

レイヤー化の 2 番目の原則は、変更を分離することです. レイヤー化するときは、変更のさまざまな理由に従ってレイヤーの境界を決定し、少なくとも各レイヤーへの変更の影響が最小限に抑えられるようにしますが、これは最小の目標にすぎません.最大の目標は、レイヤー間の相互作用を厳密に禁止することです。たとえば、データベースの変更は、インフラストラクチャ レイヤーのデータ モデルとドメイン レイヤーのドメイン モデルにのみ影響を与える必要がありますが、インフラストラクチャ レイヤーのデータベース アクセス ロジックのみが変更された場合、インフラストラクチャ レイヤーのドメイン モデルに影響を与えるべきではありません。ドメイン層。

レイヤリングの第 3 の原則は、レイヤが直交していることです. いわゆる直交とは、2 つのレイヤの間に関係がないことを意味するのではなく、2 つのレイヤが垂直に交差する 2 つの直線であることを意味します. 2 つの間の唯一の依存点は、2 つの線の交点、つまり 2 つのレイヤー間のコラボレーション ポイントです。このコラボレーション ポイントは、レイヤー間の抽象的なインターフェイスです。2 つの直交する直線は、どちらの直線を延長しても、もう一方の直線 (直線の射影) に影響を与えません。非直交の場合、線が延長されると、常に別の線に投影されます。つまり、この線の延長によって他の線が影響を受けます。

レイヤー化のもう 1 つの原則は、同じレイヤーのコンポーネントが同じ抽象化レベルにあることを確認することです。この原則は、本「Smalltalk Best Practice Patterns」で Kent Beck によって提案された「組み合わせアプローチ」パターンから借用されています。このパターンでは、メソッド内のすべての操作が同じレベルの抽象化である必要があります。これは、「Single Level of Abstraction Principle (SLAP)」と呼ばれます。

階層化されたガイダンス

多くの階層化の原則を理解した後、「パターン指向ソフトウェア アーキテクチャ: 第 1 巻 (パターン システム)」で提案されている、徐々に洗練された階層化アーキテクチャの方法を紹介します。

最初のステップでは、タスクを異なるレイヤーに分割するための抽象的な基準が定義されます。実際のソフトウェア開発では、通常、下位層はハードウェアからの距離に応じて分割され、上位層は概念の複雑さに応じて分割されます。

2 番目のステップは、抽象化基準に従って抽象化レイヤーのレベルを決定することです。

3 番目のステップは、各レイヤーに名前を付けてタスクを割り当てることです。

4 番目のステップは、サービスを標準化し、コンポーネントやモジュールがレイヤーをまたがらないようにすることです。より多くのコンポーネントを上位レベルに配置する一方で、下位レベルはスリムに保たれます。したがって、逆ピラミッドを形成します。

5番目のステップは、階層分割を改善し、1番目から4番目のステップを繰り返し実行することです。

6 番目のステップは、各層の抽象インターフェースを標準化して、J+1 層の場合、J 層が「ブラック ボックス」になるようにすることです。J 層のすべてのサービスを提供できる統一されたインターフェイスを設計します。

7番目のステップは、各層の構造を決定することです。階層構造を決定することは、レイヤー間の関係が適切であることを保証するだけでなく、レイヤー内のコンポーネントが適切な粒度を持つことも必要とします。このようにして、層間関係が完全であるが、内層関係が混沌としている状況が回避されます。

8番目のステップは、隣接するレイヤーの通信メカニズムを標準化することです.レイヤードアーキテクチャでは、一般的に使用される通信メカニズムはプッシュモデルです.JレイヤーがJ-1レイヤーを呼び出すと、必要なすべての情報がサービス呼び出しとともに送信されます. .

9 番目のステップは、隣接する層を切り離すことです. 一般に、階層化されたアーキテクチャでは、上位層は下位層を認識していますが、下位層は上位層の ID を認識していないため、一方向の結合が形成されます。

レイヤー間のコラボレーション

誰もが持っている固有の認識では、階層化されたアーキテクチャが上から下に渡されます. 抽象化レベルの観点からは、抽象化レベルが高いほど、より一般的で公開的であり、このレベルは特定のビジネスからより遠く離れています. このレベルは、通常、プラットフォーム層またはフレームワークの呼び出し元と呼ばれるものです。

トップダウンでは、上位層が下位層に依存する必要があり、これは Dependency Inversion Principle (DIP) と競合します。依存性逆転の原則では、高レベルのモジュールが低レベルのモジュールに依存してはならず、両方とも抽象化に依存する必要があります。この原則は、トップダウン アーキテクチャでは、依存関係をトップダウン方向に渡す必要があると規定した人は誰であろうと、間違った理解であることを明確に思い出させてくれました。依存性逆転の原則の根底にある本質は、不変または安定した要素 (クラス、モジュール、またはレイヤー) に依存することです。これが原則の 2 番目の文です。抽象化は詳細に依存してはならず、詳細は抽象化に依存する必要があります。

依存性逆転の原則は、「インターフェース指向設計」の原則、つまり「実装のためではなく、インターフェースのためのプログラミング」の現れです。高レベル モジュールは、低レベル モジュールの実装について何も知りません。利点は次のとおりです。

  • 低レベル モジュールの詳細な実装は、高レベル モジュールに影響を与える変更を避けるために個別に変更できます。
  • 高レベル モジュールと低レベル モジュールの両方を互いに独立してコンパイルできるため、独立した開発とコンパイルを実現できます。
  • 高レベル モジュールの場合、低レベル モジュールの実装は置き換え可能です。

高レベルと低レベルの両方が抽象化に依存している場合、最下層の特定の実装を高レベル層に渡すにはどうすればよいでしょうか? ハイレベルは両者の「直交点」、つまり抽象インターフェースを通じて具象実装への依存を分離するので、具象実装への依存は外部に移され、具象実装は外部呼び出し元。呼び出し元は、コードを呼び出すときに、基になる特定の実装を高レベルに渡します。ソフトウェア開発の第一人者である Martin Fowler は、このメカニズムを「依存性注入」と明快に呼んでいます。

したがって、最下層への高レベルの依存関係を十分に緩和するには、依存関係の反転と依存関係の注入を組み合わせて、それらをよりよく理解する必要があります。

また、レイヤー間の情報伝達は、必ずしもトップダウンではなく、ボトムアップの場合もあります。たとえば、Android システムの通知メカニズムです。メッセージを受信したAndroidシステムは、上位層のビジネスモジュールにメッセージを通知します。トップダウンのメッセージ伝達を「要請(または呼び出し)」と表現すると、ボトムアップのメッセージは「通知」と表現できます。層と下層. 観測, 下層の状態が変化し, 下層の変化は観測メカニズムを通じて上層に渡される. 上層は下層に渡されたメッセージを消費する. このモードはしばしばオブザーバーモードと言います。

上位層から下位層への「要求(または呼び出し)」を依存性注入と依存性反転の原理で実現するか、下位層から上位層への「通知」をオブザーバーモードで実現するか. これらは、私たちの思考における低レベルへの高レベルの依存に関する私たちの固有の理解を覆しました.

レイヤー間の支援についてより明確に理解できるようになったので、開発中にアーキテクチャ内のレイヤー間の協調関係に直面し、低レベルへの高レベルの依存という固有の考え方を打ち破り、デカップリングの観点から探求する必要があります。 (または結合を減らす) レイヤー間の協力関係の可能性。

さらに、クロスレイヤー呼び出しを許可するかどうか、つまり、各レイヤーが隣接する下位レイヤーだけでなく、それより下位のすべてのレイヤーのサービスを使用できるかどうかなど、レイヤー化されたアーキテクチャの原則 (または制約) を決定する必要もあります。これがいわゆる「ゆるいレイヤードシステム(Relaxed Layered System)」です。

古典的な階層パラダイム

古典的な階層化パラダイムには、主に古典的な 3 層アーキテクチャ、Ali 4 層アーキテクチャ、および DDD ドメイン駆動の階層化アーキテクチャが含まれます。

従来の 3 層アーキテクチャ

従来の 3 層アーキテクチャでは、システムの機能モジュールが、機能に応じてプレゼンテーション層 (UI)、ビジネス ロジック層 (BLL)、およびデータ アクセス層 (DAL) に分割されます。3 層アーキテクチャを図 3 に示します. プレゼンテーション層 UI は 3 層アーキテクチャの最上部に位置し、システムとユーザー間の直接的な対話とメッセージ イベントの処理を実現します; ビジネス ロジック層.データ処理とデータ伝送を実現するBLLとインターフェース データアクセス層と接続されて過去と未来をつなぐ役割を果たし、データアクセス層DALはデータの追加、削除、変更、クエリなどの操作を実装するを実行し、操作結果をビジネス ロジック層の BLL にフィードバックします。

図 3 3 層アーキテクチャ

アリババの 4 層アーキテクチャ

Alibaba の 4 層アーキテクチャは、元の 3 層アーキテクチャにマネージャー レイヤーを追加し、元の従来の 3 層アーキテクチャをアーキテクチャ図に改良します (図 4 参照)。

図 4 アリババの 4 層アーキテクチャ図

  • オープン インターフェイス レイヤー:
    1. オープン インターフェイス層は、サービス層または WEB 層に直接依存できます。
    2. サービス層によっては、サービスを RPC にカプセル化し、外部に公開することができます。
    3. WEB レイヤーに依存することで、ビジネスを HTTP にカプセル化し、外部に公開することができます。
  • 端末表示レイヤー:
    1. テンプレートのレンダリングと両端での表示を担当します。
    2. 現在、主に速度レンダリング、JS レンダリング、JSP レンダリング、モバイル端末表示などです。
  • ウェブ層:
    1. アクセス制御の転送、さまざまな基本パラメータの検証、または再利用不可能なサービスの単純な処理など。
  • サービス層:
    1. 主に特定のビジネス ロジック サービスの実装を担当します。
  • 一般的なビジネス処理層のマネージャー、主な責任は次のとおりです。
    1. サードパーティ プラットフォームのカプセル化: キャッシュやミドルウェアの一般的な処理など、サービス レイヤーの一般的な基本コンポーネントのカプセル化。
    2. DAO レイヤーと対話し、複数の DAO を再利用する
  • DAO 層:
    1. データ アクセス レイヤー、MySQL、Oracle、Redis などとのデータ インタラクション。

DDD レイヤード アーキテクチャ

DDD ドメイン駆動の階層化アーキテクチャ、ドメイン駆動設計は、従来の 3 層アーキテクチャに基づいてさらに改善され、最上位のユーザー インターフェイス層とビジネス ロジック層の間にアプリケーション層が導入されています。アプリケーション層の導入後、各層の名前もドメイン駆動の概念に従って調整されています。ビジネス ロジック レイヤーをドメイン レイヤーに名前変更し、データ アクセス レイヤーをインフラストラクチャ レイヤー (インフラストラクチャー レイヤー) に名前変更します。

図 5 DDD ドメイン駆動の階層化アーキテクチャ

要約する

これで、レイヤード アーキテクチャをより明確に把握できるようになりました。したがって、階層化されたアーキテクチャについて話すことは、従来の 3 層アーキテクチャまたはドメイン駆動設計によって推奨される 4 層アーキテクチャでなければならないという固有の考えを打破し、代わりに階層化を関心の分離の水平抽象レベルの現れと見なす必要があります。 . そのため、アーキテクチャ内の抽象レイヤーの数は固定されておらず、各レイヤーの名前でさえ、固有の (従来の) レイヤード アーキテクチャの要件に従っていない場合があります。設計システムのレイヤーは、システムの特定のビジネス シナリオと組み合わせて決定する必要があります。もちろん、レイヤー数の長所と短所も認識しておく必要があります。レイヤーが多すぎると、間接的になりすぎて不要な費用が増加します。レイヤーが少なすぎると、関心の分離が不十分になり、システム構造が不合理になる可能性があります。

レイヤード アーキテクチャ パラダイムは、ソフトウェア開発で最も一般的に使用され、悪用されやすいアーキテクチャ パラダイムです。開発者は、ソフトウェア開発と開発者の支援を容易にするために、現在のソフトウェア開発の制約と要件に従って独自のレイヤーを作成できます。階層化されたパラダイムに基づいて、他のモジュールに影響を与えることなくモジュール内のコードを変更できます。これは、ソフトウェアの階層化がもたらす利点です。また、凝集度が高く結合度が低いのも特徴です。

おすすめ

転載: blog.csdn.net/liuguang841118/article/details/128621374