Перечисления как объекты-значения и модульность
Я хотел бы разделить приложение Grails на более мелкие плагины. Некоторые доменные классы имеют атрибуты типа Enum. Некоторые значения из этих Enums логически будут частью плагинов, поэтому я ищу способ для каждого плагина зарегистрировать свои собственные значения в "основных" Enums.
Очевидно, что это невозможно сделать с помощью Enums, поскольку их нельзя изменить во время выполнения.
Один из вариантов, который я вижу, - это заменить каждый Enum классом со статическими атрибутами и добавить статический метод для регистрации новых значений из плагинов. Это имеет следующие последствия:
- GORM не будет знать, что хранить для поддельных значений Enum, поэтому он выдаст исключение
- Поэтому мне пришлось бы изменить тип этих атрибутов на String, таким образом, он будет по-прежнему работать с существующими значениями в хранилище, но я теряю преимущество наблюдения, где этот атрибут может принимать свои значения.
Есть лучший способ сделать это? Я использую подход, который не является "путем Грааля"?
В конце я ищу способ сделать точку расширения в основном приложении для плагинов, как я сделал бы с ServiceProvider в Java.
2 ответа
У меня такое ощущение, что вы слишком усложняете эту проблему, я бы определил перечисления в разных файлах в зависимости от их типа, как, вероятно, они есть сейчас, а затем использовал бы их в своих приложениях. Лично я предпочитаю группировать перечисления по типу, а не по их применению, но это зависит от вашего дизайна.
Что касается точки расширения, если вы определите их в ядре плагина, по природе плагина Grails у вас будет возможность расширения. Это означает, что ваши приложения могут переопределять или расширять эти значения. Надеюсь это поможет
Я столкнулся с той же проблемой в процессе разработки. Есть одно решение, которое я нашел.
Перенесите свои перечисления в домены и начальные значения с вашими плагинами. Создайте статические методы для получения значений, чтобы домены выглядели как перечисления. Например:
class Person {
String name
static mapping = {
cache usage: 'read-only'
table 'Person '
id column: 'Person ID', generator: 'identity'
name column: 'Name'
}
static Person getJOHN() {
getByName('John')
}
static Person getByName(String name) {
Person.findByName(name)
}
}