158

I have a drop down list that displays values from a table to the end user. I would like to have these values be sorted alphabetically.

According to proper MVC design, at what layer should I place my sorting logic: the model, the view, or the controller?

EDIT: In response to LarsH's question, "Do you mean code that determines what sort order is desired? or code that performs the sort?", I was originally referring to the code that determines what sort order is desired.

Ryan Kohn
  • 13,079
  • 14
  • 56
  • 81
  • 6
    In order to resolve disagreement in comments, it would be helpful if you say what you mean by "sorting logic". Do you mean code that determines what sort order is desired? or code that performs the sort? – LarsH Aug 15 '12 at 16:02
  • 9
    The MVC design isn't anything special or magic--it's really just a starting point. make it fit your needs and remember you can refactor any time. I've noticed that different vendors will redifine what goes into the controller or view based on their toolkit's needs so it's hard to find any agreement. The important thing is to separate your Model from your View/Controller. You might also get more mileage from the MVP pattern, I believe it's a little more specific in exactly this area. – Bill K Aug 15 '12 at 16:13
  • 9
    Maybe this should be migrated to Programmers. – Alfredo Osorio Aug 15 '12 at 16:47
  • 1
    data? from a table? in a database? add a sort setting to the retrieval op and it's done. – jqa Aug 15 '12 at 17:31
  • @AlfredoO Of the two, Programmers and Stackoverflow, which do you consider to be the more concerned with design patterns? Do you consider this question to be concerned with a pattern or its implementation? – chb Aug 15 '12 at 18:27
  • 57
    Definitely in the controller. Either that or the model. Or the view. – mob Aug 15 '12 at 20:08
  • 2
    Definitely never, never, ever, ever in the view. – contactmatt Aug 21 '12 at 17:51
  • This kind of question is one of those things that points out the fact, that while MVC is a very useful pattern for building programs with GUIs, it is not a silver bullet. – Zeke Hansell Aug 22 '12 at 19:42

12 Answers12

62

Who controls the sort order?

Simple MVC diagram (From Wikipedia)

1) Natural order within the data itself:

The order is part of the Model, so it should go there. A raw pull of "all data" would return the data in the sorted order, and there is no interface to choose the sort order.

2) The user should control how they see the data:

The View would provide an interface (such as ascending/descending arrows) that interact with the Controller, and the Model understands the data well enough to do the requested sort on the data. However, a raw pull of the data doesn't necessarily have to be sorted, unlike in (1).

In either case,

The View doesn't understand that there's a sort going on, other that the ability to show which sort direction has been chosen. Don't put the logic there.

Small caveat

The sorting functionality could go purely in the View, under one circumstance (that I can think of offhand; there may be more):

A "dumb" sort where all the data is already in the view and it doesn't have to use any domain knowledge to do the sort. Very simple string or number comparison, for example. This is not possible in, for example, search results on a webpage when results are likely to be split across multiple pages.

Izkata
  • 8,961
  • 2
  • 40
  • 50
  • 59
    The view can see the user!? – Farzher Aug 15 '12 at 15:10
  • 41
    The model updates the view!? – deceze Aug 15 '12 at 15:14
  • @deceze: Technically the model doesn't update the view itself. But in a full pure capital-M "MVC" implementation, it does send a message (fires an event, whatever) saying it's been changed, and the view hears it and refreshes or whatever. So you could say the model *triggers* an update of the view, but not that it actually *updates* the view. – cHao Aug 15 '12 at 15:44
  • 13
    That wikipedia article sucks: the "Component interaction" section conflicts with the diagram shown on the right (that you just posted here). Secondly, the model does not "update" the view. It NOTIFIES the view when there has been a state change. The view decides how to update. Ugh. You wonder why there is 1000 different answers to this question when there is so much unclear info floating around. – KyleM Aug 15 '12 at 15:50
  • 4
    @cHao Sure. We can agree that the Wikipedia graph is quite weird though, right? :) – deceze Aug 15 '12 at 15:50
  • @deceze: Oh, yeah. it's a bit odd. :) – cHao Aug 15 '12 at 15:54
  • 6
    @StephenSarcsamKamenar and everyone else: No, the image makes perfect sense: It's showing the _flow of data_, not the code connections. – Izkata Aug 15 '12 at 16:41
  • @deceze and everyone else: User interaction creates a command sent to the Controller, Controller interprets it and does something with the model, modified (sorted) data is sent from the model to the view (I would assume by way of the Controller, but the Controller shouldn't be manipulating it on the way back out), and data from the View is seen by the User. – Izkata Aug 15 '12 at 16:43
  • (And pinging @KyleM now), it's because connections in MVC aren't well-defined. How does the View know to update from the Model? How does the Controller know which part of the View was interacted with? How does the Controller know how to tell the Model something? So on and so forth. So you get different ways to describe the same thing, because different people think of patterns in different contexts. For example, that diagram (as mentioned above) is data flow, _not_ code connections, while the text of Wikipedia is probably talking about code connections. – Izkata Aug 15 '12 at 16:47
  • 2
    Izkata, to clarify, I am not complaining about your answer so much as the wikipedia article... the view knows how to update because the model has a list of observers (views) that are notified by the model when there are changes to the model. – KyleM Aug 15 '12 at 16:52
  • @KyleM I understand, all 3 of those comments are really meant as clarification for everyone, just wanted to make sure no one missed out ;) But funnily enough, the way I learned it, the Model doesn't know anything about the Views, it's the Controller that links them together. – Izkata Aug 15 '12 at 16:56
  • 1
    @Izkata: That's Model-View-Presenter (http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93presenter), no? – Managu Aug 16 '12 at 04:32
  • @Managu [Model-View-Adapter](http://en.wikipedia.org/wiki/Model–view–adapter) also exists. They're all similar enough that IMO it's just implementation details with small tweaks in the design... No wonder the details of MVC seem so unclear (given the other answers), as KyleM said. – Izkata Aug 16 '12 at 12:06
49

(Note: this quote and citation is taken from @dasblinkenlight's answer, but we disagree on our interpretation of it. read his post and make up your own mind).

According to MVC description,

A controller can send commands to its associated view to change the view's presentation of the model (for example, by scrolling through a document). It can send commands to the model to update the model's state (e.g. editing a document).

Sorting logic (e.g., the sorting comparator/sorting algorithm) belongs in the model since it contains business rules and state data. Since altering the way the model data is sorted falls squarely into the "change the view's presentation of the model" category, the controller is responsible for "doing the sorting" by calling the model.changeSortedState() method.

Community
  • 1
  • 1
KyleM
  • 4,445
  • 9
  • 46
  • 78
  • 9
    What if the same data is to be displayed in two different views, sorted differently? – s4y Aug 22 '12 at 05:22
  • That should also be done in the same way, model.SortAscending() and model.SortDescending() and called by Controller. – Brij Aug 23 '12 at 10:09
  • 1
    @Brij In proper MVC, can two views not share the same model? – KOVIKO Sep 03 '12 at 13:40
  • @Sidnicious If it makes sense to have one sorting method that takes a different parameter. E.g. `public void Sort(bool sortByDescending = false)`, where if false it sorts by ascending. Or just have two different sorting methods if the logic is very different. – MattMcGowan Nov 04 '15 at 10:26
  • @Sidnicious have two different models that delegate everything but the sorting logic to a single third model. https://docs.google.com/drawings/d/1hTy0wUABgqVNWBiJImWNqyS0if6MOry9yup8CUZvzoc/edit?usp=sharing –  Dec 11 '15 at 14:03
18

According to MVC description,

A controller can send commands to its associated view to change the view's presentation of the model (for example, by scrolling through a document). It can send commands to the model to update the model's state (e.g. editing a document).

According to this, sorting logic belongs in the controller, because altering the way the model data is sorted falls squarely into the "change the view's presentation of the model" category.

EDIT: To clarify multiple misunderstandings voiced in the comments, the "sorting logic" is not the code that performs the sort; it is the code that defines the sort. The sorting logic compares individual items to each other to establish an order (e.g through an instance of IComparator<T>) or contains logic that constructs an object to be used for ordering by an external system (e.g. through an instance of IOrderedQueryable<T>). This logic belongs in your controller, because it needs knowledge related to the "business" side of your application. It is entirely sufficient to perform the sort, but it is separate from the code that actually performs it. The code that sorts may be in your view, in your model, or even in the persistence layer that backs your model (e.g. your SQL database).

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • 12
    -1 How did you manage conclude this from that quote? Was there somewhere said that controller is supposed to retrieve information from the model? Controller sends commands to change the state. There is nothing said about extraction or manipulation the information. – tereško Aug 15 '12 at 13:49
  • 3
    @tereško How did you manage to conclude from my answer that the controller needs to retrieve information from the model? By "sorting logic" I mean only the logic that is necessary to establish an ordering - in C# terms, that's providing an implementation of `IComparer`. The remaining "boilerplate mechanics" of sorting, including the retrieval of data from the model, is up to the view. – Sergey Kalinichenko Aug 15 '12 at 13:53
  • 3
    *".. sorting logic belongs in the controller .. "*, what else does this mean ? – tereško Aug 15 '12 at 13:56
  • @tereško Did you read my reply at all? Is that somehow not entirely clear to you that sorting logic is `IComparer`? – Sergey Kalinichenko Aug 15 '12 at 13:57
  • 3
    "A controller can send commands to its associated view to change the view's presentation" really sounds like the view would do the sorting, in response to the command from the controller. – Samuel Edwin Ward Aug 15 '12 at 14:52
  • 1
    @KyleM But the view does not always have enough knowledge to contain the sorting logic. For example, consider a field that has a numeric code corresponding to one of the enums `{Unknown, Pass, Fail}`. Further assume that `Unknown` must always sort last, regardless of the ascending or descending order the user has picked. Placing this logic in the view would tell your view too much about the business nature of the data inside the `code` field. The view should not know it: all it knows is that the user performed a "sort" gesture (e.g. clicked a header); the rest is up to the controller. – Sergey Kalinichenko Aug 15 '12 at 15:25
  • I didn't say the view should contain the sorting logic. I said the model should. The controller should command the model to sort itself. This fits with the idea of "[the controller] can send commands to the model to update the model's state"... – KyleM Aug 15 '12 at 15:45
  • perform in Model, define in Controller OR in View. If view needs the data always in certain order then its simple enough for view to inject the comparator into model. If user input needs to be processed then controller has to either inject the comparator itsself or pass the comparator too - so that view could inject it. – Imre L Aug 15 '12 at 15:50
  • 1
    @ImreL why would you perform the sort in the model? The model knows the most about its own state so it logically follows that the "sorting logic (the comparators) or sort algorithms" would be contained there. The controller would command the model "hey buddy, I need you to do an ABC sort..". – KyleM Aug 15 '12 at 15:55
  • @ImreL I think the "perform in Model" is very wrong, because the sorted/unsorted state is the state of the view, not a state of the model. Multiple users may see model data sorted differently! It is done this way anyway because of vast performance implications of performing the sort in the view, where it belongs (note again that the sort logic should still be defined in the controller). – Sergey Kalinichenko Aug 15 '12 at 15:55
  • by "perform in model" i actually meant "handle in DAO" – Imre L Aug 15 '12 at 16:06
  • @ImreL I understand that -- indeed, the DAO layer provides the fastest way of sorting, but it requires bending the rules quite a bit, because it puts the model in charge of a presentation matter. – Sergey Kalinichenko Aug 15 '12 at 16:10
  • 1
    sort order is not only a presentation matter. – Imre L Aug 15 '12 at 16:13
  • Think about this: if you need model in another controller/view. Where would you put it to get the most code reuse. – Imre L Aug 15 '12 at 16:15
  • @ImreL A helper class is just as good for code reuse as the model. The only reason the sorting call is often done through the model is unparalleled efficiency of the overall solution. – Sergey Kalinichenko Aug 15 '12 at 16:22
10

None of the above. Sorting is business logic, and business logic doesn't belong in any of the three. Not every piece of code in your application will be a model, view, or controller.

What I generally do in my MVC apps is I have a service layer that performs all the business logic. The methods in the service layer should have a clean, simple API with well named parameters. You can then invoke those methods from your controller to manipulate the data in the models.

In that sense, the sorting is "in the controller", but the code itself that does the sorting should not be implemented in the controller, only invoked from there.

nont
  • 9,322
  • 7
  • 62
  • 82
  • 6
    I've recently been informed that some people consider a "service layer" (business logic) to be part of the model. – Marvo Aug 20 '12 at 19:40
  • @Marvo I think there are some cases where certain pieces of logic are so intimately tied to their data type that it makes sense to encapsulate them together in one class. (time and date functions for example). In general, though, I find it works best when model objects do nothing but hold data. – nont Aug 22 '12 at 15:03
  • Then where does the business logic "live" in the MVC pattern? – Marvo Aug 22 '12 at 18:27
  • 2
    Just because an application uses an MVC pattern, doesn't mean that every piece of code in the application will be a model, view or controller. That's taking design patterns too literally. For example, your application probably has a configuration file of some kind. That config file is neither modeling user data, nor presenting views, nor controlling the flow of data through models to views. Its a config file, which is its own kind of thing. – nont Aug 22 '12 at 19:17
  • One could just as easily consider a config file part of the model. The model doesn't have to be a database. I'm not saying you're right or wrong. I'm just suggesting that you, as I recently did (because I held the same view you have) google the subject up a bit and see what others are saying. – Marvo Aug 22 '12 at 22:49
  • sure @Marvo, you could consider anything to be anything. The guy who came up with MVC had at one point four elements: Thing-Model-View-Editor. So its gone through a number of iterations and shouldn't be taken as literal gospel truth that everything should be a M, V, or C http://heim.ifi.uio.no/~trygver/themes/mvc/mvc-index.html – nont Aug 22 '12 at 23:45
  • Nont, most references clearly state that the business rules are part of the model in a MVC architecture. – KyleM Sep 14 '12 at 19:29
  • KyleM, what references? If you show me a good argument for why the model should own the business rules, you might convince me. However, I've tried it that way, and found that it results in unmaintainable code. Without a reference, your statement amounts to "someone on the internet say so", which is not a good argument. – nont Sep 14 '12 at 19:42
  • Microsoft: http://msdn.microsoft.com/en-us/library/ff649643.aspx; Java sun: http://java.sun.com/blueprints/patterns/MVC-detailed.html; The model provides business rules.. methods for accessing and changing the state of the application.. "business logic". Pretty much every explanation of MVC online concedes this point. – KyleM Sep 14 '12 at 20:27
  • Btw, if you want to think about your business rules as being part of a separate component altogether, then by all means go ahead. But since the purpose of business rules are to access and change the application's data (the model), they are also considered part of the model. – KyleM Sep 14 '12 at 20:30
  • Thanks for the links KyleM. I think there might be two different senses of "ownership" which are conflated in this question. Should the model class contain the business rules/logic? I think not, because I've seen the mess that can create. Might it "own" the logic in some more abstract sense like through composition? I could see that working out ok. – nont Sep 14 '12 at 20:35
8

Definetly not the controller: It sends messages to view and model but should do as little work as possible. If the user can change the sorting that request gets handled by the controller by informing the model or the view about it.

Maybe the View if it is a pure View thing. If the Application works just as well without sorting then the sorting is just part of the representation and should go in the view.

If the ordering is inherent part of the domain it should go in the model.

KyleM
  • 4,445
  • 9
  • 46
  • 78
Jens Schauder
  • 77,657
  • 34
  • 181
  • 348
  • Does "providing a comparator or a sort descriptor" count as "doing work"? Because a sorting logic is encapsulated in a comparator or a sort descriptor, even if the "sorting work" is done in the sort method or the back-end of the model. – Sergey Kalinichenko Aug 15 '12 at 14:59
  • Depends on what you mean by providing: passing in is ok. But the Comparator should be part of model or view, not the controller. – Jens Schauder Aug 15 '12 at 16:31
7
  • Views are the part of MVC which is supposed to contain presentation logic.
  • Model layer is where business logic is contained.
  • Controllers only change the state of both, based on user input.

So the choice is - do you think that this is part of the domain business logic or presentation logic.

If you were implementing a proper MVC Model2 or classical MVC pattern, then I would say that the ordering of data provided by the model layer should be triggered by the view's request to the model layer. View asks for ordered data, model layer provides it.

But, since you are using ASP.NET MVC's interpretation of MVC pattern, which is a bit different then your standard MVC - the ViewModel instance should request ordered information from the model layer (for some reason ASP.NET framework thinks that templates should be called "views" and views should be called "viewmodels" .. it's strange).

tereško
  • 58,060
  • 25
  • 98
  • 150
  • 12
    You went on downvoting multiple answers applying your *own assumption* of what they mean by "sorting logic". Your assumption is utterly incorrect - sorting logic does not, and never did, include retrieval. – Sergey Kalinichenko Aug 15 '12 at 13:58
  • 1
    @dasblinkenlight , yes , i downvotes multiple topic because they all implied that controller should perform the sorting. Which IS wrong. And .. people .. please stop flagging my comments just because you disagree. – tereško Aug 15 '12 at 15:37
  • Just to be clear: I did not downvote your answer because it is not incorrect, and I never flagged any of your comments, because I do not find then to be abusive in any way. Honestly, I do not know how your answer managed to get so many downvotes: I think they are ill-conceived. – Sergey Kalinichenko Aug 15 '12 at 15:43
  • @dasblinkenlight naah .. i was raging about my comments which in this topic happened to vanish. – tereško Aug 15 '12 at 16:08
5

I would usually do it in the controller to remain in line with the pattern as per the other answers. See below for reasoning.

I've been mulling this over and reading the answers and related material and pragmatically speaking I would say it would depend on your application for instance:

Is it a medium/large application and/or has multiple UI's associated with it (i.e. a Windows App, Web interface and Phone interface).

  • In this case I would probably construct a service layer and put it in the business object and then call the appropriate method from the controller.

If its a well defined single UI website and you're using something like EF Code First and you do not have or have no intention of creating a service layer and plan on using a simple out of the box Extension method to acheive it:

  • In this case I'd probably put it in the controller as pragmatically its the best fit with regard to time/budget.

If its the same as the above BUT cannot be implemented with an out of the box extension method.

  • I may well choose to pop it in the Model class (if its truely bespoke to that single type) as it would be more appropriate here than in a controller. If the sort could be applied to more than one class then I'd implement it in an extension method and then call it in the controller.

To sum up:

Dogmatic answer: Service Layer

Pragmatic answer: Usually the controller

Luke Baughan
  • 4,658
  • 3
  • 31
  • 54
  • In which definition controller is responsible for "preparing data for view"? – tereško Aug 15 '12 at 14:10
  • 1
    @tereško : Where the model is "passive" as decribed here http://msdn.microsoft.com/en-us/library/ff649643.aspx in the variations section. See the "HTTP is an example of this". Whilst a purist may dispute this it can be easier for beginners starting out in MVC where they may be using EF or other models directly in the controller and not through a BAL to think of it this way lowering the barrier to understanding the pattern further. – Luke Baughan Aug 15 '12 at 14:39
  • 1
    what you are talking about is "anemic model". – tereško Aug 15 '12 at 14:44
  • Point noted, I've removed the offending descriptions as you suggested. Cheers for the input! – Luke Baughan Aug 15 '12 at 14:53
3

I would suggest sorting data from a table-data that is small enough to be useful in a dropdown list-should come from the DB already sorted via the query. To me, that makes the model the place the sort is applied.

If you are determined to do the sort by hand, I think there are good arguments for using either the model or controller as your preferred spot for logic. The limitation would be your particular framework. I prefer to manage data solely in the model. I use the controller to marry data(model) and presentation(view) as I've been (self)taught.

B0nk3r
  • 203
  • 1
  • 5
2

Whilst I agree in principle with the idea that sorting is Business Logic because by breaking it down to it's origin you would end up with something like "The client would like the Product page to display with the images sorted by date" then it becomes clear that the sort order for data is typically not arbitrary - even if there is no sorting as that's still a business decision by omission (an empty list is still a list).

BUT... These answer don't seem to take into account the advances in ORM technology, I can only talk in relation to the Entity Framework (let's avoid an argument about whether this is true ORM, that's not the point) from Microsoft as that's what I use, but I'm sure other ORMs offer similar functionality.

If I create a Strongly Typed view for a Product class using MS MVC and the Entity Framework and there is a foreign key relationship between the Product and Image table (e.g. FK_Product_Image_ProductId) then I would out-of-the-box be able to quickly sort the images during their display using something like this in the view:

@foreach(Image i in Model.Image.OrderBy(e => e.DisplayOrder)){ //etc etc... }

There was mention of a specific Business Logic layer, which I also use to perform 80% of my business logic, but I'm not going to write sort functionality into my Business Logic layer that mimics something that comes out-of-the-box from the Entity Framework.

I don't think there's a correct answer to this question, other than to say that; you should abstract complex business logic where possible but not at the cost of reinventing the wheel.

Rob
  • 10,004
  • 5
  • 61
  • 91
  • I was thinking the same thing, answers here don't seem to take ORMs and Extension methods into account. In most cases sorting logic will be as simple as `myList.OrderBy(x => x.CreationDate)` - there really is no need to introduce any unnecessary extra layer just to do this. To add to this, what would they do if they needed paged and sorted data? Query the whole table, sort it then keep what they need? One could just call `myList.OrderBy(x => x.Date).Skip((page-1)*pageSize).Take(pageSize)` and no unnecessary data is retrieved. – Balázs Jul 10 '15 at 08:47
1

Assume that you have MVC website, WebForms website and a mobile application.

If you want sorting to be consistent between these presentation layers, then I'd say sort outside of the presentation layer. Service would be a good candidate.

Otherwise, I would store that logic in a view model. Why? Because it'll be reusable and easily testable.

0

Out of the three you have listed, I would say that it belongs in the controller. I don't really like placing this sort of logic in the controller, though. I usually create a service layer that the controller communicates with that will be responsible for communicating with the data store and handling sorting logic. For small applications it is fine sitting in the controller, though.

Dismissile
  • 32,564
  • 38
  • 174
  • 263
0

This is a question asked with the asp.net in mind, but since somebody did mention Rails, I thought it would be interesting to consider the problem in that context. In Rails, it is natural and pretty common to perform the sorting along with the retrieval as a controller action, since the framework and ActiveRecord/ActiveQuery api provisions for it. On the other hand, it is possible to define some sort of custom sort order for static items and put that in the model to be used by the controller, so the model can play a part in the sorting logic even though it does not carry out the operation directly. Whatever it is, it can be safe to say that putting the sort logic in the view is generally frown upon.

I'm slightly amused that some answers are absolutely against putting the sort in either the controller or the model, and I find them too pedantic for my taste, but I suppose it depends on the nature of the framework used and the usual conventions associated with it. I also agree with Bill K's comment that having the separation in the first place is more important.

prusswan
  • 6,853
  • 4
  • 40
  • 61