もう1つのオプションは、作成とクエリから抽象化することです。これにより、パフォーマンス/使いやすさの点でボトルネックになったときに、特定の実装を簡単に最適化/拡張できる可能性があります。
このようなインターフェースは次のようになります。
public interface IEntityManager {
// methods for retrieving entities by plain queries
Component getComponent(String package, String componentName);
Model getModel(String package, String modelName);
Function getFunction(String name);
// more specific queries
List<Component> getComponents(Function function);
List<Model> getModels(Function function);
// even more specific queries ...
}
このようにして、任意の実装に必要なレベルのパフォーマンスを提供しながら、本番コードでこのインターフェイスを使用できます。
Component
さて、具体的な実装に関しては、すべて、インスタンス、およびそれらの関係に応じてわずかな違いがModel
あります。Function
- アプリケーションの開始時(デスクトップアプリのメソッドの開始時やWebアプリのメソッドの開始時など)に作成され、アプリケーションの実行中に変更されない
main
ServletContextListener.contextInitialised
- アプリケーションの実行中に作成/削除/更新されます
単純なので、最初のケースから始めましょう。すべてComponent
のインスタンス(およびそれらの間の関係)が、これらのエンティティを使用してロジック間で共有されるインスタンスに認識されていることを確認する必要がModel
あります。これを実現する最も簡単な方法の1つは、エンティティクラスを実装と同じJavaパッケージに入れ、コンストラクタをパッケージプライベートにして、作成ロジックを具体的な実装に移行することです。Function
IEntityManager
IEntityManager
IEntityManager
package com.company.entities;
public class Component {
public final String package;
public final String name;
Component(String package, String name) {
this.package = package;
this.name = name;
}
// ...
}
// similar Model and Function class declarations
public class EntityManager implements IEntityManager {
private final Map<Pair<String, String>, Component> components = new HashMap<Pair<String, String>, Component>();
private final Map<Pair<String, String>, Model> models = new HashMap<Pair<String, String>, Model>();
private final Map<String, Function> functions = new HashMap<String, Function>();
// variation of factory-method
public Component addComponent(String package, String name) {
// only this EntityManager can create instances
// so one can be sure all instances are tracked by it
final Component newComponent = new Component(package, name);
components.put(new Pair(package, name), newComponent);
}
// ... addModel, addFunction methods
public void addFunctionToModel(Function function, Model model) {
// here one should store 'somehow' information that function is related to model
}
public void addModelToComponent(Model model, Component component) {
// here one should store 'somehow' information that model is related to component
}
// ... other methods
}
最初のケース(すべてのエンティティはアプリケーションの開始時に作成されます)では、Builderパターンを使用してEntityManager
クラスのインスタンスを作成することもできます。これにより、作成ロジックが使用法から明らかに抽象化されます。ただし、2番目のケースでは、クラスに、のようなメソッドが必要addComponent
ですaddModelToComponent
(1つのインスタンスのシングルインスタンスをマルチスレッドで使用する場合はEntityManager
、メソッドで状態をスレッドセーフに変更することを検討する必要があります)。
そして最後に、エンティティ間の関係をどのように正確に保存する必要があるかについてです。そのような関係を持つエンティティを効率的に保存/取得するための特効薬はありません。関係がそれほど多くないエンティティが1000を超えない場合、検索はHashMap<String, Function>
非常に高速であり、ボトルネックになることはありません。そして、それがボトルネックになった場合、どの種類のクエリがより頻繁に使用され、どの種類のクエリがめったに使用されないかを徹底的に調べ、その観察に基づいてEntityManager
内部実装を調整する必要がありIEntityManager
ます。
アプリケーション内のインスタンスに関してはEntityManager
、明らかに、インスタンスは1つだけである必要があります(非常に特殊な場合を除く)。これは、Singleton
パターン(あまり好ましくないソリューションですが、しばらくは正常に機能する可能性があります)を使用するか、アプリケーションEntityManager
の開始時にインスタンス化して、明示的なインスタンスをそれを必要とするクラス/メソッドに渡すことで実現できます(より好ましいソリューション)。
お役に立てれば ...