Помогите Java OO метод статической уязвимости! - PullRequest
1 голос
/ 15 декабря 2010

Недавно я сделал метод в классе User, который выглядит следующим образом:

  public static boolean checkUN(String username) {
  boolean check = false;
  ResultSet rs;
  String dbQuery;
  SQLController db = new SQLController();
  db.setUp();
  dbQuery = "SELECT * FROM User WHERE User_name ='" + username + "'";
  try {
   db.setUp();
   rs = db.readRequest(dbQuery);
   if (rs.next()) {
    check = true;
   }
  } catch (Exception e) {
   e.printStackTrace();
  }
  db.terminate();
  return check;
 }

Я предполагал, что это будет проверка проверки, прежде чем пользователь сможет перейти к следующему шагу регистрации.

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

Какой способ более эффективен?

user.checkUsername(jTextUN.getText());

и способ экземпляра (при условии, что я изменил метод, удалив статический и входной параметр);

User user = new User();
user.setUsername(jTextUN.getText());
user.checkUsername();

Приветствия!

Ответы [ 3 ]

2 голосов
/ 15 декабря 2010

Я бы, вероятно, создал какой-то класс UserValidator и создал бы экземпляр этого для вашего метода.

2 голосов
/ 15 декабря 2010

Во-первых, мне не нравится решение, которое включает создание нового объекта 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;
1 голос
/ 15 декабря 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...