Java - 这是一个糟糕的设计模式吗?

时间:2010-04-01 14:14:23

标签: java design-patterns architecture

在我们的应用程序中,我看到过这样的代码:

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编写验证器。

有没有其他人看到这种设计模式有什么问题,或者我只是作为开发人员挑剔?

沃尔特

5 个答案:

答案 0 :(得分:3)

在返回用户对象时,您要让UserSearchCommand在现有数据上写入新信息,这可能不是人们想要允许的,因为搜索应该允许读取数据。此外,您所做的是让使用UserSearchCommand的人必须知道User类中的方法/属性/成员,这在第一个实现中并非如此。

答案 1 :(得分:3)

使用接口的第三个选项怎么样?

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);
  }
}

现在,您可以通过接口进行抽象,并防止修改用户对象。

答案 2 :(得分:2)

Law of Demeter建议第一个例子。

答案 3 :(得分:0)

当Sjoerd和JB生成有效点时,根据你对SearchCommand的使用,我会为第二个例子做出以下参数。如果您在第一个示例中定义的操作不影响UserSearchCommand的行为,那么通过定义getFirstName()等,您实际上只是复制代码,这可能导致可维护性问题,例如,如果稍后您添加一个中间用户类的名称?然后,您不仅需要将其添加到用户,还需要将其添加到UserSearchCommand中的访问者。如果对用户做某事会修改搜索的行为,那么这可能是让调用者通过搜索命令访问用户的有效参数,但这也可以通过PropertyListeners等机制实现。

正如你所指出的那样,第一个例子是将信息混合在一起,对我来说,从OOP的角度来看似乎是违反直觉的。如果要限制对用户访问某些属性,则可能需要更改访问修饰符,或创建公开您认为安全的接口以及公开适当的包/受保护属性的实现类。除非您的UserSearchCommand是用词不当,否则我希望它执行涉及搜索用户的操作,然后将这些用户作为一个单元(而不是用户的单个属性)提供。这是一个搜索命令应该执行与搜索相关的操作,用户应该包含有关用户的信息。

当然这是一个风格问题,但我会投票给你的第二个例子。

答案 4 :(得分:0)

我同意你的看法。我已经看到了同样的技术并且没有看到重点:它只是意味着复制了一大堆代码,为了什么?