Какое соглашение об именах вы используете для сервисного уровня в приложении Spring MVC?

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

public interface UserAccountManager{
   public void registerUser(UserAccount newUserAccount);
   public void resetPassword(UserAccount userAccount);
...
}

А потом класс реализации...

Что меня здесь беспокоит, так это то, что UserAccountManager - хорошее имя для класса реализации, поэтому я вынужден дать ему глупое имя, например SimpleUserAccountManager или UserAccountDbManager. Какие соглашения вы использовали до сих пор? Это хорошая идея, чтобы поместить классы реализации в другой пакет и дать им те же имена, что и интерфейсы? Кроме того, что вы думаете об использовании имен, оканчивающихся на Менеджер, на имена, оканчивающиеся на Сервис?

9 ответов

Решение

Сам Spring дает интерфейсам общие имена, а затем называет классы на основе деталей реализации. Это один пример, который приходит на ум:

interface: Controller
abstract classes: AbstractController, AbstractCommandController, 
                  SimpleFormController, MultiActionController

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

Что я считаю глупым, так это общее соглашение о добавлении суффикса "Impl" в классы реализации:

my/package/UserAccountManager
my/package/impl/UserAccountManagerImpl

Некоторые люди предпочитают это все же.

Вот что мы используем:

  • XxxDAO (объект доступа к данным) - отвечает за непосредственное взаимодействие с EntityManager, JDBC DataSource, файловой системой и т. Д. Должен содержать только логику постоянства, такую ​​как SQL или JPA-QL, но не (или как можно меньше) бизнес-логики. Доступ должен осуществляться только от Менеджеров.
  • XxxManager - Управляет объектами на бизнес-уровне, обычно выполняет операции CRUD, но добавляет необходимую бизнес-логику.
  • XxxService - уровень, на котором находится бизнес-логика. Должны "говорить" в простых объектах - Струнах, Интсах и т. Д. - как можно больше.
  • XxxController - уровень взаимодействия с пользовательским интерфейсом. Следует говорить только с Сервисами.
  • XxxUtilities / XxxUtils - вспомогательные методы без сохранения состояния, не должны зависеть от какой-либо службы в системе. Если вам нужна такая зависимость, либо преобразуйте служебный класс в службу, либо добавьте результат службы в качестве параметра.

Для реализации мы добавляем Суффикс Impl (XxxServiceImpl), чтобы отличить его от интерфейса, и если есть несколько реализаций или мы хотим добавить дополнительную информацию, мы добавляем его в качестве префикса (JdbcXxxDaoImpl, GoogleMapsGeocodingServiceImpl и т. Д.). Имена классов становятся немного длиннее, но они очень наглядны и самодокументированы.

В приведенном вами примере я бы использовал имена реализации, которые отражают, как класс выполняет операции, такие как HibernateUserAccountManager или JPAUserAccountManager, JDBCUserAccountManager и т. Д., Или, возможно, просто UserAccountManagerDAO.

Очевидно, что само по себе не важно, заканчиваются ли имена классов на Manager или Service. Вообще говоря, важно то, что имена точно передают то, что моделируется. И в этом суть проблемы: "Сервисы" или "Менеджеры" не являются объектами реального мира, которые мы пытаемся моделировать в наших программных объектах. Скорее, это места, где мы собираем кучу методов, которые делают вещи, которые просто не вписываются в обязанности каких-либо объектов, которые нам нужны / которые мы хотим моделировать.

Лично я предпочитаю "обслуживание", но только потому, что "менеджер" выглядит как нечто, что можно на самом деле смоделировать, то есть могут быть реальные менеджеры, которые представляют наши объекты "-manager". Но дело чисто академическое, и я сразу признаю, что это не имеет никакого практического значения.

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

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

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

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

Вы также можете назвать интерфейс IUserAccountManager (это соглашение используется, например, в Eclipse RCP), а затем использовать UserAccountManager для реализации по умолчанию.

Для меня класс обслуживания - это реализация варианта использования, поэтому я называю его в зависимости от того, от какого пользователя действует служба. Поэтому, если у меня есть приложение с разными ролями, например, клиенты, люди, выполняющие заказы, люди, занимающиеся вводом данных, и администраторы, то, скорее всего, у меня будет CustomerService, OrderFulfillmentService, DataEntryService и AdminService. Я думаю, что присвоение названия сервису в соответствии с типом данных, извлекаемых или изменяемых, является анти-паттерном. Поэтому, предполагая, что манипулирование UserAccount будет доменом администратора, я бы назвал его "AdminService".

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

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

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

Я также согласен избегать суффикса Impl для реализаций и избегать суффикса I для интерфейсов. В качестве примера, название интерфейса "Контроллер" и название реализации "SimpleController" или "UserController" звучат для меня лучше.

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

Некоторые рекомендации по REST, которые мы использовали: http://soaprobe.blogspot.co.uk/2012/10/soa-rest-service-naming-guideline.html (мой блог)

Другие вопросы по тегам