web-dev-qa-db-ja.com

データベースサービス関数を呼び出すアプリケーションサービス層。悪いアーキテクチャ?

シナリオ:

  • スタック:Java、Spring、Hibernate。
  • モデル:クライアントサーバーアプリケーション。
  • パターン:Model-View-Controller(MVC)。

サービス層クラスには3つの動作があります。

  1. 一部のサービスには、メソッド内にビジネスルールがあり、永続性をアプリケーションに委任します。お気に入り:

    EntityManager.save(entity);

  2. 一部のサービスは、単純にデータベース関数(パラメーターを渡す)を呼び出します。

    CallableStatement cls = con.prepareCall( "{call databaseFunction(args)}");

  3. 一部のサービスには、both動作のメソッドがあります。

私の質問:

  1. アプリケーションサービスに直接データベース機能を呼び出しても問題はありませんか?これは悪い習慣ではありませんか?このようなプロジェクトに適用できるアーキテクチャモデルは何でしょうか?
  2. 同じサービスに動作を混在させることに問題はありますか?トランザクションや一貫性など?
  3. メンテナンスの場合、このカプセル化により、開発者はデータベースの機能も変更する必要があることがわかりにくくなりますか?これを回避するには?
  4. このシナリオは世界中の他のアプリケーションで発生しますか、それとも単なるアーキテクチャ上のエラーですか?
11
linuxunil

アプリケーションサービスに直接データベース関数を呼び出しても問題はありませんか?これは悪い習慣ではありませんか?

あると思います。アプリケーションサービスのデータベース内部に関する知識を配置します。何らかの方法でデータベースを変更する(ストレージエンジンを変更する、フィールドの名前を変更する、またはインデックスを作成する)には、アプリケーションサービスを変更する必要があり、これは [〜#〜] srp [〜#〜] に違反します。

このようなプロジェクトに適用できるアーキテクチャモデルは何でしょうか?

以下のコメントを参照してください。

同じサービスに動作を混在させることに問題はありますか?トランザクションや一貫性など?

技術的な問題はないと思いますが、論理的な問題があります。アプリケーションで2つのアプローチを混合するだけで、漠然としていて、構造化されておらず、変更への適応が困難になります。 SRP違反に関する上記のコメントも参照してください。

メンテナンスの場合、このカプセル化により、開発者はデータベースの機能も変更する必要があることがわかりにくくなりますか?

もちろんです。

これを回避するには?

データベースと直接連携するメソッドと関数を、抽象化の別のレベルに配置します(DAOレイヤーか単純なリポジトリパターンか-アプリケーションの複雑さに依存します)。

このシナリオは世界中の他のアプリケーションで発生しますか、それとも単なるアーキテクチャ上のエラーですか?

私たちの世界ではすべてが起こると思います;)

7

あなたの言ったところによると、サービスレイヤーがあるので、適切と思われるアーキテクチャパターンはレイヤードアーキテクチャです。 参考資料

ええ、通常、データアクセスレイヤー以外で直接データベースコールを行うのは悪い習慣です。そのため、ビジネスレイヤーはデータベースの抽象化にのみアクセスします。

ミキシング動作に関しては、DAOパターンまたはリポジトリパターンとしていくつかのデザインパターンを使用すると、その責任を委任してコードを改善するのに役立ちます。

デザインパターンとORMを使用する利点のいくつかは、コードの可読性と責任のカプセル化であるため、データベースアクセスが変更されてもビジネスレイヤーはあまり変更されません。

3
J. Pichardo