Question

I am building an MVC application and the 'M' layer consists of a Service Layer, Domain Model Layer, and Mapper Layer.

The logic in my Domain Model is quite complex. For example, an Organisation has many Employees. When I want to modify some aspect of the Organistion/Employee, such as their pay level, I need to consult the Organisation object, the User object, and the Employee object which connects the two. Generally I have been putting these responsibilities on the composing object (in this case, the Organisation), and that's working out fine.

One issue that I am struggling with though relates to the creation of new entities. Specifically, when there are conditions/rules governing the creation of new entities, should these live in the service layer, or the domain layer?

It seems to me that the most sure-fire option is to place the logic in the domain model layer, but then my domain objects seem 'less pure'. For example, an Employee object is an Employee object, regardless of who created it. But if my rules for creating an Employee entity depend on who the creator is, I will need to inject the creator in to the Employee object. (My rules for creating Employee objects differ depending on whether its the Organisation Administrator who creates it, or any old User).

It feels more natural to place the creation rules in the service layer however this raises two issues. Firstly, I then need to make absolutely certain that all access to the domain model is via that service layer. (This is not really a big deal.) More importantly, my business logic is now spread across two layers, and there's a much greater potential for confusion.

I suspect that I need to stop prevaricating and put the logic in the service layer. What do you think?

FYI, I'm using PHP, Zend Framework with a jQuery/javascript front end.

Was it helpful?

Solution

This answer is not PHP specific (I lack experience in object oriented in PHP).

Validation

Validation actually has very vast definition. It can be:

  • Data validation

    This type of validation usually focus on data type, data length, format, etc. Usually corresponded to database schema. This kind of validation is safe to be put at domain model and can be put at service layer.

  • Business Rule Validation

    This type of validation follows the business rules. It is usually validates some business rules such as the total amount must not below zero, age must not minus, etc. This is better to be put at service layer. Simply because an object can be in different state and has different validation, for example you may has empty title when the article is in draft state, but not when in published state.

Isnull / IsRequired Validation

Beware of isnull / isrequired validation. It can be both data validation (such as an employee must not has null ID whatever it is, etc), or business rule validation (such as an employee must has one supervisor). If it is following the business rule, you must put it in service layer because the state validation I explained before.

Which layer is responsible for object creation?

All layer can do object creation. You just need to make sure that all process are accessing the service layer first before going to data access. If a specific object has a little complex logic to create (such as a car need engine, wheel, gear, brakes, etc), than a builder pattern may meets your need.

OTHER TIPS

I think the business rules should be part of the domain layer.

As suggested by ZeissS, a factory seems appropriate in the domain layer. Or instead of a factory, you could have the validation methods on the Employee class itself. The domain object creating the Employee performs it's validations and throw an exception if there is an error. This way you separate who does the validation from what is being done.

To illustrate, I am subsuming the factory into Employee class:

Organization.createEmployee( employee input fields...) {
Employee employee = new Employee();
employee.setfirstName(firstName);
employee.setLastName(firstName);

...
then 
employee.validatePosition();
employee.validatePayRate(); //throw exception if error

Similarly if User is creating employee you would do the same but the validations would pertain to user.

I do not know if this pattern fits your domain. Also, what I have shown as an example is very simplified, but the principle still holds. Hope this helps!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top