Java - это плохой шаблон дизайна? - PullRequest
3 голосов
/ 01 апреля 2010

В нашем приложении я видел код, написанный так:

User.java (сущность пользователя)

public class User
{
  protected String firstName;
  protected String lastName;

 ...
   getters/setters (regular POJO)
}

UserSearchCommand
{
   protected List<User> users;
   protected int currentPage;
   protected int sortColumnIndex;
   protected SortOder sortOrder;

   // the current user we're editing, if at all
   protected User user;

   public String getFirstName()
   {return(user.getFirstName());}

   public String getLastName()
   {return(user.getLastName());}

}

Теперь, по моему опыту, этот паттерн или анти-паттерн выглядит плохо для меня. С одной стороны, мы смешиваем несколько проблем вместе. Хотя все они связаны с пользователем, он отличается от типичного дизайна POJO. Если мы собираемся пойти по этому пути, то не должны ли мы сделать это вместо этого?

UserSearchCommand
{
   protected List<User> users;
   protected int currentPage;
   protected int sortColumnIndex;
   protected SortOder sortOrder;

   // the current user we're editing, if at all
   protected User user;

   public User getUser()
   {return(user);}

}

Просто верните объект пользователя, и тогда мы сможем вызывать любые методы для него, как пожелаем?

Поскольку это сильно отличается от типичной разработки bean-компонента, JSR 303, проверка bean-компонента не работает для этой модели, и мы должны написать валидаторы для каждого bean-компонента.

Кто-нибудь еще видит что-то не так с этим шаблоном дизайна, или я просто придирчив как разработчик?

Walter

Ответы [ 5 ]

3 голосов
/ 01 апреля 2010

Как насчет третьего варианта использования интерфейсов?

UserSearchCommand
{
  protected List<User> users;
  protected int currentPage;
  protected int sortColumnIndex;
  protected SortOder sortOrder;

  // the current user we're editing, if at all
  protected User user;

  public I_UserNameDetails getUser()
  {
    return((I_UserNameDetails)user);
  }
}

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

3 голосов
/ 01 апреля 2010

Возвращая пользовательский объект, вы позволяете UserSearchCommand записывать новую информацию поверх существующего фрагмента данных, что может быть не тем, что вы хотите разрешить, так как поиск должен позволять читать данные. Кроме того, вы сделали так, что кто-то, использующий UserSearchCommand, должен знать методы / свойства / члены класса User, чего нет в первой реализации.

2 голосов
/ 01 апреля 2010

Закон Деметры предлагает первый пример.

0 голосов
/ 01 апреля 2010

Я согласен с вами. Я видел эту же технику и не вижу смысла: это просто означает дублирование целой пачки кода и для чего?

0 голосов
/ 01 апреля 2010

Хотя Sjoerd и JB выставляют правильные баллы, в зависимости от того, как вы используете SearchCommand, я бы привел следующий аргумент для второго примера. Если операции, которые вы определяете в первом примере, не влияют на поведение UserSearchCommand, то, определив getFirstName () и т. Д., Вы на самом деле просто дублируете код, что может привести к проблемам с удобством обслуживания, например, что если позже вы добавите середину имя для класса пользователя? Тогда вам нужно не только добавить его к пользователю, но также и метод доступа в UserSearchCommand. Если что-то для пользователя изменило бы поведение поиска, то это могло бы быть допустимым аргументом, чтобы вызывающий пользователь имел доступ к пользователю через команду поиска, но этого также можно достичь с помощью механизма, такого как PropertyListeners.

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

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

...