私がプログラマーになるために夜間学校に通っていたとき、いくつかのデザインパターン:シングルトン、リポジトリ、ファクトリー、ビルダー、デコレーターなどを学びました。 デザインパターンは、既存の問題や繰り返し発生する問題に対して、実績のある解決策を与えてくれます。 しかし、同じような仕組みがより高い次元で存在することを私は知らなかった。 これらは、アプリケーションまたはアプリケーションの全体的なレイアウトのためのパターンです。 どれもメリットとデメリットがあります。

Layered Pattern

Layered Pattern は、おそらく最もよく知られているソフトウェア アーキテクチャ パターンの 1 つです。 多くの開発者が、その名前をよく知らないまま、これを使用しています。 アイデアは、コードを「層」に分割し、各層が特定の責任を持ち、より高い層にサービスを提供することです。

レイヤーの数はあらかじめ定義されていませんが、これらは最もよく目にするレイヤーです。

  • Presentation or UI layer
  • Application layer
  • Business or domain layer
  • Persistence or data access layer
  • Database layer

考え方はユーザーがあるアクション(例えば、…)を実行してプレゼンテーション層のコード部分を開始させるとすることである。ボタンをクリックするなど)。 次に、プレゼンテーション層は下位の層、すなわちアプリケーション層を呼び出します。 そして、ビジネス層に入り、最後に永続化層がすべてをデータベースに保存します。 したがって、上位の層は下位の層に依存し、呼び出しを行います。

アプリケーションの複雑さに応じて、これのバリエーションを見ることができます。 アプリケーションによっては、アプリケーション レイヤーを省略することもあれば、キャッシュ レイヤーを追加することもあります。 2 つのレイヤーを 1 つに統合することさえ可能です。 たとえば、ActiveRecord パターンはビジネス レイヤーと永続レイヤーを結合します。

Layer Responsibility

前述のように、各レイヤーにはそれぞれ責任があります。 プレゼンテーション層には、アプリケーションのグラフィック デザインと、ユーザー インタラクションを処理するすべてのコードが含まれます。 この層では、ユーザー インターフェイスに固有でないロジックを追加すべきではありません。

ビジネス層は、解決しようとしているビジネス問題に固有のモデルおよびロジックを置く場所です。 一方では、プレゼンテーション層がビジネス層を知る必要がないように、抽象化を提供します。 理論的には、アプリケーションの他の部分を変更することなく、プレゼンテーション層のテクノロジー スタックを変更できます (たとえば、WinForms から WPF への変更など)。 一方、アプリケーション層は、ビジネス層またはプレゼンテーション層に収まらない特定の調整ロジックを置く場所を提供します。

最後に、永続化層には、データベース層にアクセスするコードが含まれています。 データベース層は、基礎となるデータベース テクノロジーです (例: SQL Server、MongoDB)。 永続化層は、データベースを操作するためのコードのセットです。

Advantages

  • ほとんどの開発者はこのパターンに精通しています。
  • それは、よく整理され、テスト可能なアプリケーションを書くための簡単な方法を提供します。

Disadvantages

  • It tend to lead to monolithic applications that are hard to split up afterward.
  • Developers often find themselves to pass through the different layers, without adding any value in these layers.これは、多くの開発者が、これらの層での価値を追加することなく、異なる層を通るために多くのコードを記述していることに気づきます。 もしあなたがやっていることが単純な CRUD アプリケーションを書くことであるなら、層パターンはあなたにとってやりすぎかもしれません。

Ideal for

  • Standard line-of-business apps that do more than just CRUD operations

Microkernel

The microkernel pattern, or plug-in pattern is useful when your application has a core set of responsibilities and a collection of interchangeable parts on the side.これは、アプリケーションに責任の中心となる部分や互換性を持つ部分がある場合に有効なパターンです。 マイクロカーネルは、異なるプラグインが何を行っているかを実際に知ることなく、アプリケーションのエントリ ポイントと一般的なフローを提供します。 マイクロカーネルにはタスクをスケジューリングおよびトリガーするためのすべてのロジックを含めることができ、プラグインには特定のタスクが含まれます。 プラグインが事前に定義された API に準拠している限り、マイクロカーネルは実装の詳細を知る必要なく、プラグインをトリガーできます。 ワークフローの実装には、異なるステップの順序、ステップの結果の評価、次のステップを決定するなどの概念が含まれます。 ステップの具体的な実装は、ワークフローのコア コードにはあまり重要ではありません。

Advantages

  • このパターンは大きな柔軟性と拡張性を提供します。
  • Microkernel とプラグインは別々のチームが開発することができる。

Disadvantages

  • 何がマイクロカーネルに属して、何がそうでないか決めるのは難しいかもしれない。
  • 定義済み API は、将来のプラグインにはあまり適さないかもしれません。

Ideal for

  • Application that take data from different sources, transform that data and writes it to different destinations
  • Workflow applications
  • Task and job scheduling applications

CQRS

CQRS is an acronym for Command and Query Responsibility Segregation (コマンドおよび問い合わせの責任分離). このパターンの中心的なコンセプトは、アプリケーションには読み取り操作と書き込み操作があり、それらは完全に分離されていなければならないということです。 これはまた、書き込み操作(コマンド)に使用されるモデルが、読み取りモデル(クエリー)と異なることを意味する。 さらに、データは異なる場所に保存される。 リレーショナルデータベースでは、コマンドモデル用のテーブルと読み取りモデル用のテーブルが存在することになる。 たとえば、SQL Server はコマンド モデル、MongoDB は読み取りモデルです。

このパターンはしばしばイベント ソーシングと組み合わせられますが、これについては後ほど説明します。 ユーザーがアクションを実行すると、アプリケーションはコマンド サービスにコマンドを送信します。 コマンド サービスは、コマンド データベースから必要なデータを取得し、必要な操作を行い、それをデータベースに保存します。 そして、読み取りサービスに通知し、読み取りモデルを更新できるようにします。

アプリケーションがユーザーにデータを表示する必要がある場合、以下に示すように、読み取りサービスを呼び出して、読み取りモデルを取得することができます。

Disadvantages

  • Command と Read モデルを同期させるのは複雑になる可能性があります。

Ideal for

  • Application that expects of high amount of reads
  • Application with complex domains

Event Sourcing

上記で述べたように、CQRSはイベントソーシングとよく連動していることが特徴です。 これは、モデルの現在の状態をデータベースに保存するのではなく、モデルに起こったイベントを保存するパターンです。 つまり、顧客の名前が変わったとき、その値を「Name」カラムに格納しない。 新しい値 (そしておそらく古い値も) を含む “NameChanged” イベントを保存します。

モデルを取得する必要がある場合、保存されたすべてのイベントを取得し、新しいオブジェクトにそれらを再適用します。 これをオブジェクトの再水和と呼びます。

イベント ソーシングの現実的な例として、会計が挙げられます。 経費を追加するとき、合計の値は変更しません。 会計では、実行する操作で新しい行が追加されます。 エラーが発生した場合は、新しい行を追加するだけです。 簡単にするために、行を追加するたびに合計を計算することもできます。 この合計を読み取りモデルと見なすことができる。 以下の例では、より明確になるはずです。

Invoice 201805を追加するときにエラーが発生したことがわかります。 行を変更するのではなく、まず間違った行をキャンセルするための行、そして新しい正しい行の2つを追加しました。 これがイベントソーシングの仕組みです。 過去に起きたことは紛れもない事実なので、イベントを削除することはありません。

また、合計値を示すセルがあることに注目してください。 これは、上記のセルのすべての値を単純に合計したものです。 Excelでは自動的に更新されるので、他のセルと同期していると言ってもよいでしょう。

Event Sourcing は、オブジェクトを再水和させると、特にインスタンスに対して多くのイベントがある場合、パフォーマンスに影響を与えることがあるため、しばしば CQRS と組み合わせられます。 高速読み取りモデルは、アプリケーションの応答時間を大幅に改善することができます。

利点

  • このソフトウェア アーキテクチャ パターンは、箱から出して監査ログを提供することができます。 各イベントは、ある時点でのデータの操作を表します。

Disadvantages

  • Database の単純な編集で間違ったデータを修正できないので、ある程度の規律を必要とします。 たとえば、プロパティを追加した場合、データベースにはそのデータなしのイベントがまだ含まれています。 あなたのコードは、この欠落したデータを丁重に扱う必要があります。
  • イベントを外部システムに公開する必要があるアプリケーションに最適
  • CQRS で構築する予定
  • 複雑な ドメイン
  • データへの変更の監査ログが必要

Microservices

アプリケーションをマイクロサービスのセットとして記述するとき、マイクロサービスとは何ですか。 は、実際には、一緒に動作する複数のアプリケーションを書いていることになります。 各マイクロサービスは独自の責任を持ち、チームは他のマイクロサービスから独立して開発することができます。 それらの間の唯一の依存関係は、通信です。 マイクロサービス同士が通信すると、それらの間で送信されるメッセージに後方互換性が保たれていることを確認する必要があります。 これは、特に、異なるチームが異なるマイクロサービスに責任を負う場合、いくつかの調整を必要とする。

図で説明できる。

上の図では、アプリケーションは中央 API を呼び出し、それが正しいマイクロサービスに呼び出しを転送する。 この例では、ユーザー プロファイル、在庫、注文、および支払いについて、個別のサービスがあります。 これは、ユーザーが何かを注文できるアプリケーションであると想像できます。 別々のマイクロサービスは、お互いを呼び出すこともできます。 例えば、支払いが成功したとき、支払いサービスは注文サービスに通知することができます。 受注サービスは、在庫を調整するために在庫サービスを呼び出すことができます。

マイクロサービスがどの程度の大きさになるかという明確なルールはありません。 先の例では、ユーザープロファイルサービスは、ユーザーのユーザー名とパスワードのようなデータだけでなく、自宅の住所、アバター画像、お気に入りなども担当するかもしれません。

Advantages

    各マイクロサービスを個別に記述、保守、およびデプロイできる。

  • 拡張する必要があるマイクロサービスのみを拡張できるため、マイクロサービス アーキテクチャは拡張しやすくなるはずです。

Disadvantages

  • 予想に反して、最初はよく構造化されたモノリスを書いて、後でマイクロサービスに分割する方が実際簡単です。 マイクロサービスでは、通信、調整、後方互換性、ロギングなど、多くの余分な懸念事項が登場します。 うまく構造化されたモノリスを書くのに必要なスキルを持たないチームは、おそらく、優れたマイクロサービスのセットを書くのに苦労することになるでしょう。 失敗のポイントが多くなり、何か問題が発生したときに、問題を特定するのに時間がかかることがあります。

理想的なのは、この点です。

  • 特定の部分が集中的に使用され、拡張する必要があるアプリケーション
  • 複数の他のアプリケーションに機能を提供するサービス
  • 1 つのモノリスにまとめると非常に複雑になるアプリケーション
  • 明確に境界のあるコンテキストを定義できるアプリケーション

Combine

いくつかのソフトウェア アーキテクチャのパターンについて説明してきましたが、いかがでしたか? と、そのメリット・デメリットをご紹介しました。 しかし、ここに並べたもの以外にも、様々なパターンがあります。 また、これらのパターンをいくつか組み合わせることも珍しくありません。 必ずしも相互に排他的とは限りません。 たとえば、いくつかのマイクロサービスを持っていて、そのうちのいくつかは層状パターンを使用し、他のものは CQRS とイベント ソーシングを使用できます。

覚えておくべき重要なことは、どこでも通用する 1 つのソリューションがあるわけではない、ということです。 アプリケーションにどのパターンを使用するかという質問をすると、古くからの答えがまだ適用されます。 “it depends” (それは場合による) です。 ソリューションの長所と短所を比較検討し、十分な情報に基づいた決定を下す必要があります。

コメントを残す

メールアドレスが公開されることはありません。