Является ли хорошей идеей использовать аспекты в качестве метода для удаления защитных проверок из логики приложения?


Довольно длинное название, но в целом это вопрос.

Я хочу знать, считаете ли вы, что это хорошая идея, чтобы сделать следующее.

Вместо:

public void buyItem(int itemId, int buyerId) {
    if (itemId <= 0) {

        throw new IlleglArgumentException("itemId must be positive");
    }
    if (buyerId <= 0) {

        throw new IlleglArgumentException("buyerId must be positive");
    }
    // buy logic
}

Я хочу иметь что-то вроде:

@Defensive("isPositive(#itemId, #buyerId)")
public void buyItem(int itemId, int buyerId) {
    // buy logic
}
Как вы думаете, это хорошо / ужасно/слишком причудливо/слишком медленно ? Если вы действительно думаете, что это хорошо, я думал использовать SpEL для его реализации, есть ли у кого-нибудь что-то лучше/легче/быстрее в виду ?

Спасибо,

5 8

5 ответов:

Это не обязательно плохо, однако ваш простой случай может быть хорошо решен с помощьюисключений утверждений (, а не утверждений О чем я и упомянул вначале).

Похоже, вы вводите свой собственный набор аннотаций, которые другие разработчики в вашем проекте должны принять и адаптировать. Однако, как только вы ввели аннотации, кажется, что обычный подход Proxy был бы лучшим кандидатом для решения проблемы.

Подведем итог: проблема в вас описанное можно легко решить с помощью стандартных альтернатив java, хотя в более сложном случае это может быть оправдано (например, @Secured в spring-security), особенно если вы разрабатываете свой собственный фреймворк .

Я думаю, что это

  • сверхинжиниринг
  • Нарушение инкапсуляции, полагаясь на внешний аспект (который может или не может быть там) для поддержания инвариантов объекта
  • путаница
  • неэффективно
  • не добавляя никакого значения

Мне нравится использовать класс предварительных условий гуавы для таких проверок. Более того, такие проверки являются частью бизнес-логики, ИМХО.

Я думаю, вы имели в виду аннотации, а не аспекты. Аспекты обычно являются внешними по отношению к коду, который они рекомендуют. В любом случае, вы можете выполнить те проверки, которые вы выделили в своем посте с помощью JSR 303. Конкретный пример:

public void buyItem(@Min(value = 1) int itemId, @Min(value = 1) int buyerId) {
    // buy logic
}
В настоящее время существуют две хорошо известные реализации JSR 303:

Это выглядит как Проверка . К вашему сведению, несколько фреймворков уже существуют, проверьте этот вопрос и овал, например.

Я не знаю о перформансах, но для меня это не сверхинжиниринг: вы сохраняете только логический код. Мне нравится работать с этим.

Я бы предпочел подход Java assertion .

  1. это стандартный подход, так что все (большинство?) Программисты Java поймут это. Автоматизированных инструментов и т. д. сможете разобрать и его тоже.
  2. Вам не нужно ничего развивать самому. Я знаю, что это выглядит тривиально, но такие вещи имеют привычку обостряться.

Если вы не можете продемонстрировать, что ваш подход явно лучше или делает что-то другое, я буду использовать инструменты и API, которые предоставляет Java в качестве стандарта.