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


11

シナリオ:

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

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

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

    EntityManager.save(entity);

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

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

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

私の質問:

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

この質問は似ているが、全く同じではない... softwareengineering.stackexchange.com/questions/180012/...
ジョンRaynor

回答:


7

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

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

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

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

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

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

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

もちろんです。

これを回避するには?

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

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

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


私が正しく理解している場合、更新がfunctions / stored-procsでもORMでも発生している場合、特定のトランザクションの状態を推測するのが非常に難しいという技術的な問題がある可能性があります。アプリケーションは現在の状態で動作する可能性がありますが、小さな変更がいくつかの非常に大きな問題につながる可能性があります。Hibernateでの私の経験は、Hibernateが動作するテーブルのセット全体を管理させないと、多くの厄介な問題が発生するということです。
JimmyJames

素晴らしく簡潔な答え。SRPは、コードを初めて見たときに最初に思い浮かんだものです。一部の同僚は、このメソッドはデータベース関数のみを呼び出すため、SRPに違反しないと述べています。しかし、それらの関数のいくつかは、選択、挿入、更新を行います。それでは、SRPに違反しているかどうかを確認します。(たぶん、これ自体は個別に議論する別の質問ですか?)
linuxunil

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

@linuxunil SRPは、アーキテクチャのすべてのレベルで尊重されるべきです。私の場合、メソッドレベルではなく、サービスのレベルでのSRPを意味しました。@ JimmyJamesうん。ほとんどのORMは、ストアドプロシージャではうまく機能しません。しかし、時々保存されたプロセスが必要です。
Vladislav Rastrusny 16

3

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

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

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

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


これが反対投票された理由がわかりません。この回答では、さまざまな問題に対処するコードを分離することをお勧めします。ここでプログラミングのプリンシパルのように感じます...それが何かはわかりません...男。名前が思い出せればいいのに。+1 BTW
Greg Burghardt

それは確かな原則の1つではありませんか?
J. Pichardo

3
特許SOLIDにおける「S」であり、Sは、責任主体(SRP)イングル。ただし、推奨する懸念の分離は、サービスロジックをデータアクセスロジックから分離する正当な理由です。ウラジスラフのもう1つの答えは、単一責任主任について述べています。率直に言って、SRPと懸念の分離は、ワインやチーズのようにうまく調和しています。
Greg Burghardt、2016
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.