シナリオ:
サービス層クラスには3つの動作があります。
一部のサービスには、メソッド内にビジネスルールがあり、永続性をアプリケーションに委任します。お気に入り:
EntityManager.save(entity);
一部のサービスは、単純にデータベース関数(パラメーターを渡す)を呼び出します。
CallableStatement cls = con.prepareCall( "{call databaseFunction(args)}");
一部のサービスには、both動作のメソッドがあります。
私の質問:
アプリケーションサービスに直接データベース関数を呼び出しても問題はありませんか?これは悪い習慣ではありませんか?
あると思います。アプリケーションサービスのデータベース内部に関する知識を配置します。何らかの方法でデータベースを変更する(ストレージエンジンを変更する、フィールドの名前を変更する、またはインデックスを作成する)には、アプリケーションサービスを変更する必要があり、これは [〜#〜] srp [〜#〜] に違反します。
このようなプロジェクトに適用できるアーキテクチャモデルは何でしょうか?
以下のコメントを参照してください。
同じサービスに動作を混在させることに問題はありますか?トランザクションや一貫性など?
技術的な問題はないと思いますが、論理的な問題があります。アプリケーションで2つのアプローチを混合するだけで、漠然としていて、構造化されておらず、変更への適応が困難になります。 SRP違反に関する上記のコメントも参照してください。
メンテナンスの場合、このカプセル化により、開発者はデータベースの機能も変更する必要があることがわかりにくくなりますか?
もちろんです。
これを回避するには?
データベースと直接連携するメソッドと関数を、抽象化の別のレベルに配置します(DAOレイヤーか単純なリポジトリパターンか-アプリケーションの複雑さに依存します)。
このシナリオは世界中の他のアプリケーションで発生しますか、それとも単なるアーキテクチャ上のエラーですか?
私たちの世界ではすべてが起こると思います;)
あなたの言ったところによると、サービスレイヤーがあるので、適切と思われるアーキテクチャパターンはレイヤードアーキテクチャです。 参考資料
ええ、通常、データアクセスレイヤー以外で直接データベースコールを行うのは悪い習慣です。そのため、ビジネスレイヤーはデータベースの抽象化にのみアクセスします。
ミキシング動作に関しては、DAOパターンまたはリポジトリパターンとしていくつかのデザインパターンを使用すると、その責任を委任してコードを改善するのに役立ちます。
デザインパターンとORMを使用する利点のいくつかは、コードの可読性と責任のカプセル化であるため、データベースアクセスが変更されてもビジネスレイヤーはあまり変更されません。