Вопрос

Я унаследовал это гигантское устаревшее веб-приложение Java, используя Struts 1.2.4.У меня конкретный вопрос относительно действий.На большинстве страниц есть ровно одно действие, а методыprocessExecute() — ужасные монстры (очень длинные и с множеством вложенных операторов if, основанных на параметрах запроса).

Учитывая, что действия представляют собой реализацию шаблона команд, я думаю разделить эти действия на одно действие для каждого жеста пользователя.Однако это будет большой рефакторинг, и мне интересно:

  1. Это правильное направление?
  2. Могу ли я сделать какой-то промежуточный шаг, шаблон, который поможет разобраться с беспорядком внутри монолитных действий?Может быть, другой шаблон команды внутри действия?
Это было полезно?

Решение

Мой способ справиться с этим:

  • не делай «все сразу»
  • всякий раз, когда вы что-то меняете, оставляйте это лучше, чем вы это нашли
    • замена условных операторов отдельными реализациями действий — это один шаг.
    • Еще лучше:Отделите свои реализации от классов действий, чтобы вы могли использовать их при изменении фреймворков.
    • Сохраните новую реализацию команды абсолютно без ссылок на Struts, используйте новые действия в качестве оболочки для этих реализаций.
    • Возможно, вам потребуется предоставить интерфейсы для ваших форм Struts ActionForms, чтобы передавать их без копирования всех данных.С другой стороны, вы можете захотеть передать другие объекты, кроме ActionForms, которые обычно представляют собой набор строк (см. другой вопрос о Struts 1.2 Формы действий)
  • начать мигрировать детали на более новые и лучшие технологии.Struts 1.2 был великолепен, когда вышел, но это определенно не то, что вы хотите поддерживать вечно.Сейчас существует несколько поколений лучших фреймворков.

Определенно есть еще кое-что. Извините, у меня мало времени...

Другие советы

На мой взгляд, в Struts Actions вообще не должно быть много кода.Им следует просто напрямую взаимодействовать с запросом и ответом — взять некоторые данные из формы или параметра запроса, передать эту информацию на уровень обслуживания, а затем поместить некоторые данные в объект Response или, возможно, сохранить некоторые данные в сеансе пользователя.

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

Это всего лишь мой личный опыт.

Я уже имел дело с подобными вещами раньше.Хороший первый шаг — вставить еще один базовый класс в цепочку наследования между Action и одним из исходных чудовищных классов действий (назовем его ClassA).Особенно, если у вас нет времени сделать все сразу.Затем вы можете начать выделять части функциональности в более мелкие параллельные классы действий (ClassB, ClassC).Все, что есть общего между исходным классом ClassA и новыми рефакторингованными классами, может быть перенесено в новый базовый класс.Итак, иерархия теперь выглядит так:

Original Hierarchy:      New Hierarchy:

     Action                   Action
       |                        |
       |                      BaseA
  (old)ClassA                   |
                       +--------+----------+
                       |        |          |
                   ClassB (new)ClassA   ClassC
  1. Используйте один метод за раз
  2. Запишите несколько тестовых случаев, которые вы сможете воспроизвести позже. Пример здесь (обязательно пройдите как можно больше путей в коде, т.е.все жесты пользователя на странице, вызывающие это действие)
  3. выполните рефакторинг метода, чтобы уменьшить его сложность, создав меньшие по размеру методы, выполняющие меньшие задачи.
  4. Повторно запустите тесты, пока вы это делаете.

На этом этапе вы выполнили рефакторинг версии большого раздражающего метода. Сейчас вы действительно можете начать создавать конкретные действия.

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

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

Это невесело, но если вы какое-то время будете работать над базой кода, это сэкономит вам время и избавит от головной боли.

Сложная проблема, но типичная для ранней разработки веб-приложений.

Прежде всего, вам нужно начать думать о том, какая логика представляет собой бизнес-поведение, какая логика представляет собой «поток» (т. е.что видит пользователь), и какая логика получает контент для того, что он видит.

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

После этого вам просто нужно потратить несколько недель и отшлифовать это.

Один длинный метод никогда не будет хорошим, если только это не один оператор переключения, где случаи очень короткие (анализ токена или что-то в этом роде).

Вы могли бы хотя бы реорганизовать длинный метод на более мелкие методы с описательными именами.

Если это вообще возможно, вы могли бы начать свой метод с определения того, что он должен делать, изучив форму, а затем, если/иначе, перейти к различным вариантам.Однако нет вложенных if, они делают код нечитаемым.Только

enum Operation {
  ADD, DELETE;
}

...

Operation operation = determineOperation(form);
if (operation == Operation.DELETE) { 
  doDelete(form); 
} else if (operation == Operation.ADD) {
  doAdd(form);
}

Если вы сможете зайти так далеко, ваша логика будет красивой и чистой, и вы сможете делать любой рефакторинг, какой захотите.

Самое сложное — прояснить свою логику, и это можно сделать поэтапно.Не выбирайте шаблон, пока не поймете, в чем именно заключается ваша проблема.

Если вы планируете провести рефакторинг кода, вам следует сначала написать тесты для существующего кода, чтобы вы могли быть уверены, что не изменили его функциональность после начала рефакторинга.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top