トランザクション リンクの設計原則とパターンに関する簡単な説明

順序

以前簡単に読んだ本を最近読みました。そのうちの 1 つは「エンタープライズ アプリケーション アーキテクチャ パターン」でした。読書メモを書き残そうと思いましたが、執筆時期は 2003 年で、かなり昔のことです。システムが古いのかもしれません。構造も大きく変わっており、抜粋するととても古く感じられ、響きもそれほど大きくありません。しかし、それを読んでいる間に私が感じた心の平安は、依然として非常に懐かしいものでした。思い返してみると、私も以前にデザインの原則やパターンなどを勉強したことはありましたが、主に自分の感じたことを話しただけでした。心の平安を得たいのであれば、やはりこの本の論理を参照し、それを日々の仕事の中での理解と結びつける必要があります。それでは、これらの原則といくつかのモデルに基づいて簡単に説明しましょう。

設計原則

単一責任の原則

意味:

単一責任原則 (SRP: Single Commission Principle) は、単一機能原則とも呼ばれ、オブジェクト指向 (SOLID) の 5 つの基本原則の 1 つです。クラスの変更理由は 1 つだけであることが規定されています。

事例:ビジネス活動が異なれば、サービスの入り口も異なり、フルフィルメント システムや返金システムなど、多くのビジネス プロセス BPM が存在します。この利点は、シナリオをより適切に分割できることであり、さまざまなシナリオでのインターフェイスの電流制限、エラー定義、プロセス設計、回帰テストなどを個別に開発でき、影響範囲が比較的確実であることです。多くのサブサービスをルーティングした一般的なサービスを使用すると、いくつかの共通の操作が実行できるように見えますが、相互の制約や制限がさらに多くなり、アスペクトによっていくつかの共通の問題も解決できるため、特に必要ありません。拡張:さらに議論する価値があるのは、入口層の分離について合意を形成するのは簡単ですが、プロセス、プロセス ノード、機能、拡張機能などは、さらに下位のさまざまなシナリオで共有できるかということです。実際の運用では、機能の違い、シナリオの複雑さ、開発コストと保守コストを総合的に考慮して決定されることが多く、システム スタイルの違いは同じではありません。

  • フルフィルメント システムは、機能のレベルに応じて決定されます。1 つの機能内で、複数のシナリオを考慮する必要があります。たとえば、支払いポイントを延長する場合、受け取りの確認から発生する場合もあれば、返品と支払いから発生する場合もあります。預金の没収から生じる可能性があります。
  • 逆返金システムの拡張は、返金のタイムアウトのカスタマイズ、購入者の返金申請、販売者の返金への同意、購入者の返品など、さまざまなビジネス活動に応じて可能な限り独立した拡張ポイントを持ちます。

独立性の影響は軽減されますが、修正する場合、独立性が高くなりすぎて一部のシーンが欠落する可能性があります。幸いなことに、私たちが意思決定をするときに直面するシナリオは、多くの場合具体的で数えられるものです。

単一責任の原則を理解する

開閉原理

意味:

オブジェクト指向プログラミングの分野におけるオープンクローズ原則は、「ソフトウェア内のオブジェクト (クラス、モジュール、関数など) は拡張に対してはオープンであるが、変更に対してはクローズされるべきである」と規定しています。これは、エンティティが許可されていることを意味します。ソースコードを変更せずに動作を変更します。

事例:拡張フレームワーク TMF の反復であれ、その後のスター リング システムの提案であれ、重要な目的は「ビジネスとプラットフォームの分離」を解決することであり、これはオープンクローズ原則の重要な具体化でもあります。コア ロジックは、プラットフォームに精通したユーザーが制御する必要があり、変更を少なくして可能な限り多用途である必要があります。拡張ロジックはビジネス開発者が理解し、可能な限り柔軟で調整が容易である必要があります。システムの内部を見ると、実際にはドメイン機能の拡張が数多くあり、たとえば、支払いの際に Alipay に直接接続したり、決済システムを通じて WeChat などの Alipay 以外のチャネルにリンクしたりできます。このような拡張もオープンクローズ原則の表れですが、よりコアプロセスに近く、より大きな影響を与えます。拡張機能の外側に目を向けると、ビジネス APP パッケージや製品パッケージなどのプラグイン内であっても、依然として複数の業界や複数のシナリオにサービスを提供する可能性があり、多くの再ルーティングや拡張機能が存在する可能性があります。例: Taoxi は、衣料品、家電、美容など、多くの業界にサービスを提供する必要があります。ビジネスのカスタマイズも異なり、多くの場合、いくつかの戦略と責任連鎖拡張モデルが使用されます。各レベルが独自の拡張メカニズムを設計できることがわかります。 拡張:スターリングの拡張レベルに関しては、さらに検討できる問題がいくつかあります。1. ビジネス分離メカニズム分離された変更部分については、実際にはさらに期待しています。異なるビジネスとメンテナーが相互に分離できることを期待しています。Starlink システムでは、分離のためにビジネス アイデンティティの概念が使用されていますが、これは技術的な観点からのみであり、シナリオの競合は可能な限り分析レベルに移動されるため、その後の実行のプレッシャーが軽減され、柔軟性があまり高くありません。使用済み。例:商品を出品する際に、注文するための「事業者」が存在しない場合、出品される商品は商品ラベルなどにより識別され、複数の「事業者」にまたがることになります。幸いなことに、技術的にはサービスをオーバーレイしてロジックの再利用を実現できる「製品パッケージ」ソリューションがありますが、「オーバーラップの欠落」シナリオが頻繁に発生します。しかし、ビジネスアイデンティティの概念が設けられておらず、要求シナリオに基づいて判断すると、インパクトや表現が不確実性に満ち、「いつ」「誰が」の矛盾を判断することが困難になります。紛争を解決すること。2. ビジネスとプラットフォームの境界. 私たちはよく基本ドメインと呼びますが、実際には、ドメイン機能と拡張機能に加えて、ビジネスプロセス、ビジネス機能、基本実装も含まれるため、基本 + ドメインと考えることができます。 、プラットフォーム共有、共通パッケージ、開発 SDK など。これは基本的なものとみなされ、プラットフォーム担当者の参加が必要です。ただし、いくつかの例外があります。

  • ドメイン拡張では、拡張ポイントに進むことなく、特殊なビジネス (このビジネスのロジックは比較的完全で独立している) に機能が提供されます。プラットフォームの jar パッケージ内で成長する特別な協力状況が存在しますが、進化のルールは基本的にビジネスによって決定され、開発にはプラットフォームの介入が必要です。
  • 独立してデプロイされたシステムでは、コード ベースがフォークされ、独立して進化します。この時点では、レベル全体が「ビジネス」として定義されます。
  • ビジネス機能はプラットフォーム機能とみなされ、プラットフォーム sar パッケージにも統合されますが、税金や輸入などのビジネス機能は基本的に国際的なビジネス維持であり、プラットフォーム ロジックとは言いがたいです。

これらの例から判断すると、ビジネスとプラットフォームの境界は特定の定義レベルを超え、もはや絶対的なものではなくなりました。その中核は依然として「権利と責任の統合」の方向性を踏襲している。

開閉の原理を理解する

リヒター置換原理

意味:

リスコフ置換原則 LSP は、オブジェクト指向設計の基本原則の 1 つです。リスコフ置換原則では、基本クラスが出現できる場所には必ずサブクラスが出現できると述べています。LSP は継承と再利用の基礎であり、派生クラスが基本クラスを置き換えることができ、ソフトウェア ユニットの機能が影響を受けない場合にのみ、基本クラスを真に再利用でき、派生クラスもそれに基づいて新しい動作を追加できます。基本クラスの。

事例:別のアイデア、私たちはよく使います:

  • 拡張ポイントをカスタマイズする場合、ビジネス パッケージまたはシナリオ製品パッケージによって返される結果は考慮されず、カスタマイズされた結果のみが考慮されます。
  • データベースを切り替えるときは、どのデータ サービスにアクセスするかは気にせず、返された結果だけを気にします。
  • 外部の支払いシステムを呼び出す場合、Alipay を使用するか WeChat を使用するかは気にせず、支払い結果のみを気にします。
  • 注文をクエリする場合、注文データベースを使用するか外部サービス (評価など) を使用するかは気にせず、クエリの結果のみを気にします。
  • ……

置換可能性の原理により、抽象化に向けたプログラミングが可能になります。置換が十分にスムーズに行えるかどうかは、抽象化が合理的であるかどうかによって決まります。拡張:抽象化してカスタマイズ可能な置換を実現できますが、実際には、意味を持たないものを実現するのは困難なことがよくあります。

  • サービス保証は異なる場合があります: たとえば、支払いと出荷については注文データベースが照会され、評価については評価インターフェイスが照会され、保証レベルとインターフェイスの機能が一貫していない可能性があります。追加の安定性の保証が必要です。
  • 実装機能に一貫性がない可能性があります: 3 か月後には注文が履歴データベースに入力されます。クエリ レベルは消費者が無関心になるように調整できますが、変更が行われると双方の機能が変更されるため、消費者のその後の操作は制限されます。は異なります。一部のボタンは、履歴ライブラリに入ると機能が低下します。
  • たとえば、決済システムを置き換える場合、Alipay では取引が保証されているため、販売中に返金する方が迅速かつ便利ですが、その後の資金保管や戦略の影響により、返金が行われない可能性があります。 WeChat ログイン チャネルのせいでタイムリーではありません。両側のエラーコードも異なります。
  • ……

リヒター置換原理を理解する

デメテルの法則

意味:

デメテルの法則は簡単に言うと、「親しい友人とだけ話しましょう」です。OOD の場合、これは次のように解釈されます。ソフトウェア エンティティは他のエンティティとの対話をできるだけ少なくする必要があります。各ソフトウェア ユニットは他のユニットに関する最小限の知識を持ち、そのユニットと密接に関連するソフトウェア ユニットに限定されます。

事例:ビジネス活動の実行プロセスはデータ操作を調整するプロセスであり、最終的には全員が合意に達し、データベースにメッセージを送信します。このプロセスでは、さまざまな分野の連携を調整するために、基本的なプロセスとそれに対応するノードの集合から構成される調整層があり、この層で最も代表的な調整役となるのがコンテキスト(リクエスト、結果、コンテキストなどの概念)です。 )。データはコンテキストから取得されますが、後続のノードに渡す場合はコンテキストを詰め戻す必要があり、これをリサイクルと呼びます。もっと大きな視点で見ると、エントランスシステムはコーディネーターの役割も担っています。たとえば、発注システムは、商品システム、在庫システム、マーケティング システム、資本システム、フルフィルメント システムなどを呼び出して、データを収集および送信します。システムが相互に直接呼び出しを行うことはほとんどありません。このようなコーディネーターは、呼び出し操作と変換操作を実行することがよくありますが、この変換層のおかげで、次のことを理解して制御することもできます。

  • モデルを合理化して、リンク上のデータ転送と複数の変換を削減できます。
  • 読み取り専用を制御して、その後の予期しない改ざんを回避できます。
  • パフォーマンスを節約し、遅延読み込みやその他のモードを設計し、必要に応じて実際に取得できます。
  • ……

拡張:コーディネーターは各参加者に関する情報を運ぶ必要があるため、参加者の数が増加するにつれて、情報はますます重くなります。また、一部のシステムには多くのレイヤーがあるため、秘密のレイヤーによって苦しめられることになり、新しいデータが追加されるたびに、再度追加する必要があります。そのため、徐々に、誰もが比較的独自のデータを運ぶ共有モデルを使用し始めました。この結果の裏では、別のアイデアが浮かび上がります。各参加者が生データを取得するために固定領域を提供し、データセンターを操作する場合、コーディネーターをバイパスしてレイヤーごとに送信できるでしょうか? また、データセンターは、自身のデータをより適切に管理する方法も知っておく必要があります。システム レベル間で変換するだけであれば、確かにはるかに便利ですが、システム間にこのデータを処理する可能性のある不明瞭なプロセス ロジックがある場合、それはデータ センターの範囲を超えます。さらに、一部のパーツがモノリスである集約ルート設計の場合、分散したデータセンター間での一貫性の運用も困難になります。最後に、そしてより重要なことですが、コーディネーター自体が調整を目的としている場合、そのコーディネーターは「有名」でなければなりません。開発においては、コンテキストが見つけやすいか、分散したセンターが見つけやすいかということも非常に重要であり、分散アプローチには特定のプロトコルが必要です。

デメテルの法則

インターフェース絶縁原理

意味:

クライアントは、必要のないインターフェイスに依存すべきではありません。あるクラスの別のクラスへの依存関係は、最小のインターフェイスに基づく必要があります。単一の全体的なインターフェイスよりも、複数の特殊なインターフェイスを使用する方が適切です。あるクラスの別のクラスへの依存関係は、最小のインターフェイスに基づく必要があります。

ケース:インターフェース分離の一般的なケースは次のとおりです。

  • 読み取りおよび書き込み機能によって分離されます。つまり、データ読み取り用の 1 つのインターフェイス セットと書き込み操作用の別のインターフェイス セットです。
  • 操作役割による分離: 買い手が操作するためのインターフェースのセット、販売者が操作するためのインターフェース、およびウェイターが操作するためのインターフェースの別のセット。
  • ページ タイプごとに分離します。PC 用に 1 セット、H5 用に 1 セット、クライアント用に 1 セット。
  • コンポーネント プロトコルごとに分離: Ultron 用に 1 セット、Astore 用に 1 セット、DTO 用に 1 セット。
  • ……

これらのシナリオを見ると、自然に分離について考えるようになり、コード自体は異なるモジュールにある可能性が高くなります。インターフェイスの分離は単なる宣言メソッドではありません。

  • クライアントの場合も依存関係を減らすことができ (ただし、各システムには大規模なクライアントが 1 つしかないことがよくあります)、不必要な依存関係の一部を削除できます。
  • サーバーについても、結合を回避して独立して開発することが可能になり、共有と共通を抽象化して再利用することもできます。

拡張機能:注文管理システムには、ボタンの操作を定義する doOp と呼ばれるインターフェイスがあり、渡されるさまざまな操作コードを通じて、「出荷をリマインドする」、「注文をキャンセルする」、「注文を削除する」ことができます。 、「コレクションを拡張する」「グッズ」などの各種操作を行います。この背景には、何百もの注文ボタンがある可能性があることです。インターフェイスの定義はサーバーだけの問題ではありません。また、ワイヤレス パッケージング インターフェイス mtop を申請する必要があり、クライアントもそれを継承する必要があります。再利用するには、クライアントへのパスをできるだけ多くし、比較的一般的なインターフェイスを提供します。ここで、インターフェイスの独立性の原則は絶対的なものではなく、抽象化の数と抽象化間の類似度に関係していることがわかります。さらに、上記のボタンの例は「完全に非分離」ではなく、エントリ層を再利用しているだけです。その後、ボタン コードと厳密に直交し、ボタン コードに基づいて異なる処理戦略にルーティングされます。 。

インターフェース分離の原理を理解する

依存関係逆転の原理

意味:

依存関係逆転の原則とは、プログラムは特定の実装ではなく抽象インターフェイスに依存する必要があることを意味します。簡単に言うと、実装ではなく抽象化をプログラミングする必要があるため、クライアントと実装モジュールの間の結合が軽減されます。

ケース:基本的なサービスが短期的には変わらないと考えており、複数の実装セットが存在しない場合、多くの場合、呼び出しリンク内の「上位層は下位層に依存する」というロジックに直接依存することになります。これは非常にシンプルで効率的です。例えば、注文管理システムにおける注文クエリのサービスをRepoとみなして、その基盤となるサービスとしてインスタンスをドメイン内で直接呼び出します。サービスが外部であり、独自の制御の対象ではないと考え、変更を分離してインターフェイスをアップグレードする機能を保持したい場合は、多くの場合、別のインターフェイス層をラップします。注文およびフルフィルメント システムにはゲートウェイの概念があります。抽象的なサービス インターフェイスに依存するようになり、特定の実装インスタンスを認識しなくなりました。分離用の抽象インターフェイスの層を追加すると、インターフェイスは抽象コントラクトであり、双方が独立して開発できるため、より優れた疎結合機能が維持されますが、管理コストも発生します。これは判断とトレードオフです。 拡張:概念的にはこのレベルは非常に優れていますが、正しくするにはまだいくつかのコストがかかります。

  • パッケージ化モジュール: A が B に依存する過程で、抽象的な C が導入されたとします。このような抽象化レイヤーは A と B とは関係がないため、別個の jar パッケージとコード ライブラリにする必要があります。ただし、新しいライブラリを作成するのが面倒なため、A または B のサブモジュールでホストされることがよくあります。パッケージ化するときに、個別に入力する必要があり、非常に面倒です。
  • 複雑なオブジェクトの課題: 抽象指向のインターフェイスはより多くの変換を意味します通常のシステムでは、これは比較的簡単かもしれませんが、複雑なオブジェクト設計を取引するコンテキストでは、これは骨の折れるプロセスになります。さらに残念なことに、トレーディングシステムのドメインオブジェクトとデータベースモデルは論理的なマッピングであり、これらのレイヤーを重ね合わせた後、データがどのように取り出されるのかを見つけるのが困難です。

したがって、場合によっては、逆の方向に進み、密結合モデルを選択することがあります。複雑なシステムでは、次のように感じることがよくあります。単純さ、純粋さ、密結合は一筋の光です。なぜなら、少しずつ発見できるからです。関連するコードは、dot-dot-dot-dot-dot-dot-dotではなく、迷子になります。これを言うとき、私は悪魔の擁護者を演じているわけではありません。問題を弁証法的に見て、それを特定のシナリオと組み合わせることができればと願っています。諦めたときにのみ利益を得られ、得たところでは必ず失われます。

依存関係逆転の原理

デザインパターン

以下に23種類のデザインパターンの中からいくつかをピックアップしてご紹介します。

テンプレート

テンプレートメソッドとは、実行処理を抽象的に分解し、スケルトンメソッドと拡張メソッドによって標準的なメインロジックと拡張を完成させることを意味します。

プラットフォームの設計とトランザクション リンクの拡張機能は、類推するのがより適切です。基本テンプレートはプロセス全体とそれに対応するノードの配置であり、スケーラブル領域はさまざまなビジネスのカスタマイズ領域です。これにより、プラットフォームとビジネスのより良い統合が形成されます。

責任の連鎖

責任の連鎖とは、実行するプロセッサが見つかるまで、キュー内のプロセッサによってリクエストが 1 つずつ実行されることを意味します。

ビジネス機能の拡張とドメインの拡張は、結果をリサイクルするときに実装されたプラグインを横断し、リサイクル ルールを組み合わせてタイムリーなサーキット ブレーカーを実行します。これは責任の連鎖の論理に似ています。商品の受け取り確認や支払い時の「支払い通知をスキップするかどうか」を例に挙げると、TMF実行エンジンは商品パッケージやアプリパッケージの実装を横断し、最初にtrue(スキップ)を返した結果を見つけた場合に実行します。実行を停止します。全体的に true を返します。

戦略

戦略とは、タスクを完了するためにさまざまなアルゴリズムがあり、関連する切り替えを実行できることを意味します。

逆返金では、保証された取引である必要があるもの、入金リンクである必要があるもの、WeChat 支払いである必要があるもの、カードと資産の返却である必要があるものなど、さまざまな返金リンクをサポートする必要があります。複数の出金戦略をサポートするために、ストラテジーモードを採用しており、拡張ポイントを通じてさまざまなファンド戦略をカスタマイズでき、単一または複数のファンド戦略を同時に実行できます。

観察者

オブザーバー パターンは、登録やコールバックなどの協調設計を通じて、変更通知の協調メカニズムを完成させることを意味します。

取引において、システム内のオブザーバーモードはまれです。ただし、システム間には依然として多くのメッセージベースの監視モードが存在します。典型的なリバース0s出金:返金によって作成されたメッセージを監視し、同意コールを行うことで、0s出金のクイック同意機能が実現されます。メッセージの非同期通知方法により、より適切な分離を実現できるだけでなく、失敗した場合にはメッセージの再投資メカニズムを使用して成功の確率を高めることもできます。

状態モデルは、異なる状態では異なる処理動作が存在することを意味します。

ワークフローはトランザクション システムに導入され、ビジネス活動が通過できる状態と、各状態で実行できる操作を定義します。たとえば、通常の保証の準トランザクション プロセスには、外部支払トランザクションの作成、支払コールバック、物流注文の作成、出荷、受領確認などのステータス ノードが含まれます。各ノードは、実行できる操作も定義します。たとえば、外部支払いトランザクションを作成する場合、支払いの検証、注文のクローズ、価格の変更などの操作を実行できます。ただし、支払いがないため、支払いや返金などの操作は実行できません。が作られました。

調停者

複数のクラスを調整する必要がある場合、全員の知識コストを削減するために調整のために仲介者が導入されることがよくあります。

取引システムでのプロセスの実行中に、さまざまなフィールドのデータを調整する大きなコンテキストが存在します。一般的なシナリオでは、各オーケストレーション ノードがデータ更新に影響を与える可能性があるため、データをどこかに保存してから最終更新ノードに引き渡す必要があります。情報を伝達するというこの役割は、多くの場合、コンテキストを介して行われます。逆のプロセスでの更新連携の大まかな構造は以下のとおりです。

複合

組み合わせにより、継承されたパターンと子ノードを通じてオブジェクト階層を再帰的に記述することができます。

再帰的思考のより良い例は、一連の注文を継続的にグループ化する注文システムでの注文の分割です。再帰的にさらに洗練するのと同じように、論理的に理解します。

シングルトン

シングルトンとは、マルチスレッドの場合、オブジェクトが一意のリソースとして 1 回だけ作成されるようにする必要があることを意味します。

注文管理システムでは、外部呼び出しサービスは Repo と呼ばれ、リソース ライブラリとして機能します。これらのリソース ライブラリを簡単に取得するために、それらはすべてシングルトン モードを通じて取得されるため、一部のツール クラスは、Bean を注入せずに静的メソッドを通じてサービスを簡単に呼び出すこともできます。このようなリポジトリには、注文サービス、評価サービス、アイコン サービス、タイムアウト サービスなどが含まれます。

通訳者

インタプリタとは、一連のコンテキストに対して一連の言語が形成され、表現の意味を解釈することで対応するタスクを完了できることを意味します。

トランザクションで見られるインタープリター モードは、主にオリジナルのタオバオ システムのニュートン システム、動的スクリプト構成です。この構成プラットフォームは主に製品パッケージ内のいくつかの動的ルールを解決し、プッシュ モードを通じて解釈の動的性質を利用して導入コストの一部を削減できます。

プロキシ

プロキシの目的は、クラスをラップし、二次転送や関連する操作の制御を実行することです。

注文管理システムでは、さまざまなドメインによるコンテキストの改ざんを防ぐために、コンテキストに対して一定の保護手段が設けられています。特定の実行ノードに入ると、コンテキスト変換が実行されます。変換プロセス中、エンティティ オブジェクトは、読み取り専用インターフェイスをラップして読み取り専用サービスを提供することによってプロキシされます。ただし、特定のインスタンスは取得できず、設定された変更はできません。

要約する

「Enterprise Application Architecture Patterns」には、このパターンについてよく書かれた文章があります。

それぞれのパターンは、私たちの周りで繰り返し発生する問題と、その問題に対する解決策の核心を説明します。こうすることで、手間をかけずにソリューションを何度も使用できます。

この記事では、いくつかの原則と設計パターンを使用して、私が偵察した取引システムのいくつかの設計について説明します。私の目から見たトランザクションのリンクについて、視点を提供し、さらに詳しく知ることができれば幸いです。

著者|天河

クリックして今すぐクラウド製品を無料で試し、クラウドでの実践的な取り組みを始めましょう!

元のリンク

この記事は Alibaba Cloud のオリジナル コンテンツであり、許可なく複製することはできません。

Lei Jun: Xiaomi の新しいオペレーティング システム ThePaper OS の正式版がパッケージ化されました。Gome App の抽選ページのポップアップ ウィンドウは創設者を侮辱しています。Ubuntu 23.10 が正式にリリースされました。金曜日を利用してアップグレードするのもいいでしょう! Ubuntu 23.10 リリース エピソード: ヘイトスピーチが含まれていたため、ISO イメージが緊急に「リコール」されました 23 歳の博士課程の学生が Firefox で 22 年間続いた「ゴーストバグ」を修正しました RustDesk リモート デスクトップ 1.2.3 がリリースされましたWayland を強化して TiDB 7.4 をサポート リリース: MySQL 8.0 と正式互換. Logitech USB レシーバーを取り外した後、Linux カーネルがクラッシュしました. マスターは Scratch を使用して RISC-V シミュレータをこすり、Linux カーネルを正常に実行しました. JetBrains が Writerside ツールを開始しました技術文書の作成に。
{{名前}}
{{名前}}

おすすめ

転載: my.oschina.net/yunqi/blog/10120093