複数の部門があり、部門ごとに個別の処理クラスがあるアプリケーションを作成しています。各部門と部門の処理は、別々のクラスで表されます。
そのため、Javaのmainメソッドは、ifelseラダーのシリーズのように見えます。
元々書かれたクラスをあまり変更せずに、後で部門とその処理クラスを追加できるように、より柔軟にする方法はありますか?
Abstract Factoryパターンについて読みましたが、それ以外の解決策はありますか?
複数の部門があり、部門ごとに個別の処理クラスがあるアプリケーションを作成しています。各部門と部門の処理は、別々のクラスで表されます。
そのため、Javaのmainメソッドは、ifelseラダーのシリーズのように見えます。
元々書かれたクラスをあまり変更せずに、後で部門とその処理クラスを追加できるように、より柔軟にする方法はありますか?
Abstract Factoryパターンについて読みましたが、それ以外の解決策はありますか?
「Department」のように、部門を非表示にするインターフェースを作成します。次のようなメインメソッドを記述します。
main() {
String criteria = ...; // this is how we choose the department to use,
// and you probably don't want to use a String
// but some other, more expressive type
for (Department department : departments) {
if (department.supports(criteria)) {
department.doWhatever();
}
}
}
次に、依存性注入を使用してdepartments
コレクションにデータを入力します。設定方法によっては、純粋な構成である可能性があります。
このトピックに特化したWebサイト全体があります。何をしようとしているかによっては、ポリモーフィズムと場合によってはリフレクションを使用する必要があります。
各状態のフィールドで列挙型を作成できます。次に、列挙型に抽象メソッドinit()
を作成し、メンバーごとに実装します。
コードでは、たとえばプロパティファイルから状態を取得して、次のように言うことができます。State.valueOf(state).init()
抽象ファクトリパターンは、おそらくあなたが説明したシナリオに最も適しています。部門プロセッサの階層と、それに対応する部門クラスの階層が必要になります。抽象ファクトリは、いくつかの識別子に基づいてペアごとに具体的なファクトリを生成し、部門を処理して、Departmentオブジェクトを返します。
アプリケーションの残りの部分は、部門オブジェクトの作成の違いを認識する必要はありません。これは、FActoryを使用して、部門が適切なディスクリミネーターを通過するようにするためです。
新しい部門を追加するには、新しい部門クラス、プロセッサクラス、およびファクトリロジックの更新が必要になります。
または、部門の構造はすべて同じであるが処理が異なる場合は、戦略パターンのようなものを使用することを検討できます。この場合、部門は1つですが、代わりに戦略の処理に関する決定が行われます。したがって、適切な戦略が部門に注入され、部門の動作はそれに応じて異なります。
「ファクトリ」または「アブストラクトファクトリ」デザインパターンを使用することが最初のステップになります。これにより、オブジェクト初期化ロジックがメインコードから削除され、ファクトリクラスで分離されます。このようにして、メインコードは変更のために閉じられ、拡張のために開かれます(別名Open Closed Principle)。行った変更は、ファクトリクラスで分離されます。
これをさらに一歩進めたい場合は、リフレクションを使用することもできます。例は次のとおりです。
static Object createObject(String className) {
Object object = null;
try {
Class classDefinition = Class.forName(className);
object = classDefinition.newInstance();
} catch (InstantiationException e) {
System.out.println(e);
} catch (IllegalAccessException e) {
System.out.println(e);
} catch (ClassNotFoundException e) {
System.out.println(e);
}
return object;
}
このコードを使用すると、次のようなオブジェクトを簡単に作成できます。
public static void main(String[] args) {
NewDepartment dep = (NewDepartment) createObject("yourpackage.NewDepartment");
}
もちろん、リフレクションを使用する場合はトレードオフがあります。それを使用するかどうかはあなたの裁量です。