2

以前の状況:

リソースが存在します。クラス ルートが作成され、その作成中に子クラス (1 つのベースの多数の実装) が作成されます。それらは子供を所有できますが、所有する必要はありません。基本的に、これはそれ自体で構築される典型的なツリー構造です。

子クラスの 1 つ「NeedyChild」は、ルートの作成中に開かれたリソースへのアクセスを必要とします。可能なリソースは 1 つだけだったので、それをシングルトンにして、Resource.getInstance(); によって NeedyChild からアクセスしました。

今の状況:

私はたくさんの木を作らなければなりません。これらは互いに独立しており、かなり時間がかかるため、並行処理にしました。残念ながら、各ツリーには独自のリソースがあります。

質問: 現在の実行可能なリソースに固有のリソースにアクセスする方法を教えてください。

私の解決策:

  1. Child 基本クラスに、そのコンストラクターで Resource パラメーターが必要になるようにします。長所:速いです。これはかなり効率的で (参照を渡すことは大したことではありません)、単純です。短所: アプリケーション全体でコンストラクターの呼び出しとシグネチャを変更する必要があり、おそらく 100 か所を超える可能性があります。

  2. ベースコンストラクターが呼び出し元を見つけ、参照を保存し、リソースをルートに渡すためのリフレクション。NeedyChild は「作成者」階層を上ってルートを取得し、次にリソースを取得します。しかし、私はそれをしません、それは悪です。

  3. 調査しませんでしたが、コードが現在内部で実行されている親 Runnable にアクセスできるでしょうか? リソースへの参照を保持できる RunnableClass にキャストし直しますか? 問題は次のとおりです。それが可能かどうかはわかりません。少し「間違っている」ようにも思えます...

  4. (実際には機能していません)ツリーを両方の方法でトラバース可能にし、リソースをルートに与え、NeedyChild getParent() からルートに到達するまで十分に長くします。それは素晴らしいことですが、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));
    }
}
4

1 に答える 1