web-dev-qa-db-ja.com

読みやすさとポリモーフィズムの利点

私たちは、アプリケーションで多くのCRUD操作を扱っています。各データベーステーブルには、さまざまなタイプの操作を実行するための1つ以上の対応するSQLContainerインスタンスがあります。これらのSQLContainerはすべて1つのヘルパークラスに格納されているため、プログラムのどこからでも任意のタイプのCRUD操作を実行できます(そのヘルパークラスへの参照がある場合)。

アプリケーションの規模が急速に拡大している今、このデータベースヘルパークラスも大幅に拡大しています(5+ KLOC)。このヘルパークラスの成長は、すべてのSQLContainerが同じ操作を実行するための個別のメソッドセットを持っているという事実によって影響を受けました。 employeeContainerをコミットする必要がある場合は、commitEmployeesContainer()を呼び出すため、メソッド名を読み取るだけで、アクションが明確にわかります。 (getEmployeesContainer()。commit()を呼び出すこともできますが、コミット後にいくつかの追加操作を実行します。たとえば、いくつかのコンテナーを除いて、各コンテナーでほぼ同じコミットのステータスコードを取得します)

現在、このヘルパークラスにポリモーフィズムを追加し、汎用メソッドを作成することを検討しています。レコードをコミットするためにcommitContainer(getEmployeesContainer())を使用できますが、そのようなポリモーフィズムには型安全性がまったくなく、一部のテーブルに異なるコンテナーがほとんどない場合、誤って間違ったコンテナーを渡す可能性があります。

利点の1つは、新しいSQLContainerが追加されるときに新しいメソッドのセットを追加する必要がないことです。また、コミットアルゴリズムへの変更を簡単に適応させることができます。

質問:
読みやすさを維持しながらメンテナンスを容易にするアプローチはどれですか、それともこのタイプの問題に対する代替ソリューションはありますか?

1
rpozarickij

この種の一般的なアプローチは、静的ヘルパーメソッドを使用してクラス(名前が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 パターンはオプションですが、読みやすさを維持しながら、プログラムを非常に柔軟で簡単に保守できるようになっていることがわかりました。お役に立てば幸いです。

4
Neil