2008-10-16 5 views
5

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

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

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

ответ

9

Мой способ борьбы с этим было бы:

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

Там определенно больше - Извини, я бегу из времени здесь ...

1

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

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

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

Оттуда вы просто должны занять несколько недель, и растереть его

1

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

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

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

enum Operation { 
    ADD, DELETE; 
} 

... 

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

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

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

1

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

+0

Я собираюсь сказать pshah. Автор утверждает, что методы чудовищно длинны и имеют высокую циклическую сложность. Такой код часто является кошмаром для модульного теста. – JonMR 2010-02-22 21:57:01

2

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

Original Hierarchy:  New Hierarchy: 

    Action     Action 
     |      | 
     |      BaseA 
    (old)ClassA     | 
         +--------+----------+ 
         |  |   | 
        ClassB (new)ClassA ClassC 
+0

Прочтите мой ответ выше для размышлений о наличии иерархии действий. Я думаю, что во многих местах, которые делают это, у них, вероятно, слишком много бизнес-логики в их веб-слое. – bpapa 2008-10-17 22:54:36

5

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

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

Это только мой личный опыт.

2
  1. Go один метод в то время
  2. Запись некоторых тестовых случаев вы можете играть позже. Example here (убедитесь, что вы ударили столько же путей через код, как вы можете, то есть все жесты пользователя на странице, которые вызывают это действие)
  3. refactor метод, чтобы уменьшить его сложность, создав более мелкие методы, которые делают меньше вещей.
  4. повторно запустить тесты, как вы это делаете

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

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

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

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

 Смежные вопросы

  • Нет связанных вопросов^_^