Полиморфизм в аспекте - PullRequest
0 голосов
/ 17 ноября 2009

Я пытаюсь решить, что является лучшим способом отправки типа в 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 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.
}

Какой метод предпочтительнее и почему?

1 Ответ

1 голос
/ 12 сентября 2010

то, что является предпочтительным, очень сильно зависит от ситуации.

Если я правильно понял вашу проблему, вы хотите каким-то образом добавить этот метод «вычисления» после факта в уже существующую иерархию типов, и изменение исходного кода исходных типов не вариант, верно?

В этом случае самый важный вопрос: как часто происходят изменения в иерархии типов узлов? Потому что любое такое изменение, вероятно, заставит вас скорректировать свой аспект, что является проблемой сопровождения.

Сказав это, ваше третье предложение является "каноническим" объектно-ориентированным решением. В общем программировании это обычно предпочтительнее, чем подход с переключением, потому что последний имеет тенденцию приводить к сложному и трудному для понимания коду, , если операции в computation() не являются очень короткими и простыми. По сути, то же самое верно для решения на основе AspectJ, как и в вашем случае. Но настроить аспект немного сложнее, потому что он должен внедрять определения в несколько подклассов, тогда как в другом случае, когда вы выбираете решение для случая переключения, вы просто внедрите небольшой метод пересылки в базовый класс. и прыгайте оттуда в простой класс Java, содержащий ваш тип включения.

шаблон посетителя : на самом деле то, что вы здесь делаете, выглядит как классический вариант использования шаблона посетителя, который можно элегантно реализовать с использованием аспекта. Вероятно, это было бы самым чистым решением, но сам шаблон посетителя является сложной темой (я могу объяснить более подробно, если есть интерес)

...