Я в анти-паттерне, и я хочу выбраться

Я разрабатываю веб-приложение java, используя jsp / jquery / ejb / jboss.

У меня есть веб-форма, которая позволяет пользователю выбирать любую комбинацию из 100 полей (все из разных несвязанных таблиц / объектов) из базы данных. Эти поля затем выводятся через сервлет Java в электронную таблицу Excel. Выполняется хранимая процедура, которая всегда возвращает все 100 полей.

Веб-форма устанавливает 100 логических значений в объекте передачи (TO), чтобы определить, следует ли затем отображать данные. Затем на этот ТЗ делается ссылка для создания строки заголовка электронной таблицы, а также для каждой строки из базы данных, которая повторяется.

Все работает нормально, но кажется неправильным. Я не могу придумать жизнеспособный способ, который не ссылался бы на 100 логических значений (N + 1 раз), чтобы определить, следует ли включать поле в выводимую электронную таблицу. Когда я говорю «жизнеспособный», я имею в виду, например, что я не хочу переписывать хранимую процедуру или создавать 100 различных хранимых процедур.


person NimChimpsky    schedule 11.08.2010    source источник
comment
Не понимаю, чем вы недовольны. Размер TO или способ его использования для генерации запроса?   -  person Andy Johnson    schedule 11.08.2010
comment
Либо оба. То, как я это делаю, просто не казалось особенно элегантным или эффективным решением.   -  person NimChimpsky    schedule 11.08.2010


Ответы (4)


Наше решение было в аналогичных ситуациях для создания динамического объекта передачи. По сути, это был Map вместо POJO, имеющий несколько геттеров и сеттеров.

Коды, которые заполняют и читают этот объект передачи, были простыми итерациями.

person pcjuzer    schedule 11.08.2010
comment
Интересный. Итак, в этом примере, что было бы ключом / значением? Изменить - на самом деле, довольно очевидно. Идентификатор поля / имя столбца в качестве ключа, а значение будет данными, возвращенными из базы данных. - person NimChimpsky; 11.08.2010
comment
+1 Думаю, это хорошее решение. Но вместо того, чтобы иметь 100 геттеров / сеттеров для заполнения карты, я бы имел перечисление имен полей в TO и Dictionary ‹FieldEnum, bool› с двумя функциями bool GetField (FieldEnum e) и void SetField (FieldEnum e, bool б). - person Andy Johnson; 11.08.2010
comment
+1 Выбор карты вместо обычного TO / Bean часто является хорошим способом, когда у вас есть много свойств, в которых нет логического / семантического смысла разделять их на разные объекты. Я также иногда использую это для параметров метода, когда у меня много параметров, а некоторые из них необязательны. Использование перечисления для имен полей также является хорошим выбором. Часто также полезно обернуть карту методом, который позволяет вам предоставить значение по умолчанию, которое возвращается, когда ключ не установлен, поэтому вам не нужно проверять «null» непосредственно в вашем коде. - person Johannes Wachter; 11.08.2010
comment
В любом случае, я бы не стал помещать перечисление в само ТО. Я бы лучше поместил их в какой-нибудь служебный интерфейс. Таким образом, TO может стать очень общим классом, и когда вы добавляете новые элементы в службу, TO изменять не нужно. - person pcjuzer; 13.08.2010

Вместо использования хранимой процедуры для этого не могли бы вы динамически создать выбранную строку SQL в своем приложении, а затем выполнить этот оператор SQL. Таким образом, вам нужно ссылаться на логические значения только один раз, и вы возвращаете только те столбцы, которые вам нужны.

person Adrian    schedule 11.08.2010

Вы можете исключить ручное перечисление полей следующим образом:

  • при загрузке формы для каждого из доступных полей электронной таблицы вы выводите логический элемент управления. Вероятно, лучше всего добавить какой-то префикс, чтобы у вас не было конфликтов с другими полями, которые существуют в форме.

  • при отправке формы вы отображаете все включенные поля с префиксом.

person Steve B.    schedule 11.08.2010

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

static final FIELD1 = 1;
static final FIELD2 = 2;
static final FIELD3 = 4;
static final FIELD4 = 8;
static final FIELD5 = 16;
etc

Каждое поле формы будет иметь значение своего битового значения, если оно выбрано, или 0, если оно не выбрано. При отправке формы просуммируйте поля и отправьте значение. Итак, если были проверены поля FIELD1 и FIELD3, вы должны отправить значение 5 (00101 в двоичном формате).

Затем вы применяете простую битовую маску для каждого поля, чтобы определить, какие из них были выбраны (есть ли лучший способ, чем поле за полем?):

boolean field1Selected = sum & FIELD1;
boolean field2Selected = sum & FIELD2;
etc

Недостатки: 100 полей - это действительно большое число! Возможно, вам придется использовать 2-битные массивы. Я также не уверен, что это действительно упрощает вашу проблему, но, возможно, это так.

person nojo    schedule 11.08.2010
comment
Заменяет ли это 100 полей типа bool на 100 битовых масок? Верно, что это уменьшает TO меньше в памяти, но это проблема, которую OP пытается решить? - person Andy Johnson; 11.08.2010
comment
Произведенное число для хранения битовой маски только вписывается в границы значения java max для целого числа. Я думаю. TO немного меньше в памяти, но это единственное преимущество, которое я вижу. Первоначальный вопрос действительно о том, чтобы найти лучший способ, чем поле за полем. - person NimChimpsky; 11.08.2010