あるエンティティから別のエンティティへの値のコピーを処理するプロジェクトで、クラスを AttributeUpdater という名前にします。コア メソッドは、エンティティの属性を走査し、指定されたとおりに 2 番目の属性にコピーします。そのループ中に、AttributeUpdater は、コピー中に上書きされた値に関する情報を含むすべてのレポートを、最終的なログ記録のために適切なリストに収集します。このリストは、値が上書きされた古いエンティティがデータベースに永続化されなかった場合に削除されます。その場合、デフォルト値と冗長と見なされるログのみが上書きされるためです。疑似 Java コードの場合:
public class AttributeUpdater {
public static CopyResult updateAttributes(Entity source, Entity target, String[] attributes) {
List<CopyReport> reports = new ArrayList<CopyReport>();
for(String attribute : attributes) {
reports.add(copy(source, target, attribute));
}
if(target.isNotPersisted()) {
reports.clear();
}
return new CopyResult(reports);
}
}
エンティティがまだ永続化されていなくても、レポートが実際に重要なケースが 1 つあります。メソッド シグネチャに別のパラメーターを追加するだけでよいのであれば、これはそれほど大きな問題ではありませんが、クラスの実際の構造と必要な屈折の量のために、それはやや選択肢から外れています。メソッドは静的であるため、私が思いついた他の唯一の解決策は、フラグを静的フィールドとして追加し、関数呼び出しの直前に設定することです。
public class AttributeUpdater {
public static final ThreadLocal<Boolean> isDeletionEnabled = new ThreadLocal<Boolean> {
@Override protected Boolean initialValue() {
return Boolean.TRUE;
}
public static Boolean getDeletionEnabled() { return isDeletionEnabled.get(); }
public static void setDeletionEnabled(Boolean b) { isDeletionEnabled.set(b); }
public static CopyResult updateAttributes(Entity source, Entity target, String[] attributes) {
List<CopyReport> reports = new ArrayList<CopyReport>();
for(String attribute : attributes) {
reports.add(copy(source, target, attribute));
}
if(isDeletionEnabled.get() && target.isNotPersisted()) {
reports.clear();
}
return new CopyResult(reports);
}
}
ThreadLocal は、スレッドセーフに使用されるコンテナーです。このソリューションは、仕事をしますが、少なくとも 1 つの大きな欠点があります。レポートが削除されることを前提とする他のすべての方法では、それらのレポートが期待どおりに削除されることを保証する方法がありません。ここでも、屈折はオプションではありません。だから私はこれを思いついた:
パブリック クラス AttributeUpdater {
private static final ThreadLocal<Boolean> isDeletionEnabled = new ThreadLocal<Boolean> {
@Override protected Boolean initialValue() {
return Boolean.TRUE;
}
public static Boolean getDeletionEnabled() { return isDeletionEnabled.get(); }
public static void disableDeletionForNextCall() { isDeletionEnabled.set(Boolean.FALSE); }
public static CopyResult updateAttributes(Entity source, Entity target, String[] attributes) {
List<CopyReport> reports = new ArrayList<CopyReport>();
for(String attribute : attributes) {
reports.add(copy(source, target, attribute));
}
if(isDeletionEnabled.get() && target.isNotPersisted()) {
reports.clear();
}
isDeletionEnabled.set(Boolean.TRUE);
return new CopyResult(reports);
}
}
このようにして、古いコードの場合、関数が変更前と同じように常に機能することを保証できます。このソリューションの欠点は、特にネストされたエンティティの場合、ThreadLocal-Container に頻繁にアクセスすることです。それらの 1 つに対する反復は、ネストされた要素ごとに disableDeletionForNextCall() を呼び出すことを意味します。また、このメソッドは全体的に頻繁に呼び出されるため、有効なパフォーマンス上の懸念があります。
TL;DR: 疑似 Java ソース コードを見てください。1 つ目は古いコードで、2 つ目と 3 つ目は削除を無効にするための別の試みです。パラメータをメソッド シグネチャに追加することはできません。
どちらのソリューションが優れているかを判断する可能性はありますか、それとも単に哲学的な問題ですか? または、この問題に対するより良い解決策はありますか?