Where should I put custom attributes for my objects? In the POJO/POCO class or the service layer?

StackOverflow https://stackoverflow.com/questions/12390991

Вопрос

This question was for a Java project I'm working on but could apply to C# too.

Anyway, so I have an MVC web project. In it, I have three "layers" for my data.

com.example.model.dao
com.example.model.entities
com.example.model.service

So dao is my low-level database classes. Things like Hibernate wrappers, etc. entities are my POJO's and service is my business logic.

Now let's say one of those POJO's is User. In User, it maps to a database table called users. This table (and POJO) has two fields, firstname and lastname. OK, so I want to put a method somewhere called getFullName that simply concatenates the first and last name.

So where should this method go? I thought about putting it in the POJO itself. But since sometimes we use tools to generate POJO's from a database, custom logic there could be overwritten. And is this a business process anyway?

Should I put it in my service implementation?

Thanks for your suggestions.

Это было полезно?

Решение

You should implement custom business logic in the business layer. In this case it should be in your service layer as you are generating your POJOs.

Другие советы

in c# I would use a partial class (which resolves "generated class" problems : of course, your generated POCOs would need to be partial)

public partial class User {
   public string GetFullName() {
     return string.Format("{0} {1}", FirstName, LastName);
   }
}

Solution which wouldn't work in Java... as partial classes don't exist !

So the "most appropriate" solution wouldn't probably be the same for the 2 languages.

I normally put that type of methods in the entity itself, but since you say it could be overwritten, you could use a helper class for the entity.

class UserHelper {
  String getFullName() {
    ...
  } 
  ... more methods
}

I don't see getting a person's full name as a business process.

As many of the developers around here, Im very strict with Design Patterns, Best Practices, and Standards, but ...

...there is always an exception to rules, or to be more exact to guidelines.

Developers usually put that kind of functions on the logic layer, but, in some cases, its OK to add it in the Plain Old (Java / C# / ...) Objects.

Pseudocode:

class DataAccessLayerPerson
{
  public FirstName
  {
    get; set;
  }

  public MiddleName
  {
    get; set;
  }

  public LastName
  {
    get; set;
  }

  public getFullName()
  {
     return FirstName + MiddleName + LastName;
  }
}

class BusinessLogicLayerPerson
{
  public FirstName
  {
    get; set;
  }

  public MiddleName
  {
    get; set;
  }

  public LastName
  {
    get; set;
  }

  public FullName
  {
    get; set;
  }
}

A similar common case, is when a table has a field conceptually used as boolean, but, programatically used as char(1) storing 'f' or 't', or as integer or as bit, and I have to use them in programming as boolean.

So, I use some logic in the data access layer, and read and write to those fields as booleans.

Cheers.

We had the same problem in our project, so we did as this:

@MappedSuperclass
public class UserDTO {
   // this is the class which can be regenerated by code generator, and only contains database fields
}

@Entity
public class User extends UserDTO {
   // this is the class containing more business methods, methods do things that are not part of the database columns
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top