I assume that by asking this question there are runtime unknowns that prevent you from determining in advance which items will be the same across reports. Otherwise you could just reference the same instances directly.
A flyweight-style factory that caches "equivalent" instances could help reduce memory footprint. Each ReportComponent
would need some sort of parameter object to encapsulate their particular data field(s) and implement equals()
to define just what "equivalent" means.
public class ReportComponentFactory {
private final Map<String, ReportComponent> headerCache =
new HashMap<String, ReportComponent>();
private final Map<GraphParameters, ReportComponent> graphCache =
new HashMap<GraphParameters, ReportComponent>();
public ReportComponent buildHeader(String headerText){
if (this.headerCache.containsKey(headerText)){
return this.headerCache.get(headerText);
}
Header newHeader = new Header(headerText);
this.headerCache.put(headerText, newHeader);
return newHeader;
}
public ReportComponent buildGraph(GraphParameters parameters){
if (this.graphCache.containsKey(parameters)){
return this.graphCache.get(parameters);
}
Graph newGraph = new Graph(parameters);
this.graphCache.put(newGraph);
return newGraph;
}
...
}
Note that instantiating parameter objects will require some temporary memory consumption, but they should be garbage collected easily enough.