Разделение служб → Бизнес-объекты?
Я считаю, что я структурирую свои проекты, как это делают многие люди. У вас есть уровень данных (DAO), уровень обслуживания (службы) и уровень представления (Spring MVC, Wicket,...).
Обычно услуга начинается довольно просто и "коротко".
Постепенно, однако, служба должна поддерживать все больше и больше случаев использования, пока через какое-то время она не станет одним огромным классом со многими линиями и методами, которую трудно читать и поддерживать. В то время вы можете либо решить придерживаться его, либо начать рефакторинг, который является громоздкой и "опасной" работой, которая может занять много работы.
Я ищу решение, как предотвратить необходимость в любом будущем рефакторинге.
Один из подходов может заключаться в разделении ваших услуг в нескольких под-сервисах и создании вашего оригинального сервиса фасад службы. Так, например, вместо большого UserService у вас может быть UserServiceFacade, который делегирует вызовы в PasswordService, RegistrationService,....
Это не плохое решение, я думаю, но я не слишком увлечен этим, потому что:
- сложно заранее определить, в каких подсервисах расколоть работу; если вы пропустили ошибку, вам все равно может потребоваться повторный рефакторинг или иметь службу только с одним методом.
- повторное использование Business Logic может быть более сложным, если, например, для доступа к службам PasswordService и RegistrationService требуется общая функциональность
Другим решением может быть использование бизнес-объектов, которые (в моем понимании) также можно увидеть подсервисы, но затем по одному на конкретный UseCase, поэтому у вас может быть BO как CreateUserBO, CheckPasswordBO, DeleteUserBO,....
Я немного увлечен этим подходом, потому что, по моему мнению, он предлагает несколько преимуществ:
- сам BO очень читаем и только с ним требует контракт; все остальные могут быть делегированы другим BO, один BO будет коротким и до точки
- Простота повторного использования.
- Легче изменить/переключить реализацию определенного UseCase: просто введите другую реализацию с помощью Spring
- Легче тестировать: нужно только протестировать конкретную UseCase, делегировать ее в другую BO можно издеваться
- Сотрудничество: меньше конфликтов, если несколько разработчиков работают на разных BO тогда, когда они работают на одной и той же службе
Я также вижу некоторые возможные недостатки:
- немного дополнительной работы (по крайней мере, в терминах сортировки)
- Значительно больше классов, которые могут снизить читаемость вашего проекта?
- еще один уровень абстракции: требуется дополнительный шаг для поиска фактической реализации UseCase
Вопрос или, вернее, вопросы (извините):
- Являются ли Business Objects идеальным решением для этой проблемы?
- Согласны ли вы с преимуществами/недостатками BO, которые я перечисляю выше, и/или вы видите другие?
- Есть ли другие (хорошие) решения для предотвращения мега-сервисов, разрушающих ваш день?
Ответы
Ответ 1
Я бы рекомендовал вам ознакомиться с этой статьей в Domain Driven Design, если ваше приложение является чем-то серьезным, чем назначение в колледже. Основная посылка - это структура вокруг ваших объектов и сильная модель домена. Различия между службами, которые обеспечивают связанные с инфраструктурой вещи (например, отправка электронной почты, сохраняющиеся данные) и услуги, которые фактически выполняют те вещи, которые являются вашими основными бизнес-требованиями.
Я также предложил бы исследовать Spring Roo - который привносит некоторые революционные вещи в том, что касается разметки ваших слоев, необходимо использовать уровни DAO и т.д.
Надеюсь, что это поможет.
Ответ 2
С первым подходом вы упоминаете, вместо того, чтобы создавать "фасад", почему бы просто не расширить этот сервис? В такой ситуации вы сможете повторно использовать код из класса super/original.
Я думаю, что если вы упорядочиваете свою структуру пакета читабельным образом, то, имея в своем распоряжении несколько меньших классов, безусловно, предпочтительнее в любом случае иметь большие классы, которые обладают большой функциональностью и как таковые более подвержены риску изменений.
В конце концов, я думаю, что оба подхода довольно схожи, либо вы можете получить высокую степень повторного использования кода, и если вам нужно обновить что-то структурно, то его довольно легко сделать глобальное изменение (относительно говорящее)), а также легко сделать конкретные изменения в реализации.
Ответ 3
Что я лично делаю, так это то, что я всегда использую фасад для своих услуг. Логика находится во внутренних классах службы, но я предоставляю интерфейс, который может вызвать клиент этой службы.
Я стараюсь избегать с самого начала, чтобы поставить какую-либо логику в фасад. Это всего лишь код плиты котла, который перенаправляется на правильную логику кода.
Таким образом, даже если ваш сервис имеет множество функций, фасад вполне поддается поддержке.
Но если вы контролируете всю исходную базу, вы не должны стесняться рефакторировать и делиться, если у вас будет слишком много функций в одной службе. Даже если вы используете несколько классов для выполнения задания, четкое разделение вашего обслуживания будет лучше в долгосрочной перспективе.