Where should the business rule be in the MVC standard?

Asked

Viewed 10,118 times

21

A few weeks ago I started to study in depth ASP.NET MVC and, as 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 much where the business rule should be focused. Most of the time, it left the business rule of the application in the controller or created an "intermediate class" that would do this. Example:

Customer model

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

Middle class

public class ClienteService
{
    private Cliente _cliente;

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

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

My doubts are as follows::

  • This is the standard or recommended to use?
  • The right thing would be to let the whole business rule in controller?
  • Is there any Pattern design that defines this?

3 answers

16


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

There is a great discord whether it should be placed on the model or the controller (M or C of the MVC).

As stated by the reply of @Gypsy there are two premises to use logic in the model:

  • I will use that same logic in two or more places of my code?

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

I’ll add two more that are:

  • Code testing;
  • Sharing models between 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 on the controller as well, but this is not the issue here). With this 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 I must make the logic in the model?

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

A simple example are the Dataannotations, that are placed in the Model. And are business rules.

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

The Blog da Microsoft has a very good article about the "Best Practices" to use Asp.NET MVC. It’s a little old, but many things apply today.

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

I did not speak well, 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 must have the logics relating to data entry and what it will perform.

Let’s look at the project Musicstore of Microsoft itself.

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 the IdentityConfig.cs.

Your application can have business rules deferent to access time, limit of requests, among others. Are these business rules or not? These are things the Model doesn’t need to know, doesn’t agree?

Concluding

If your rule belongs specifically to the domain, put in the domain, but in a way that the controller understand, to be able to use what Asp.NET MVC provides you with good and give a quick response to the user. Dataannotations are excellent for this.
If your rule belongs to the application, don’t even think about the domain, it has nothing to do with that.
And validations that involve data conferencing between Models should be done in Controller or through static classes (Helpers), such as the @Gypsy explains.

  • 1

    About this here: "But you spoke so much of validation in the Model, should I do there?" , validation rule inherent only to the own Model should rather be done in the Model. The attributes, as you said yourself, follow this premise. Validations that involve data conferencing between Models should be made in Controller or through static classes (Helpers).

  • 2

    @Ciganomorrisonmendez I think the "No" really got strong in this placement. My intention was not that. About the Helpers I agree, I forgot to comment on the name, but I hope you don’t mind "copying" your text. p

  • 2

    A big problem that I see and that I commented on in the answer are people using Helpers like being a Service or using Repository as if it were a Helper.

14

Where the MVC standard business rule should be?

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

The concern that the creation of Pattern MVC (back in the 1970s) was trying to resolve is the separation between presentation and business logic, and the controller most often is quite attached with the presentation.

See this Fowler drawing representing the MVC:

Relação entre os componentes no pattern MVC

Note that View knows Controller, which also knows View; and note that Model knows no one.

In your book 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 evident in many designs, and that this is not a problem, it is natural that they get confused.

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

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

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

Stackoverflow needs to show the answers first with more votes. Is that a business rule? It certainly is, this is a core principle of the tool.

Stackoverflow can’t admit to an untitled question. That’s also a business rule.

So these rules need to be in Model? They don’t need to be and they probably aren’t. These are very simple business rules, which can be solved in the presentation.

The 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 only Dtos representing in the system the database data.

The OS is probably an example of a system that classifies itself as low complexity of business rules, where an abstraction of the domain in a layer can be unnecessary and even harmful.

Most of the projects I’ve participated in to date, however, had complex enough business rules and sufficient need for reuse that justified a more elaborate design approach. But surely not all systems justify such an approach! I am not going to say "majority" in general because I have no statistical data. I can only speak from my own context.

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

They can if the system has simple rules, basically presentation rules.

They should not be if the system has complex rules, a complex domain, and a high need for re-use (the rules need to be available to more than one type of consumer - as end user, service facade, other business services of the system itself, integrations, code bases of other systems, etc).

I’ll leave the answer with Fowler (taken from the already mentioned book):

"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 shouldn’t 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 separation.

Unfortunately, a lot of UI frameworks make this separation difficult, and those that don’t are almost always taught without separation.

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

  • 3

    So this answer is only based on Fowler? The answer yes, but my motivation to write it is based on many other sources and personal experience. Fowler comes in because people like reliable references in the answer ;-)

11

This is the standard or recommended to be?

The recommended is always the simplest or quickest. If separation is necessary for some reason, go the way of separation. Personally speaking, I rarely do this separation of business rules into intermediate layers because there is no reason in my systems for this to happen.

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

The right thing would be to leave the whole business rule in the controller?

In the vast majority of cases, yes. There are two general premises that can be used to decide this:

  • I will use that same logic in two or more places of my code?
  • The separation represents some real gain in my application that justifies the increased complexity?

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

If in the component models itself Microsoft goes for simplification, it means that rowing in the opposite direction goes against the premise of productivity of the provider itself framework. An example of this is that the models of Scaffold to repository are no longer distributed together with Visual Studio since version 2013.

Is there a Pattern design that defines this?

A Controller is still a Design Pattern. A Model not either. I did a design pattern mapping exercise on ASP.NET MVC and what I got so far is as follows:

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

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

Browser other questions tagged

You are not signed in. Login or sign up in order to post.