0

私はAspectJのタイプにディスパッチするためのより良い方法を決定しようとしています。3種類のノードを持つツリーで計算を実行しているとします。次に、簡単なJavaメソッドを記述できます。

private void computation(TreeNode node) {
    if (node instanceof Node0) {
        // Do stuff.
    } else 
    if (node instanceof Node0) {
        // Do stuff.
    } else 
    if (node instanceof Node0) {
        // Do stuff.
    }
}

また

private void computation(TreeNode node) {
    switch (node.kindNode()) {
        case NODE0:
            // Do stuff.
            break;
        case NODE1:
            // Do stuff.
            break;
        case NODE2:
            // Do stuff.
            break;
    }
}

または、各ノードタイプにメソッドを挿入できます。

private void Node.computation() {
    throw new UnsupportedOperationException(getClass() + ".computation()");
}

private void Node0.computation() {
    // Do stuff.
}

private void Node1.computation() {
    // Do stuff.
}

private void Node2.computation() {
    // Do stuff.
}

どの方法が好ましいのか、そしてその理由は?

4

1 に答える 1

1

何が好ましいかは、状況によって大きく異なります。

私があなたの問題を正しく理解していれば、この「計算」メソッドを事後的に既存の型階層に追加したいのですが、元の型のソースコードを変更することはできませんよね?

この場合、最も重要な問題は、ノード タイプの階層がどのくらいの頻度で変更されるかということです。そのような変更はおそらくアスペクトを調整することを余儀なくされるため、これは保守上の問題です。

そうは言っても、あなたの3番目の提案は「正規の」オブジェクト指向ソリューションです。一般的なプログラミングでは、通常、switch-case アプローチよりも優先されます。後者は、操作が非常に短く単純でない限り、複雑で理解しにくいコードになる傾向があるためです。computation()基本的に、あなたの場合のように、AspectJ ベースのソリューションにも同じことが当てはまります。ただし、複数のサブクラスに定義を挿入する必要があるため、アスペクトの設定は少し難しくなります。一方、スイッチ ケース ソリューションを使用する場合は、基本クラスに小さな転送メソッドを挿入するだけです。そこから、スイッチオンタイプを保持するプレーンな Java クラスにジャンプします。

ビジター パターン: 実際、ここで行うことは、アスペクトを使用してエレガントに実装できるビジター パターンの古典的なユース ケースのように見えます。おそらくそれが最もクリーンな解決策ですが、訪問者パターン自体は高度なトピックです (興味があれば、より詳細に説明できます)。

于 2010-09-12T00:46:47.060 に答える