tags:

views:

39

answers:

2

I have a dilemma and I'm not sure about the best way to start solving it.

I'm working with an old code base at work. Some of the domain objects (and db tables behind them) don't make a lot of sense. eg, deleted is stored as a long, age is stored as a String, etc. Which I've been able to work with fine. In the view I can say if (deleted == 1).... But there are some specific business logic that is leading to a maintenance problem by having it in the view. Here's one example:

String title = null;
if (obj.getTitle != null) {
    title = obj.getTitle();
} else {
    title = obj.getName() + " - " + obj.getCategory();
}

I would really like to have a "view bean" where this business logic and legit oddities are ironed out and stored so that I can use it in multiple views but then change it in one place. If I had a Product POJO and then my ProductViewBean, as an example, I would do something like:

productViewBean.setDeleted( product.getDeleted() == 1 );
productViewBean.setTitle( product.getTitle() != null ? product.getTitle() : product.getName() + " - " + product.getCategory() );

My question is, where should I do this? Should I have a manager (with appropriate daos injected into it) that is injected into my controller and returns my "view bean"? Or am I going about this all wrong and could there be better approach?

Thanks in advance

(Note: I understand that the underlying structure is the real problem but it is beyond my jurisdiction to change at this point. Too many projects use these domain objects. And even if I did clean up the db/domain objects (so that deleted was a boolean etc) I'm still left with unavoidable business logic (if !title then 'build title from other components') that doesn't belong in the data layer and that I would like to encapsulate in one place so that neither the controller or view have to worry about it and it can be used across multiple controllers/views. I happen to be at a point where I can write something that is efficient and maintainable and could even create a good layer to ease cleanup of these domain objects in the future.)

+1  A: 

I'll bet you can sort all that out in the Spring data binding and validation API.

I'd also say that you should have a service tier that's distinct from the web controller layer. Inject the services into the web tier and let them do all the work. They worry about units of work, transactions, and DAO objects.

duffymo
A: 

I would try an Adapter delegating to the domain object like the following. The controller and view use this one. If the ProductViewBean is in the same package as the manager, the manager only can use the getDelegate() method to pass it to the dao.

public class ProductViewBean {
  private final Product delegate;

  public ProductViewBean(Product delegate) {
    this.delegate = delegate;
  }

  Product getDelegate() {
    return delegate;
  }

  public String getTitle() {
    if (delegate.getTitle == null) {
      return delegate.getName() + " - " + delegate.getCategory();
    }
    return delegate.getTitle();
  }

  public void setTitle(String title) {
    delegate.setTitle(title);
  }

  public boolean isDeleted() {
    return delegate.getDeleted() == 1L;
  }

  public void setDeleted(boolean deleted) {
    delegate.setDeleted(deleted ? 1L : 0L);
  }

  ...
}

So you can make the API you like.

Arne Burmeister