I have a abstract class which is extended by many many other classes:
What I have done:
public abstract class AbstractActionHandler {
protected WorkItem currentWI;
protected String status;
protected String field;
protected void init(WorkItem currentWI, String status, String field) throws IllegalArgumentException, SecurityException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
this.currentWI = currentWI;
this.status = status;
this.field = field;
if(couldBeExecuted()) {
this.executeAction();
}
}
protected boolean couldBeExecuted() throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, SecurityException, NoSuchMethodException {
long start = System.currentTimeMillis();
DataObjectFactory fact = DataObjectFactory.getFactory(currentWI);
DataWorkItem currentWI = fact.getDataWorkItem("current");
long end = System.currentTimeMillis();
System.out.println("+++++ " + " Workitem Factory takes " + (end-start) + "ms " + "+++++");
// Other logic which returns false or true
// [...]
}
// Implementation of business logic
protected abstract void executeAction();
// Should call init function
public void execute(WorkItem currentWI, String status, String field) throws IllegalArgumentException {
this.init(currentWI, status, field);
}
}
Now I figured out that the creation of DataWorkItem
object takes a lot of time. Because I am using an abstract factory I can simply change the line
DataObjectFactory fact = DataObjectFactory.getFactory(currentWI);
to
DataObjectFactory fact = DataObjectFactory.getBoostFactory(currentWI);
and provide another implementation of DataWorkItem
object.
Old implementation which calls an external API function which needs a lot of time and which is basically only necessary to call once:
public DataWorkItem(IWorkItem wi, String revision) {
OtherExternService externService = (OtherExternService) PlatformContext
.getPlatform().lookupService(OtherExternService.class);
IPObjectList listOfRevs = externService.getDataService().getObjectHistory(wi);
}
New implementation which calls API function only one time because of singleton implementation:
public DataWorkItem(WorkItem wi, String revision, boolean global) {
// +++
// We use a global object here which holds the history of current work item.
// We only need to read this history once so we create a singleton here.
// The performance is hardly improved by this pattern.
// We use this constructor in DataBoostObjectFactory.
// +++
IPObjectList listOfRevs = WorkItemGlobal.getInstance(wi).getObjectList();
}
Singleton class:
public class WorkItemGlobal {
public static WorkItemGlobal instance = null;
private IPObjectList listOfRevs;
private WorkItemGlobal(WorkItem wi) {
OtherExternService externService = (OtherExternService) PlatformContext
.getPlatform().lookupService(OtherExternService.class);
listOfRevs = externService.getDataService().getObjectHistory(wi);
}
public static WorkItemGlobal getInstance(WorkItem wi) {
if(instance == null) {
instance = new WorkItemGlobal(wi);
}
return instance;
}
public static void deleteInstance() {
instance = null;
}
public IPObjectList getObjectList() {
return listOfRevs;
}
}
Question:
Is it good to use a Singleton here?
Of course I can avoid using a singleton if I create the DataWorkItem
object outside of the classes which extends AbstractActionHandler
and pass the object to the constructor (for example).
But with this approach I have to adjust ALL classes which extends AbstractActionHandler
because I have to call a function (or change constructor) which passes the DataWorkItem
object to the abstract class.
At all it works good (for now). I can see a hardly improved performance because the call to the external API function is only done once.
Other suggestions or ideas?