另一种选择是从创建和查询中抽象出来,因此当它成为性能/易用性方面的瓶颈时,可以轻松地优化/扩展某些实现。
这样的界面如下所示:
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 ...
}
通过这种方式,可以在生产代码中使用此接口,同时提供具有所需性能级别的任意实现。
现在,关于具体实现 - 取决于是否 allComponent
和实例及其关系Model
略有不同:Function
- 在应用程序开始时的某处创建(例如,在桌面应用程序的方法开始处或在Web应用程序中),并且在应用程序执行期间不会更改
main
ServletContextListener.contextInitialised
- 在应用程序执行期间创建/删除/更新
让我们从第一种情况开始,因为它更简单:应该确保所有Component
,Model
和Function
实例(以及它们之间的关系)对于IEntityManager
使用这些实体的逻辑之间共享的实例都是已知的。实现这一点最直接的方法之一是将实体类与实现放在同一个 Java 包中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
类的实例——这将清楚地从使用中抽象出创建逻辑。但是,在第二种情况下,应该在类中具有类似addComponent
,的方法addModelToComponent
(对于单个实例的多线程使用,EntityManager
应考虑使方法修改其状态thread-safe)。
最后,关于应该如何存储实体之间的关系:没有有效存储/检索具有这种关系的实体的灵丹妙药。我想说,如果一个实体的关系不超过 1000 个,那么搜索HashMap<String, Function>
将很快,不应该成为瓶颈。如果它成为瓶颈,应该彻底检查哪种查询更频繁使用,哪些很少使用,并根据观察调整EntityManager
内部实现 - 因此建议抽象所有IEntityManager
接口。
Concerning instance of EntityManager
in application - obviously, there should be only one instance of it (unless one has very special case). One can achieve this using Singleton
pattern (less preferred solution, though it may work fine for some time), or simply instantiating EntityManager
at the beginning of application and passing explicit instances to classes / methods which need it (more preferred solution).
Hope this helps ...