Для теста попробуем отрефакторить один и тот же метод на языке Kotlin с помощью двух моделей: ChatGPT и Llama-3, запущенной на локальном компьютере.
data class ButtonsProperties(
val defaultButton: Button,
val customButtonsByOs: Map<OperationSystem, List<CustomButton>>,
) {
// для некоторых мобильных клиентов в соответствии с их ОС и версией приложения нужно переопределять кнопку
fun getButton(headers: Headers): Button {
// получаем список переопределенных кнопок, соответствующих ОС клиента
val customButtons: List<CustomButton> = if (headers.os != null) {
customButtonsByOs.getOrDefault(headers.os, Collections.emptyList())
} else {
Collections.emptyList()
}
return if (customButtons.isEmpty() || headers.appVersion == null) {
// если не подошла ОС или не указана версия клиента
defaultButton
} else {
getButtonBySupportedVersion(
headers = headers,
customButtons = customButtons,
defaultButton = defaultButton,
)
}
}
// из списка кнопок для переопределения выбираем кнопку с максимальной версией, которая не превышает версию нашего клиента
private fun getButtonBySupportedVersion(
headers: Headers,
customButtons: List<CustomButton>,
defaultButton: Button,
): Button = customButtons
.filter { it.version <= headers.appVersion }
.maxWithOrNull(comparator = Comparator.comparing(CustomButton::version))
?.button ?: defaultButton
data class CustomButton(
val version: ApplicationVersion,
val button: Button,
)
}
Что делает метод? Выбирает кнопку в зависимости от заголовков, с которыми пришел мобильный клиент: в качестве дефолтной будет выбираться defaultButton, а в качестве альтернативы — одна из customButtonsByOs.
Какие проблемы сразу бросаются в глаза?
val customButtons: List<CustomButton> = if (headers.os != null) {
customButtonsByOs.getOrDefault(headers.os, Collections.emptyList())
} else {
Collections.emptyList()
}
.maxWithOrNull(comparator = Comparator.comparing(CustomButton::version))
Предлагаю сразу скормить обеим моделям исходный код с запросом
Проведи рефакторинг этого кода на языке Kotlin, чтобы он стал читабельнее и компактнее:
и посмотреть на результаты. (Далее в примерах объявление класса буду опускать.)
Давайте посмотрим, что получилось:
fun getButton(headers: Headers): Button {
val customButtons = customButtonsByOs[headers.os].orEmpty()
return customButtons.takeIf { headers.appVersion != null }
?.maxByOrNull { it.version.takeIf { it <= headers.appVersion } }
?.button ?: defaultButton
}
Отмечу, что вариант от ChatGPT не скомпилируется, так как класс Headers написан на Java и поля os и appVersion являются nullable. Ошибка в выражении:
// Type mismatch.
// Required: ApplicationVersion
// Found: ApplicationVersion?
it.version.takeIf { it <= headers.appVersion }
Из контекста этот interop не очевиден, поэтому дадим поясняющее указание