Во-первых, мне не нравится решение, которое включает создание нового объекта User
и последующий вызов checkUsername()
для него по нескольким причинам:
- Если не существует действительного пользователя сучитывая имя пользователя, у вас не должно быть объекта
User
, представляющего этого пользователя ... потому что он не существует.Это не жесткое и быстрое правило, поскольку иногда вам может понадобиться объект User
, представляющий пользователя, которого вы собираетесь создать, или что-то подобное, но здесь я нахожу это неестественным. - Это противоречит ожиданиям относительночто могут делать объекты данных.Создание
new User()
и последующее получение checkUsername()
возвращают разные значения в зависимости от того, какое имя пользователя дано этому пользователю.
Теперь я знаю, что вы в классе, и это может пойти дальше того, что вы изучаете, но пойти еще дальше:
Ни одно из решений не кажется мне очень хорошимпоскольку оба тесно связывают любой код, который использует их, с базой данных, что затрудняет его тестирование.
Общее решение этого заключается в том, чтобы обернуть код, который затруднит тестирование компонентов, использующих его, в интерфейсе,что-то вроде этого:
public interface UserService {
boolean checkUsername(String username);
...
}
Затем вы можете создать реализацию UserService
, которая взаимодействует с базой данных, и классы, которым необходимо использовать этот код, могут внедрить его реализацию в свои конструкторы:
public class UserServiceClient {
private final UserService userService;
public UserServiceClient(UserService userService) {
this.userService = userService;
}
...
}
Это принцип внедрения зависимости.Помимо того, что вы просто делаете свой код более гибким, он позволяет вам предоставлять поддельные реализации UserService
для тестирования.Если вы хотите проверить, что происходит в определенном классе, когда checkUsername
возвращает true
, и что происходит, когда он возвращает false
, вы можете просто использовать поддельные реализации, которые всегда возвращают true
или всегда возвращают false
.Вам не нужно беспокоиться о настройке соединений с базой данных или о наличии нужных данных или о том, что состояние базы данных правильно сбрасывается после теста, и, что не менее важно, тест выполняется гораздо быстрее, когда не требуется выполнять работу с базой данных.коммуникация.
Другая вещь, которую вы можете захотеть сделать, которая находится где-то посередине между двумя подходами, - это иметь объект User
, который хранит данные о пользователе (но не может связываться с базой данных или чем-либо подобнымсамо по себе) и поместить такой метод в ваш UserService
:
User getUser(String username);
Этот метод вернет объект User
для пользователя с данным именем пользователя, если он существует, и null
в противном случае.Вы также можете реализовать checkUsername
как просто
return getUser(username) != null;