web-dev-qa-db-ja.com

機能別パッケージと循環依存関係についての疑問

私は次のライブラリを実装しています:

  1. 一部の入力データを受け取ります(データ構造とクラスをparsingパッケージに入れます)
  2. データを構造に格納します(データ構造とクラスをstorageパッケージに入れました)
  3. 意味のある方法でデータを提示する(chartパッケージ)

別のデータ表現(たとえば、tableパッケージ)を追加する場合は、parsingおよびstorageパッケージを再利用できるため、コードをこのように分割しました。

私は循環依存関係が心配ですが:

  • 私のParserは入力データを専用のデータ構造クラスRecordに保存する必要があります。これは、DataStorageがデータを取得する方法を知り、Parserがデータの方法を知る必要があることを意味します挿入はDataStorageクラスで実行されます。
  • chart-そして最終的にはtable-パッケージがDataStorageクラスからデータを取得する方法についてもう少し知っておく必要があることも心配しています。

私の懸念は有効ですか?はいの場合、どうすれば問題を解決できますか? contractsinterfacesなどの特定のクラスがそれらを実装するような方法で、Record/DataStorageパッケージ内のいくつかのインターフェイスを公開することを考えていました循環依存ではなくなります。

この解決策は良い方法と考えられますか、それとももっと良い代替案がありますか?

2
Vigenere

RecordDataStorageなどの特定のクラスがそれらを実装し、循環依存関係がなくなるような方法で、コントラクト/インターフェースパッケージの一部のインターフェースを公開することを考えていました。

これで結構です。各パッケージは(可能な限り抽象的な方法で)定義します1)入力と出力なので、これらのパッケージへの依存関係はdependency inversionによって実装されます。これは、パッケージとコンシューマの間のクリーンな依存関係です。どちらも、相互にかなり分離されているためです。

つまり、package-by-featureは、境界(パッケージ、モジュール、レイヤーなど)。その場合、別の組織になる可能性があります。 package-by-componentのようなもの2


1:これに沿って、興味があるかもしれません依存関係ルール:どのデータが境界を越えるか

2:ライブラリや小さな事業単位などの小さな境界の場合、package-by-featureは問題なく機能しますが、モジュール式アーキテクチャの場合package-by-componentは重要です。小さな組み込み機能とアドオンまたはプラグインを比較してください。

5
Laiv

インターフェイスでサイクルをマスキングする場合は注意が必要だと思います。

パーサーについてストレージに知らせることをお勧めしますが、その逆はお勧めしません。パーサーはドメイン/ビジネスロジックのようです。他のすべてはそれを中心に展開します。 The Onion Architecture も参照してください。

すべてをオーケストレーションする新しいパッケージ(アプリなど)を作成できます。しかし、「パーサー」から「ストレージ」への変換は、おそらくストレージシステムに大きく依存しています。したがって、「ストレージ」パッケージまたは「parserstorage」パッケージのいずれかに属していると思います。

パーサーが非常に多くのデータを生成するので、それをストレージと絡み合わせるのに必要なパフォーマンスの観点からは、パーサーパッケージにストレージのインターフェイスを定義し、それらを「ストレージフレーバー」パッケージに実装できます。

1
chromanoid

循環依存関係は、アーキテクチャのwhich-class-is-responsible-forが正しくないことを示す指標になる可能性があります。

通常あなたは持っています

  • 技術コンポーネント(csv-parserまたはhtml-table-displayなど)および
  • で構成されるビジネスドメインコンポーネント(つまり、製品データ)
    • データ項目(名前、説明、価格などの製品値)、
    • データリポジトリ(csvから/への製品データのロードを保存するため(csv-parserを使用)および/またはデータベース)
    • data-gui(フォームの編集、リスト(html-table-displayを使用)、...製品)
    • servicesまたはmvc-models(つまり、csv-repositoryからproduct-itemsをロードして処理を行うか、データベースリポジトリに保存するか、結果を表示します)

このアーキテクチャは、循環依存を回避します。

  • 技術コンポーネントには、ドメインコンポーネントに関する知識がありません。
  • クラス間の調整はサービスやモデルで行われます

この例はパッケージ化されます

  • 2つの技術コンポーネント
    • io(csv-parserを含む)、
    • html-tools(html-tableツールを含む))
  • および1つのビジネスドメインコンポーネント
    • productdata(csv /データベースからロード/保存して、Webページにリストとして表示できます)
0
k3b