Мы все пытаемся использовать общие подходы и известные шаблоны для создания приложения с минимальными усилиями и максимальной отдачей. У нас есть отличные библиотеки и мощные фреймворки, которые выполняют рутинные операции за нас. Все это мы используем для того, чтобы сосредоточиться только на бизнес-логике. Однако эта погоня довольно часто приводит нас к спагетти-коду, особенно когда речь идет о реализации функции без готового решения для нее.
В этой статье я хочу поделиться с вами одним мощным инструментом, который, по моему опыту, ценят не все разработчики. Этот инструмент есть в большинстве языков программирования, и он очень часто используется во многих фреймворках — аннотации.
Вы любите спагетти?
Давайте рассмотрим пример, с которым я столкнулся пару лет назад. Мне нужно было сделать синтаксический анализ электронной таблицы Excel, чтобы поместить проанализированные данные в базу данных. Также я хотел собрать часть данных из базы данных и создать электронную таблицу.
Для реализации я использовал известную Java-библиотеку — Apache POI. API библиотеки облегчает работу, поскольку позволяет вручную создавать лист, строку, ячейку и другие элементы. Это очень хорошо, но когда необходимо генерировать различные электронные таблицы Excel, код становится абсолютно нечитаемым и неподдерживаемым. В итоге, как это обычно бывает, первая версия приложения получается просто ужасной.
Реализация состояла из класса данных, который представлял строку со всеми полями, необходимыми для синтаксического анализа. Также был парсер, в котором поля Excel анализировались ячейка за ячейкой и помещались во вновь созданный экземпляр класса данных.
Поначалу программа работала отлично и делала то, что от нее требовалось. Проблемы начались, когда пришло время вносить какие-то модификации; код не читался. Даже я, написавший этот код, не мог найти подходящего места для размещения новых строк для реализации новой необходимой мне функции.
Спасение в аннотациях
Спасли приложение от этого спагетти-кода аннотации. Чтобы избавиться от неподдерживаемого кода, мне нужно было перенести логику определения того, какой столбец следует анализировать, какой тип данных содержится в ячейке и все остальное в другое место. Для этого я создал аннотацию, в которой указал имя столбца для каждого поля класса.
В аннотации я также добавил переменную, с помощью которой можно выбирать цвет и шрифт ячейки. Тем самым код в классе синтаксического анализа был значительно сокращен. Только один обработчик динамически создавал электронную таблицу по параметрам, взятым из аннотаций. Это была победа.
Затем, чтобы внести какие-либо изменения в приложение, мне просто нужно было создать класс с аннотациями. Решение напоминало библиотеку Jackson, которая анализирует JSON с помощью аннотаций, и, я думаю, нет необходимости рассказывать, насколько удобна Jackson или аналогичные библиотеки.
По мере развития приложение получило новую аннотацию, с помощью которой в электронной таблице можно было создать ячейку с функцией внутри. Различные поля можно умножать, вычитать, использовать любые общие функции Excel. Также я добавил итоговую строку для отображения суммы по столбцу. И все это было я сделал лишь за счет незначительной модификации основного парсера и простого добавления аннотаций к классам.
@ColumnExcel(
name = "Views",
position = 4,
total = ExcelTotalFormula.SUM)
private BigDecimal variableC;
@ColumnExcelFormula(
name = "Conversion",
position = 5,
cellTypePattern = CellDataTypeFormatPattern.PERCENTAGE
)
public String variableD(int rowNumber) {
return new CellAddress(rowNumber, 4).formatAsString() + "*"
+ new CellAddress(rowNumber, 2).formatAsString();
}
@ColumnExcelTotalFormula(position = 4, cellTypePattern = CellDataTypeFormatPattern.RUR)
public static String getVariableCTotalFormula(int firstRowNum, int lastRowNum) {
return "SUM( " + new CellAddress(firstRowNum, 4).formatAsString() + ":"
+ new CellAddress(lastRowNum, 4).formatAsString() + ")";
}
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ