問題タブ [hexagonal-architecture]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票する
2 に答える
5264 参照

architecture - 六角形アーキテクチャ - シンプルなユースケース

私は六角形のアーキテクチャについて多くのことを読んできましたが、ほとんどの概念を理解しています (そうであることを願っています) 。そのアーキテクチャのユースケースの例は見つかりませんでした。

私のアプリケーション ドメイン モデルが人々を酔わせることだとしましょう。ビジネスロジック全体Personは、ドメイン層にあるクラスに含まれています。

ドメイン層にはPersonRepository

実装者:

アクセスして人を酔わせたいとしましょう: GET /person/johnDoe/drink。次のようなユース ケースを作成する必要があります。

コントローラーから呼び出しますか?この言及されたケースは、ドメイン層またはアプリケーション層に存在する必要がありますか? この場合のポートとアダプターは何ですか? この人を酔わせる方法が必要な場合はどうすればよいですか? 1 つは GET 要求から、もう 1 つはphp console person:drink JohnCLI コマンドからですか? アプリをどのように構成すればよいですか?

0 投票する
1 に答える
690 参照

php - すべての目的に役立つリポジトリからのデータ構造?

次の (Laravel PHP) プロジェクトで実装したいリポジトリサービス/ユースケースパターン ( DDD設計の一部)に関して頭を悩ませていることについて助けが必要です。

すべてが明確に見えます。紛らわしい DDD の一部は、リポジトリのデータ構造です。人々は、リポジトリが返すデータ構造 (配列またはエンティティ) を選択しているようですが、すべてに欠点があります。その一つが、自分の過去の経験を振り返るパフォーマンスです。1 つは、単純なデータ構造 (配列または単純なオブジェクト属性) 用のインターフェイスがないことです。

以前のプロジェクトでの経験を説明することから始めます。このプロジェクトには欠陥がありましたが、いくつかの優れた長所を学び、新しいプロジェクトで見たいと思っていますが、いくつかの設計ミスを解決しています.

以前の経験

過去に、Kohana フレームワークと Doctrine 2 ORM (データ マッパー パターン) を使用して API 中心の Web サイトを構築しました。フローは次のようになりました。

ウェブサイト コントローラー → API クライアント (HMVC 呼び出し) → API コントローラー → カスタム リポジトリ → Doctrine 2 ORM ネイティブ リポジトリ/エンティティ マネージャー

私のカスタム リポジトリは、Doctrine2 DQL を使用してプレーンな配列を返しました。Doctrine2 は、読み取り専用操作の配列結果データを推奨しています。そして、はい、それは私のサイトを素晴らしく軽くしました. API コントローラーは配列データを JSON に変換しました。そのような単純な。

過去に、私の会社は読み込まれた Doctrine2 エンティティに完全に依存するプロジェクトを作成しましたが、パフォーマンスのために後悔していました。

私の REST API は
/api/users?include_latest_adverts=2&include_location=true
、users リソースのようなクエリをサポートしていました。include_locationロケーション関係を直接含むリポジトリに渡される API コントローラー。latest_adverts=2コントローラーは、広告リポジトリを読み取って呼び出し、各ユーザーの最新の 2 つの広告を取得しました。配列が返されました。

たとえば、最初のユーザー配列:

これは非常に成功したことが証明されました。私のウェブサイト全体が API を使用していました。API はすでに oauth を使用して完全に運用されているため、新しいクライアントを追加するのは非常に簡単です。ウェブサイト全体がその上で実行されます。

しかし、この設計にも欠陥がありました。has_adverts=true私のコントローラーには、検証、メール送信、パラメーター、またはユーザーに広告のみを表示するためのフィルターのための多くのロジックがまだ含まれていました。まったく新しい CLI インターフェイスなどの新しいポートを作成した場合、すべての検証などのためにこれらのコントローラーを大量に複製する必要がありますが、新しいクライアントを作成する場合は複製しません。それで、少なくとも1つの問題が解決されました:-)

私の管理パネルは、doctrine2 リポジトリ/entity-manager に完全に結合され、開発をスピードアップしました (一種の)。なんで?私のAPIには、ウェブサイト専用の特別な機能(特別な検証、登録のためのメール送信など)を備えたファットコントローラーがあったためです。作業をやり直したり、リファクタリングしたりする必要がありました。そこで、エンティティを直接使用して、たとえばすべての API コントローラーを書き直してサービス (サイトと管理者用) に移動する代わりに、何らかの明確な方法でコードを記述することにしました。設計ミスを修正するには時間が問題でした。

次のプロジェクトでは、すべてのコードを独自のカスタム リポジトリとサービスを通過させたいと考えています。良好な分離のための 1 つのフロー。

新しいプロジェクト (DDD のアイデアを使用) とデータ構造のジレンマ

私は API 中心であるという考えは好きですが、HTTP プロトコルを介さずに同じ機能を使用できるようにする必要があるため、次のプロジェクトのコアを API 中心にしたくはありません。DDDのアイデアでコアを設計したい。

しかし、API として機能し、単純な配列を返すレイヤーを使用するというアイデアは気に入りました。私自身のフロントエンドを含む、新しいポートの完璧なベースです。私の考えは、Service クラスを API インターフェイス (配列データを返す) と見なし、検証などを行うことです。Web サイト専用のサービス (登録) と、管理者またはバックグラウンド プロセスで使用される単純なサービスを使用できます。一部の管理ケースでは、単純な CRUD 編集にサービスが必要ない場合もあります。リポジトリを直接使用することもできます。コントローラーは非常に薄いでしょう。これにより、実際の REST API を作成することは、フロントエンド コントローラー クラスと同じサービスを使用して新しいコントローラーを作成するだけの問題になります。

ビジネス ルールのような内部ロジックの場合、リポジトリの配列の代わりにエンティティ (明確なインターフェイス) を使用すると便利です。このようにして、属性に基づいたロジックを実行するいくつかのメソッドを定義することでメリットが得られます。しかし、Doctrine2 を使用していて、リポジトリが常にエンティティを返すと、アプリケーションのパフォーマンスが大幅に低下します!!

1 つのデータ構造はパフォーマンスを保証しますが明確なインターフェイスはありません。もう 1 つのデータ構造は明確なインターフェイスを保証しますが、Doctrine 2 のようなデータ パターン パターンを使用するとパフォーマンスが低下します (現在または将来)。また、混乱を招く 2 つのデータ型になってしまう可能性もあります。

私はこの流れに似た何かを考えていました:

Controller (シン) → UserService (検証を含む) → UserRepository (ストレージのみ) → Eloquent ORM

なぜ Doctrine2 ではなく Eloquent なのですか? Laravel フレームワークとコミュニティ内で共通していることに少しこだわりたいからです。そのため、たとえば、モデルに基づいて管理インターフェイスなどを生成する (DDD ルールをバイパスする) など、サードパーティのモジュールを利用できます。サードパーティのモジュールを使用する以外に、切り替えが常に簡単で、データ構造の選択やパフォーマンスに影響を与えないように、コアのものを設計します。

Eloquent はアクティブレコードのパターンです。したがって、このデータを Doctrine2 エンティティのような POPO に変換したくなるでしょう。しかし、いいえ... 上で述べたように、doctrine2 の実際のモデルを使用すると、システムが非常に太くなります。そのため、単純な配列に戻ります。これを知ることは、将来の両方と他の実装で機能します。

しかし、常に配列に依存するのは気分が悪いです。特に社内のビジネス ルールを作成する場合。開発者は、配列の値を推測する必要があり、IDE にオートコンプリートがなく、Entity クラスのような特別なメソッドを持つことができませんでした。しかし、データを処理する方法を 2 つ作るのも気分が悪いものです。または、私はあまりにも完璧主義者です ;) すべてに対して 1 つの明確なデータ構造が必要です!

インターフェイスと POPO を構築することは、多くの重複作業を意味します。Eloquent モデル (エンティティではなく単なるテーブル マッパー) を、このインターフェイスを実装するエンティティ オブジェクトに変換する必要があります。すべて余分な作業です。最終的に、最後のレイヤーは API のようになり、再び配列に変換されます。これも余分な作業です。配列は再び取り引きのようです。

DDD と Hexagonal を読み取るのはとても簡単に思えました。それはとても論理的なようです!しかし、実際には、OOP の原則に固執しようとしているこの 1 つの単純な問題に苦労しています。配列を使用したいのは、パフォーマンスなどに関して、モデルの選択や ORM からのクエリの選択に依存せず、ビューまたは API の配列に変換する際に重複する作業がないことを 100% 確実にする唯一の方法だからです。しかし、ユーザー配列がどのように見えるかについての明確な契約はありません。これらのパターンを使用してプロジェクトをスピードアップしたいのですが、遅くするのではありません:-)したがって、多くのコンバーターを持つオプションはありません。

今、私はたくさんのトピックを読みました。Doctrine2 のような適切なエンティティに準拠する POPO とインターフェースを作成することができますが、Eloquent のすべての余分な作業が必要です。Doctrine2 への切り替えはかなり簡単ですが、パフォーマンスに大きな影響を与えるか、Doctrine2 配列データをこれらの独自のエンティティ インターフェイスに変換する必要があります。単純な配列を返すことを選択する人もいます。

Eloquent の代わりに Doctrine2 を使用するよう人々を説得する人もいますが、Doctrine2 は重く、読み取り専用操作には配列の結果を使用する必要があるという事実を無視しています。

リポジトリは変更可能に設計されていますよね?デザインだけが「いい」からではありません。では、パフォーマンスや重複する作業に大きな影響を与える場合、完全なエンティティに頼ることができるでしょうか? Doctrine2 のみ (結合) を使用している場合でも、そのパフォーマンスのために同じ問題が発生します!

すべての ORM 実装は配列を返すことができるため、重複した作業はありません。良い成果。しかし、私たちは明確な契約を欠いています。そして、配列またはクラス属性のインターフェースはありません (回避策として)...うーん;)

私たちのプログラミング言語で欠落しているブロックを見逃すだけですか? 単純なデータ構造のインターフェース??

すべての配列を作成し、高度なビジネス ロジックをこれらの配列と対話させるのは賢明でしょうか? したがって、明確なインターフェースを持つクラスはありません。事前計算されたデータ (通常は Entity メソッドによって返されます) は、Service クラスで定義された配列キー内にあります。賢明ではない場合、上記のすべてを考慮した代替手段は何ですか?

パフォーマンスやさまざまな ORM の実装などを考慮して、この「ドメイン」で優れた経験を持つ人が、これにどのように対処したか教えていただければ幸いです。

前もって感謝します!

0 投票する
2 に答える
505 参照

design-patterns - ドメイン レベルのアクセス許可を適用する場所

パーミッション/承認 (認証ではない) は分野横断的な問題だと思います。

Onion アーキテクチャまたは Hexagonal アーキテクチャでは、どこでパーミッションを実行する必要がありますか? 必要な許可の例は次のとおりです。

  • フロントエンドに返されるデータのフィルタリング (UI、API、またはその他)
  • ビジネス オペレーションがまったく実行可能であることの検証

理想的には、単一責任の原則により、ビジネス オペレーションを実行してデータを返すコードは、ユーザーのアクセス許可をまったく認識する必要がありません。その機能の実装は、ビジネス オペレーションを実行する方法、またはリポジトリやドメイン サービスにクエリを実行する方法を知っている必要があります。それだけです。

ビジネス操作を実行したり、データを返したりするクラスと同じインターフェースを実装するラッパー/ファサードは、このパーミッションを置く場所でしょうか? それとももっと良い方法がありますか?

また、ベスト プラクティスがロールではなくアクティビティごとのアクセス許可である場合、単にデータを返すことを目的とするサービスによってアクセス許可を実行する必要があると言うのは有効ですか?

0 投票する
1 に答える
492 参照

domain-driven-design - 六角形のアーキテクチャ - 一連の呼び出し

六角形のアーキテクチャとドメイン駆動設計を理解しようとしていますが、コマンド ハンドラーとコマンド バスについて混乱していますか? これはアプリケーション層またはドメイン層のどちらに属すべきか?

また、クラス図やシーケンス図の例も見つかりませんでした。コマンドバスも含むサンプルシーケンス図を誰かが提供できるかどうかに感謝します。

0 投票する
1 に答える
1482 参照

php - DDD および Hexagonal アーキテクチャ - サービス

DDD/Hexagonal アーキテクチャ アプリケーションの構築を開始してからしばらく経ちましたが、両方に関連する概念の量に圧倒されました。

私は少し行き始めましたが、必要に応じて概念を適用しようとしました。アプリケーションに適用できない、または考えていないものがまだたくさんあることがわかりました。そのうちのいくつかは、アダプター、コマンド (CQRS?)、イベント..

これとは別に、Hexagonal Architecture に関係することに少し行き詰まりました。外部の動作の定義を適用しようとしているのは、内部に依存する必要があるため、インフラストラクチャ層 -> アプリケーション層 -> ドメイン層

私の場合、次の LoginService の例として、アプリケーション層でサービスを定義しました。

しかし、六角形のアーキテクチャが表す依存関係ステートメントを吹き飛ばしていると確信しています。私のアプリケーション層はインフラストラクチャ層に依存しているため。(この場合、$this->userRepository->findByUsername($userName);アプリケーションの serviceContainer に注入された DoctrineUserRepository の一部です)

私のレポは github で完全に利用できます: Malendar リポジトリ

データベース出力に依存するこの Service ケースをどのように処理しますか? また、使用するのに非常に便利な概念をスキップしますか?

よろしくお願いします=D