Как я могу сломать некоторые методы в слое весеннего сервиса - PullRequest
2 голосов
/ 11 января 2012

Я занимаюсь техническим обслуживанием / развитием многослойного проекта Spring 3.0. Клиент представляет собой сложное приложение RCP, вызывающее некоторые методы Spring Beans из уровня обслуживания (менеджеров) на сервере на основе RMI. У меня есть несколько огромных методов в менеджерах, некоторые из них занимают более 250 строк. Вот пример: (я опущен код для ясности)

    @Transactional(readOnly = false, propagation = Propagation.REQUIRED)
 public Declaration saveOrUpdateOrDelete(Declaration decla, List<Declaration> toDeleteList ...){

     if (decla.isNew()){

        // create from scratch and apply business rules for a creation

        manager1.compute(decla);
        dao1.save(decla);
        ...

      }else if (decla.isCopy() {

         // Copy from an other Declaration and apply business rules for a copy
         ...

       }else {

         // update Declaration
        ...
       }
     if (toDeleteList!=null){

       // Delete declarations and apply business rules for a mass delete
        ...
       }

Первые 3 ветви являются взаимоисключающими и представляют собой единицу работы. Последняя ветвь (удаление) может происходить одновременно с другими ветвями.

Не лучше ли разделить этот метод на что-то более «CRUDy» для ясности и удобства обслуживания? Я думал о разделении этого бегемота на другие методы менеджера, такие как:

public Declaration create(Declaration decla ...){...

public Declaration update(Declaration decla ...){...

public Declaration copyFrom(Declaration decla ...){...

public void delete(List<Declaration> declaList ...){...

Но мои коллеги говорят, что это передаст сложность и бизнес-правила клиенту, что я потеряю преимущество атомарности и т. Д. Кто здесь?

Ответы [ 3 ]

2 голосов
/ 11 января 2012

Решение о том, что на самом деле делает updateOrCreateOrWhatever, принимается клиентом в любом случае, так как он должен установить соответствующее поле в Declaration объекте.

Клиент с таким же успехом может просто вызвать соответствующий метод.

Таким образом, код определенно более управляем и тестируем (меньше веток, о которых нужно заботиться).

Единственным аргументом в пользу его сохранения является то, что сетевые обходы, упомянутые @Pangea. Я думаю, что это может быть обработано пользовательским классом диспетчера. ИМО, это не является частью бизнес-логики, и поэтому не должно заботиться об уровне обслуживания.

Еще одна вещь, которую необходимо учитывать, - логика транзакций. Должны ли создание / обновление и удаление происходить в одной транзакции? Могут ли оба значения decla и toDelete не быть равными нулю одновременно?

0 голосов
/ 11 января 2012

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

В чем разница написания:

public Object doIt (Object ... obj) {...}

0 голосов
/ 11 января 2012

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

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

...