之前的情况:
存在资源。Root 类被创建,在它的创建过程中它创建了子类(一个基类的许多实现)。那些可以,但不是必须,拥有孩子。基本上,这是一个典型的树形结构,它自己构建。
其中一个子类“NeedyChild”需要访问在创建 Root 期间打开的资源。只有一个 Resource 可能,所以我将其设为单例并通过 Resource.getInstance() 从 NeedyChild 访问它;
现在的情况:
我必须建造许多树。这些是相互独立的,需要相当长的时间,所以我让它并发。不幸的是,每棵树都有自己的资源。
问题:现在如何访问特定于当前可运行的资源?
我的解决方案:
使 Child 基类在其构造函数中需要 Resource 参数。优点:速度很快。它相当有效(传递引用没什么大不了的),很简单。缺点:它需要我在整个应用程序中更改构造函数调用和签名,可能超过 100 个位置。
反射使基础构造函数找到它的调用者,保存引用,然后将资源提供给 Root,NeedyChild 将向上“创建者”层次结构获取 Root,然后获取资源。但我不会那样做,这是邪恶的。
没有研究它,但也许我可以访问代码当前正在内部执行的父 Runnable?将其转换回我的 RunnableClass 可以包含对资源的引用?问题是:我不知道这是否可能,它似乎也有点“错误”......
(不是真的工作)使树可以双向遍历,将 Resource 提供给 Root 并从 NeedyChild getParent() 提供足够长的时间,直到您处于 Root 位置。这会很棒,但是 NeedyChild 在创建过程中需要 Resource,并且只有在创建之后,它才会附加到父级。我想过延迟填充与资源相关的字段,但它很快就变得丑陋了。
TBH 我可能不得不修改基本构造函数并传递“this”(这样我就可以遍历回根),或者传递 Resource. 特定于可运行的上下文似乎也相当不错,但是我已经在进行并行处理以使事情变得更快,我真的不想通过一些非常慢的反射查找来否定它...
那么,有什么想法吗?
附录 1:示例代码
abstract class BaseElement{
List<BaseElement> children = new ArrayList<>();
public void addChild(BaseElement child){
children.add(child);
}
}
class Loader{
private PackageElement resultPackage;
private Resource resource;
public Loader(Resource resource){
this.resource = resource;
}
public callMeFromOutside(SourceTree source){
resultPackage = new Package(source.pack());
}
}
class PackageElement extends BaseElement {
public PackageElement(PackageTree pack){
this.addChild(new Element(pack.element()));
}
}
class Element extends BaseElement{
public Element(ElementTree element){
this.addChild(new NeedyChild(element.needyChild()));
}
}
class NeedyChild extends BaseElement{
public NeedyChild(NeedyTree needy){
this.setSomethingImportant(resource.loadSomethingBasedOn(needy));
}
}