In our application, I have seen code written like this:
User.java (User entity)
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());}
}
Now, from my experience, this pattern or anti-pattern looks bad to me. For one, we’re mixing several concerns together. While they’re all user-related, it deviates from typical POJO design. If we’re going to go this route, then shouldn’t we do this instead?
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);}
}
Simply return the user object, and then we can call whatever methods on it as we wish?
Since this is quite different from typical bean development, JSR 303, bean validation doesn’t work for this model and we have to write validators for every bean.
Does anyone else see anything wrong with this design pattern or am I just being picky as a developer?
Walter
While Sjoerd and JB make valid points, depending on your use of the SearchCommand I would make the following argument for the second example. If the operations you are defining in the first example do not effect the behavior of the UserSearchCommand, then by defining getFirstName(), etc you are really just duplicating code, which can lead to maintainability issues, for example what if later you add a middle name to the user class? Then you not only need to add it to user but also an accessor in UserSearchCommand. If doing something to the user would modify the behavior of the search then that could be a valid argument to have the caller access the user through the search command, but this could also be achieved via a mechanism such as PropertyListeners.
As you pointed out the first example is mixing information together and, to me, seems counter-intuitive from and OOP perspective. If it is a matter of restricting access to some properties to the User then it may be a matter of changing the access modifiers, or creating an interface that exposes what you deem safe and an implementation class that exposes appropriate package/protected properties. Unless your UserSearchCommand is a misnomer I would expect it to perform operations involving searching for users and then make those user’s available as a unit (not individual properties of a user). That is a search command should perform operations related to a search and a user should contain information about the user.
Of course this is a stylistic question, but I would give my vote to your second example.