Where should be the business rule in the MVC standard?

17

A few weeks ago I started studying the ASP.NET MVC background, and since I came from Windows Forms, there are some things that have not been very clear yet.

In all the applications I've done so far in this pattern, I've never bothered too much about where the business rule should be concentrated. For the most part, I left the business rule of the application in the controller or created an "intermediate class" that would do this. Example:

Model client

public class Cliente
{
    public int Id { get; set; }
    public string Nome { get; set; }
}

Intermediate class

public class ClienteService
{
    private Cliente _cliente;

    public ClienteService(Cliente cliente)
    {
        _cliente = cliente;
    }

    public void AlgumaRegraDeNegocioExtremamenteComplexa()
    {
         //...
    }
}

My doubts are as follows:

  • Is this the default or the recommended one to use?
  • Is it okay to leave the entire business rule in the controller ?
  • Is there a design pattern that defines this?
asked by anonymous 19.02.2016 / 02:21

3 answers

13

It is not advisable to put the business rules into a service, that is, to create a service layer for this.

There is great disagreement whether to be placed in the MVC ( M or C ) model or controller.

As stated by the answer from @Cypsy there are two premises for using logic in the model:

  
  • Will I use this same logic in two or more places in my code?

  •   
  • The split represents some real gain in my application that   justifies the increase in complexity?

  •   

I'll add two more that are:

  • Code tests;
  • Sharing templates across systems;

To perform system tests it is normal to do unit tests directly on the model, ignoring the controller (of course, there are unit tests in the controller as well, but this is not the issue here). With that being easier to test.
And if your idea is to share the code with other applications, or put a REST together, who knows, you would have to replicate that data in the controller.

But then should I make logic in the model?

There will be people defending this more than the family. But my answer is "it depends". It all depends on what you want to do.

A simple example is the DataAnnotations . , which are placed in the Model. And they are business rules.

There are cases of people using Repository Pattern to make business rules, which can not measure how wrong it is, but there are cases.

Microsoft Blog has a very good article on the "Best Practices" for using Asp.NET MVC. It's a bit old, but a lot of things apply today.

But you spoke so well of validation in the Model, should I do it there then?

I did not speak well, I pointed out facts that are used.

We should keep in mind that "Business Logic" is a broad term. There are model logics and application logics.

The controller should have the logics of data entry and what it will perform.

Let's look at Microsoft's MusicStore project.

If we look at the controller ManageController we will see that it has checks that are considered business logic, just as Identity has logics that are placed in IdentityConfig.cs .

Your application may have deferential business rules at the time of access, limit of requests, among others. Are these business rules, or are not they? These are things the Model does not need to know, do not you agree?

Completing

If your rule belongs specifically to the domain, put it in the domain, but in a way that controller understands, so you can use what Asp.NET MVC gives you and give you a quick response. DataAnnotations are great for this.
If your rule belongs to the application, do not even think about the domain, it has nothing to do with it. And validations involving data conferencing between Models must be done in Controller or through static classes (Helpers), such as #

    

19.02.2016 / 14:39
12

Where should the business rule stay in the MVC standard?

  

If there really is business logic, and especially if it is complex, it should stay in Model .

The concern that the creation of the MVC pattern (there in the 1970s) tried to solve is the separation between presentation and business logic, and the controller is mostly coupled with the presentation .

See this Fowler drawing for MVC :

NoticethatViewknowstheController,whichalsoknowsView;andnoticethatModeldoesnotknowanyone.

Inhisbook Patterns of Enterprise Application Architecture , Fowler says:

  

"The separation between presentation and model is one of the most fundamental heuristics of good software design."

In this same book, he mentions that the separation between Controller and View may not be so obvious in many designs , and that this is not a problem,

And they are even confused: note how the Controller really needs to know View, he knows the presentation rules (he is also the one who defines these rules).

This intimacy between Controller and View is already an indication that the Controller is not good company for business logic (tell me who you walk with and I'll tell you who you are) if you really want to separate these concepts.

But what, after all, is "logic" or "rule" of business?

StackOverflow needs to show the answers with the most votes first. Is this a business rule? Certainly it is, this is a core principle of the tool.

StackOverflow can not support an untitled question. This is also a business rule.

So these rules need to be in the Model? They do not need and probably are not. These are very simple business rules that can be resolved in the presentation.

OS, such an important tool with so many users, may not even have a domain layer concentrating its business rules with high abstraction. It is possible that Models here are just DTOs representing the data in the database.

The SO is probably an example of a system that is classified as low-complexity business rules, where abstraction of the domain in a layer may be unnecessary and even harmful.

Most of the projects I've attended to date, however, had complex enough business rules and a need for reuse that warranted a more elaborate design approach. But with absolute certainty not all systems justify such an approach! I will not talk about "majority" in general because I do not have statistical data. I can only speak from my own context.

If you decide, my child: the rules may or may not stay in the Controller?

If the system has simple rules, basically rules of presentation.

Should not have complex rules, a complex domain, and high need for reuse (rules need to be available for more than one type of consumer - such as end user, service fronts, other system services , integrations, code bases of other systems, etc.).

I'll leave the answer with Fowler (removed from the book already mentioned):

  

"The value of MVC lies in its two separations. Of these, the separation between presentation and model is one of the most important principles of software design, and the only time you should not follow it is in very simple systems where the model has no real behavior in it.

     

As soon as you have some non-visual logic, you should apply the separation.

     

Unfortunately, a lot of UI frameworks make this separation difficult, and those that do not become almost always taught without separation.

     

The separation between view and controller is less important so I would only recommend doing it when it is really useful.

    
19.02.2016 / 20:07
10
  

Is this the default or recommendable?

Recommended is always what is simpler or faster. If separation is necessary for some reason, go through the separation path. Personally speaking, I rarely do this separation of business rules in middle tiers because there is no reason in my systems for this to happen.

A good reason for the split in the case of ASP.NET MVC5 is when you have to implement a REST (Web API) layer and an MVC layer with the same rules. Because the Controllers of each architecture are very different from each other, the separation is justified. Otherwise, there is no need for separation.

  

Is it okay to leave the entire business rule in the controller?

In most cases, yes. There are two general assumptions that can be used to decide this:

  • Will I use this same logic in two or more places in my code?
  • Does the separation represent any real gains in my application that justify increasing complexity?

In the vast majority of cases, the answer is "no", but notice that there is a movement of people who go "yes" (mainly here in Brazil) even without presenting concrete reasons for this. Concrete reasons go beyond simply "I'm going to improve the modularity of my code," or "I'll better define the responsibilities of each component." This type of decision strongly compromises the entire productive chain, because it adds elements that increase complexity without real need for it. Nobody swaps the ORM of the whole system once a month, or a dependency injector.

If Microsoft's own component models start with simplification, it means that rowing in the opposite direction runs counter to the productivity premise of the framework vendor itself. An example of this is that the Scaffold templates for repository are no longer distributed together with Visual Studio since the 2013 release.

  

Is there any design pattern that defines this?

A Controller is still a Design Pattern . A Model does not either. I did a design pattern mapping exercise in ASP.NET MVC and what I got so far was this:

  • Factory : Controllers Creators
  • Decorator : Models and Controllers attributes
  • Proxy : Creating temporary objects for lazy loading when using Entity Framework;
  • Iterator : Everything that implements IEnumerable ;
  • Observer : DbContext of the Entity Framework;
  • State : DbEntityEntry of the Entity Framework;
  • Template Method : ASP.NET MVC abstract classes, such as System.Web.Mvc.Controller ;
  • Visitor : Entity Framework query generators.

Responding to your question, depending on the approach you take to building standards, ASP.NET MVC implements its own standards.

    
19.02.2016 / 06:25