私たちは、アプリケーションで多くのCRUD操作を扱っています。各データベーステーブルには、さまざまなタイプの操作を実行するための1つ以上の対応するSQLContainerインスタンスがあります。これらのSQLContainerはすべて1つのヘルパークラスに格納されているため、プログラムのどこからでも任意のタイプのCRUD操作を実行できます(そのヘルパークラスへの参照がある場合)。
アプリケーションの規模が急速に拡大している今、このデータベースヘルパークラスも大幅に拡大しています(5+ KLOC)。このヘルパークラスの成長は、すべてのSQLContainerが同じ操作を実行するための個別のメソッドセットを持っているという事実によって影響を受けました。 employeeContainerをコミットする必要がある場合は、commitEmployeesContainer()を呼び出すため、メソッド名を読み取るだけで、アクションが明確にわかります。 (getEmployeesContainer()。commit()を呼び出すこともできますが、コミット後にいくつかの追加操作を実行します。たとえば、いくつかのコンテナーを除いて、各コンテナーでほぼ同じコミットのステータスコードを取得します)
現在、このヘルパークラスにポリモーフィズムを追加し、汎用メソッドを作成することを検討しています。レコードをコミットするためにcommitContainer(getEmployeesContainer())を使用できますが、そのようなポリモーフィズムには型安全性がまったくなく、一部のテーブルに異なるコンテナーがほとんどない場合、誤って間違ったコンテナーを渡す可能性があります。
利点の1つは、新しいSQLContainerが追加されるときに新しいメソッドのセットを追加する必要がないことです。また、コミットアルゴリズムへの変更を簡単に適応させることができます。
質問:
読みやすさを維持しながらメンテナンスを容易にするアプローチはどれですか、それともこのタイプの問題に対する代替ソリューションはありますか?
この種の一般的なアプローチは、静的ヘルパーメソッドを使用してクラス(名前がDAOで終わる)を作成し、その特定のデータベーステーブルに関連するCRUDメソッドを実行することです。その静的クラスは、派生クラスを支援する保護されたメソッドを持つ共通の静的クラスから派生します。
たとえば、静的クラスUserDAO
が渡されたユーザー名に基づいてUserEntity
オブジェクトを返すことができるように、org.project.dao.UserDAO.getByUsername("MICHAELJ")
が呼び出されます。次に、UserDAO
は、スーパープロテクトメソッドget
を呼び出して、クエリを作成し、オブジェクト配列(複数の値が必要な場合は配列)を返すために必要なすべての情報を渡します。 UserDAO
は最初のものを取得してキャストし、呼び出し元に返します(または、何も見つからない場合はnull
を返します)。このようにして、DRYに違反することはなく、適切なメソッドを変更するだけで、すべての読み取りまたはUserDAO
のみに変更を加えることができます。
インスタンスを使用する場合(たとえば、データベース接続情報を保持したい場合)、それも問題ありませんが、現在のようにグローバルな方法でインスタンスにアクセスすることはできません。それを必要とするクラスに渡す必要があります。つまり、現在ヘルパークラスを使用しているすべてのクラスを変更する必要があります。
次に、私は通常、物事をさらに一歩進めて、唯一のコンストラクター引数としてUser
インスタンスをとるUserEntity
クラスを作成します。私のプログラム全体を通して、私はUser
を使用して、情報を取得および設定し、優れた機能とデータ検証を処理します。このように、UserEntity
が変更された場合、それがキーフィールドでない限り、UserDAO
を変更する必要はなく、残りを変更せずにUser
にゲッターとセッターを追加するだけで済みます。 User
クラスは、UserDAO
と直接インターフェースする唯一のクラスであるため、必要に応じて簡単に修正できます。
この Façade パターンはオプションですが、読みやすさを維持しながら、プログラムを非常に柔軟で簡単に保守できるようになっていることがわかりました。お役に立てば幸いです。