Выбор стратегии через конфигурацию JSON

Я внедряю обучающий агент в Java / Kotlin. Часть функциональности этого агента включает в себя поиск по большому списку возможных вариантов. Есть много хороших способов поиска пространства возможностей, и я часто передумал, какой из них лучший. Поэтому я решил реализовать его в качестве шаблона стратегии.

class Agent(val searchStrategy : SearchStrategy){ fun search(input : InputGraph) : Result{ return searchStrategy.search() } } interface SearchStrategy{ fun search(input : InputGraph) : Result } class FastSearch : SearchStrategy{ //implementation here } class AccurateSearch : SearchStrategy{ // implementation here } class ExperimentalSerach : SearchStrategy{ // implentation here } 

Недавно я решил запустить большой набор экспериментов, которые проверяют эффективность различных параметров системы. Это делается через скрипт python, который запускает каждый эксперимент, запустив скомпилированную банку с другим файлом config.json в качестве аргумента. Что-то вроде:

 { "numSamples" : 5000, "environmentDifficulty" : 3, "hazardProbability" : 0.4, //etc.. } 

Теперь я хочу дать экспериментатору возможность настроить стратегию, используемую агентом. Каков наилучший способ сделать это? Я сразу подумал, что я могу просто добавить дополнительное поле строки в config.json:

 { "numSamples" : 5000, "environmentDifficulty" : 3, "hazardProbability" : 0.4, "agentStrategy": "FastSearch" } 

Затем постройте его в основной системе с веткой if или if:

 val searchStrategy = when(config.agentStrategy){ "FastSearch" -> FastSearch() "AccurateSearch" -> AccurateSearch() "ExperimentalSearch" -> ExperimentalSearch() val agent = agent(searchStrategy) 

Но похоже, что это начнет становиться неудобным / трудно поддерживать, если я начну добавлять больше стратегий. Есть ли способ лучше?

Один из способов его решения – использовать имя класса для загрузки и создать экземпляр стратегии следующим образом:

 val agentClass = classLoader.loadClass(config.agentStrategy)!! val agent = agentClass.newInstance() as SearchStrategy 

Другим способом было бы зарегистрировать все стратегии поиска, а затем сопоставить один с использованием заданной config следующим образом:

 class SearchStrategies(val strategies: List<SearchStrategy>){ fun findForConfig(config:Config) = strategies.find { it.javaClass.name.contains(config.agentStrategy) } } //somewhere at boot time val searchStrategies = SearchStrategies(listOf(FastSearch(), AccurateSearch())) //when needed val config = ... val agent = searchStrategies.findForConfig(config) 

Наконец, также возможно использовать SPI для достижения большей расширяемости и стандартного соответствия при стоимости сложности.

Intereting Posts
Kotlin + Spring загрузка запроса сортировки Потребитель, играющий странно в Котлине Назначение отдельного элемента атрибуту значения IntArray в аннотациях Kotlin Динамическая оценка шаблонных строк в Котлине Kotlin switch-statement с более чем двумя переменными? В библиотеке Injekt для Kotlin, как мне создать локальные области, например, для каждой активности Android? Как мое преобразование из String в Double не работает? Отменить возвращаемое значение для возврата Unit? Серия Autosize ScatterChart Как сделать clickable listview в android с помощью kotlin Ошибка компиляции во время преобразования класса RealmObject в Kotlin Kotlin определяет таймаут по запросу на сервер Как реализовать свойство, которое извлекается из определенного источника, пока оно не будет установлено непосредственно в Котлин? Android Studio 1.5 с плагином Kotlin получил исключение, когда он находится в режиме отладчика. Как это исправить? ByteArray для Float в kotlin