AspectJ中的多态性

AspectJ中的多态性,aspectj,dispatch,aspects,Aspectj,Dispatch,Aspects,我正在尝试决定在AspectJ中,哪一种是对类型进行分派的更好方法。 假设我在一棵有三种节点的树上执行计算。然后我可以编写一个简单的Java方法: private void computation(TreeNode node) { if (node instanceof Node0) { // Do stuff. } else if (node instanceof Node0) { // Do stuff. } else

我正在尝试决定在AspectJ中,哪一种是对类型进行分派的更好方法。 假设我在一棵有三种节点的树上执行计算。然后我可以编写一个简单的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 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.
}

哪种方法更可取以及为什么?

什么更可取在很大程度上取决于具体情况

如果我理解你的问题是正确的,那么你想在事实发生后以某种方式将这个“计算”方法添加到已经存在的类型层次结构中,而更改原始类型的源代码不是一个选项,对吗

在这种情况下,最重要的问题是:节点类型层次结构的更改频率有多高?因为任何这样的改变都可能迫使您调整方面,这是一个维护问题

话虽如此,您的第三个建议是“cannonical”面向对象解决方案。在一般编程中,它通常优于切换案例方法,因为后者往往会导致复杂和难以理解的代码,除非
computation()
中的操作非常简短。基本上,基于AspectJ的解决方案也是如此,就像您的案例一样。但是,设置方面要稍微困难一些,因为它必须在多个子类中注入定义,而在另一种情况下,当您选择switch case解决方案时,您只需将一个小的转发方法注入基类,然后从基类跳转到持有switch on类型的普通java类中

访问者模式:实际上,您在这里所做的看起来像是访问者模式的经典用例,可以使用方面优雅地实现。这可能是最干净的解决方案,但访问者模式本身是一个高级主题(如果有兴趣,我可以更详细地解释)

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.
}