42

I understand the role of the model and view in the Model-View-Controller pattern, but I have a hard time understanding why a controller is necessary.

Let's assume we're creating a chess program using an MVC approach; the game state should be the model, and the GUI should be the view. What exactly is the controller in this case?

Is it just a separate class that has all the functions that will be called when you, say, click on a tile? Why not just perform all the logic on the model in the view itself?

Anne Nonimus
  • 979
  • 1
  • 9
  • 10
  • 1
    Personally, *[this is what I do](http://stackoverflow.com/questions/371898/how-does-differential-execution-work).* There may be cases where there is no alternative to MVC, but I can't stand it. – Mike Dunlavey Mar 27 '12 at 22:53
  • 10
    Three words..."Separation Of Concern". – Travis J Mar 28 '12 at 00:19
  • 4
    Almost all Windows programs before .net used Doc-View with no controller. This seems to have been relatively successful. – Martin Beckett Mar 28 '12 at 15:17
  • Martin, un(change)able monolites. – Independent Aug 23 '12 at 17:07
  • I've answered below, but I'll add that yes, you can build an application without distinct controller classes, but that wouldn't be MVC. You're assuming "an MVC approach", so yes, controllers play an important role. If you choose some paradigm that's not MVC it's quite possible that you won't have any controllers. – Caleb Mar 25 '13 at 14:22

11 Answers11

41

Why not just perform all the logic on the model in the view itself?

The controller is the glue that binds the model and view together, and it's also the insulation that keeps them apart. The model shouldn't know anything about the view and vice versa (at least in Apple's version of MVC). The controller acts like a two-way adapter, translating user actions from the view into messages to the model and configuring the view with data from the model.

Using the controller to separate the model and view makes your code more reusable, more testable, and more flexible. Consider your chess example. The model would of course include the game state, but it might also contain the logic that affects changes to the game state, such as determining whether a move is legal and deciding when the game is over. The view displays a chess board and pieces and sends messages when a piece moves, but it doesn't know anything about the meaning behind the pieces, how each piece moves, etc. The controller knows about both the model and the view as well as the overall flow of the program. When the user hits the 'new game' button, it's a controller that tells the model to create a game and uses the new game's state to set up the board. If the user makes a move, the controller relays the command to the model and, based on the response, allows the move or not.

Look at what you get by keeping model and view separate:

  • You can change the model or the view without changing the other. You may have to update the controller when you change either one, but in a way this is part of the advantage: the parts of the program that are most likely to change are concentrated in the controller.

  • Model and view can both be reused. For example, you could use the same chess board view with an RSS feed as a model to illustrate famous games. Or, you could use the same model and replace the view with a web-based interface.

  • It's easy to write tests for both model and view to ensure that they work the way they should.

  • Both model and view can often take advantage of standard parts: arrays, maps, sets, strings, and other data containers for the model; buttons, controls, text fields, image views, tables, and others for the view.

Caleb
  • 38,959
  • 8
  • 94
  • 152
  • 1
    In the original MVC architecture for desktop applications, views were active classes, observing the model directly, and disconnected from the controller. – kevin cline Mar 25 '13 at 17:57
  • The problem with all the answers is that there are as many interpretations of MVC as people posting. And the benefits listed above only apply to one specific interpretation of MVC. If one were to put most of the logic into the controller (or model) and have the View call/initiate specific method calls on the controller then that makes the Controller/Model combo standalone and very reusable. Most of the time it is a new view that is needed. I have never had a need to reuse a view. Even your RSS example could be easily handled with a new View that uses your old one with an RSS layer in between. – Dunk Mar 25 '13 at 23:03
  • 2
    @Dunk: it is vital to separate the business logic from the user interface so that the business logic can be tested directly. – kevin cline Mar 26 '13 at 20:48
  • @Kevin : I totally agree, business logic doesn't belong in the user interface. However, the controller doesn't need to be part of the user interface. That's what I mean by there are many definitions. In one person's definition the controller handles button presses while another person would put that as part of the view. If the view knows how to turn operator actions (ie. button presses/element selections) into application requests then the Controller/Model become very reusable with nearly any kind of user interface, which could include GUI, Console or network interfaces. – Dunk Mar 27 '13 at 16:27
  • I should add that there are many more variations of MVC than the 2 that I listed above. So it really depends on your definition of MVC as that has a huge impact on what is the "right" way to answer to OPs question. Without clearly specifying the responsibility of all 3 components in your answer it does not make for a complete or even correct answer. And the main reason I even pointed this out is because people were disagreeing with Travis's comments when he is in fact correct if you use the definition of MVC that I described, but not with the one Caleb describes. – Dunk Mar 27 '13 at 16:35
  • 1
    @Dunk: I suppose you can call anything you like a "controller", but in the MVC architecture, the controller is dependent on and therefore part of the user interface. – kevin cline Mar 27 '13 at 17:06
  • @Kevin : Do a search on MVC and you will find that while the diagrams may all look the same/similar once you read about the functionality in each piece there will be at least 10 variations all claiming to be MVC. You could claim that the "original" version of MVC is the only true MVC definition but that would ignore many years of people refining that initial definition into being something that is actually usable in real-life situations. Also, I think you left out a word, "the controller is dependent on...." what? That word seemed to lead to your conclusion that makes it part of the UI. – Dunk Mar 28 '13 at 14:32
7

There are many, many different ways of implementing this general design pattern, but the basic idea is to separate the various concerns as necessary. MVC is a nice abstraction in the sense that:

Model: Represents that data, whatever that might mean
View: Represents the user interface, whatever that might mean
Controller: Represents the glue that causes that model and view to interact, whatever that might mean

It's extremely flexible because it doesn't specify a whole lot. A lot of people waste a lot of bandwidth arguing the details of what each element might mean, what names should be used instead of these, and whether there should really be 3 or 2 or 4 or 5 components, but that's missing the point to a certain degree.

The idea is to separate out the different "chunks" of logic so that they don't overlap. Keep your presentation stuff together, keep your data stuff together, keep your logic stuff together, keep your communication stuff together. And so forth. To a certain extent, the less these areas of concern overlap, the easier it is to do interesting things with them.

That's all you really should be worrying about.

tylerl
  • 4,850
  • 21
  • 32
  • 3
    Glue, glue, I like that definition, it's so correct: **the whole model should be christened MVG** and people would stop scratching their heads in search of elegance where there isn't any to find. – ZJR Aug 22 '12 at 20:11
  • 1
    +1 for “glue”; it also means that it is the part that is best suited to being done in a scripting language (as those tend to excel at gluing). – Donal Fellows Mar 25 '13 at 08:54
  • @DonalFellows I like that thought a lot. Something that "glues" 2 disparate entities together needs a lot of flexibility which weakly typed scripting languages (i.e. JavaScript) promote – Zack Macomber Jan 13 '18 at 16:41
5

Using your example the Controller would be what decided what was a legal move or not. The Controller would let the view know how to arrange the pieces on the board at start up using the information it received from the Model. There are more things that can be handled by the Controller but the key is to think about Business Logic on that layer.

There are times when all the Controller does is pass information back and forth, like a sign up page. Other times the Controller is the difficult part of the development because there are many things that need to be done at that layer like enforcing rules or doing complicated math for example. Don't forget the Controller!

JustinDoesWork
  • 849
  • 4
  • 12
  • 38
    "Using your example the Controller would be what decided what was a legal move or not". This is bad example :( such logic shall be also in the Model. Otherwise your logic is split between Controller and the Model. – Dime Mar 29 '12 at 09:26
  • 6
    @Dime - The model should contain no logic whatsoever. The Controller will be the one holding logic, hence "controlling". – Travis J Mar 29 '12 at 11:40
  • 34
    @TravisJ Don't quite agree there. Controlling doesn't mean knowing how to do a job. It is about controlling those objects that do. Hence the logic for doing the work would be in the model and the controller would control which model to use to perform the necessary requirements of the action etc Too much logic in controllers in my view would be recipe for controller blot... – dreza Mar 31 '12 at 22:25
  • 5
    It's not the OOP-way to have data objects and procedures manipulating them. And it's not the SOLID way to have a Controller which knows about everything and do everything. – Abyx Apr 02 '12 at 12:46
  • 4
    @dreza - I feel badly for your code. Your model should contain data. The controller should manipulate that data through design patterns such as factories, adapters, mediator, etc. All three should be lean, the model, the controller, and the view. Most of the code should be in these design patterns which deal with generics in order to reduce redundancy. – Travis J Apr 02 '12 at 19:50
  • @Abyx - "The programming construct that combines data with a set of methods for accessing and managing those data is called an object." The model should hold a definition of data, not how to manipulate that data nor how to send it up the line. It should only have data to offer and the logic should be elsewhere. – Travis J Apr 02 '12 at 19:52
  • 3
    @TravisJ I feel badly for your code... Try thinking of it this way: Controller: Knight1->MoveTo(cell). Knight1 indicates success/failure through return statement. Controller warns user on event of failure, or on success searches for possible captures and continues. _Both_ the Controller and the Model should have _some_ logic - in this case, every model knows what moves are valid, and the controller mediates the game itself. – Izkata Aug 22 '12 at 20:22
  • 1
    I also agree that a model should be as lean as possible and most (if not all) logic should be in the controller. Models should at their absolute best, be just POCO objects. – sergserg Aug 22 '12 at 20:22
  • 25
    The whole point of OOP is to have cohesive bits of data and behavior kept together and state internally encapsulated. "Model" models both behavior and data. – Misko Aug 22 '12 at 20:45
  • @ChrisMiskowiec - Could not agree more. The structure of the data should be its logic. – Travis J Aug 22 '12 at 20:57
  • 2
    @Izkata - The model should be just a model of the data and the data's relationships. There should be an abstraction which knows what moves are valid. – Travis J Aug 22 '12 at 21:03
  • As a rule the view contains the presentation data and logic, the model contains the "back-end" data and logic, and the controller decides when and how the two meet. "View" can be divided into separate components for templates and template logic, while "Model" can be divided into separate components for data and data logic. But the controller generally should be minimal to allow for greater reuse and less duplication. – tylerl Aug 22 '12 at 23:41
  • 2
    I think most of you people don't know the difference between data model and domain model. The all the bussines logic should be in the domain model. Data model is the data you pass to the view because – Matjaz Muhic Aug 23 '12 at 06:11
  • 3
    @Travis A Controller with "logic" and dumb "data" models is NOT OOP! MVC is not necessarily OO either, but if done with OO, the Controller is just "glue" between the View and the Model. The **Model must have all the logic in order to be OO**. It's ok if you do otherwise, but don't kid yourself: if you have an "anemic" Model, you're not doing OOP. All the patterns in the world won't make it OO, either. – Andres F. Aug 23 '12 at 15:52
  • 1
    @JustinDoesWork This is not Object Oriented: `Using your example the Controller would be what decided what was a legal move or not`. It's fine if you don't want to do OO, but if you do, the **Model** must have this logic. – Andres F. Aug 23 '12 at 15:54
  • @AndresF. - Don't kid **yourself**. Have a look at Stack Overflow's Model: http://code.google.com/p/stack-exchange-data-explorer/source/browse/App/StackExchange.DataExplorer/Models/StackEntities/StackExchangeData.Designer.cs?r=51eb60622e23455ad51d4ef1c4ab83a1d9944828 See how there is no logic in there aside from relationships? If your model has all the logic you are are not separating concerns. – Travis J Aug 23 '12 at 16:05
  • 5
    Worth a read: http://martinfowler.com/bliki/AnemicDomainModel.html – Craige Aug 23 '12 at 19:31
  • 3
    Shouldn't the view and the model be completely ignorant of everything else? That way if you choose a new view you can make the controller aware of it without affecting the model. If you change the model or replace it then with minor changes to the controller you have a different behavior. If the logic is in the controller then you can't do that. So in a board game program you could have models for chess, checkers, back gammon, etc. You just change the model to affect the game type. – Demolishun Oct 20 '12 at 07:43
  • 12
    -1 The controller *must not* contain business logic. The model *is* "the app", it holds the data and has callable routines for everything that can *happen* in the app; not necessarily all in one file or class. The view visualizes the state of the model. The controller bridges the model/view and the real world/input. Want to "publish" *the app* as a web app? Just need a controller that handles HTTP and an appropriate HTML-based view. Want a command line interface to your app? Just need an appropriate controller and view. The model, the business logic, never changes in these cases. – deceze Mar 24 '13 at 22:34
  • 1
    -1 I'm with Martin Fowler on this one. The model should encapsulate the business logic that allows it to be exposed and manipulated by the view via the controller. Changing either the view or model requires changing the controller which will require a *lot* of code if it contains business logic. – David Harkness Mar 25 '13 at 06:00
4

All good answers so far. My two cents is that I like to think of the controller as primarily being built up with questions like What and where?

  • I've been asked if a chess piece (view) can be moved to x. Is it
    allowed? I'm not sure but I know where and who to ask (the model).
  • Something has asked me to save my data. How the heck do I do that? I know where to ask though! How we save the data, or where it's saved to, I've got no idea, but that Repository class should know. I'll forward it and let it deal with it.
  • I've got to show the current chess piece position to the user that the model moved it to. not sure if I want to show the piece as green or yellow? Bah, who cares, I know there's a view that can handle this so I'll pass em the data and they can decide how it's going to be showen.

These little snippets are examples of how I'm trying to remember the abstraction and concept MVC is trying to convey. What, Where, and How are my three main thought processes.

What and where => Controller How and when => Models and views

In essence my controller actions tend to be small and compact and when reading them tend to look sometimes like a waste of time. In closer inspection they are acting as the traffic signal man, channeling the various requests to the appropiate workers but not doing any of the actual work themselves.

dreza
  • 3,466
  • 4
  • 32
  • 39
2

It really comes into play when you are dealing with event handlers, but you still need the controller to handle interactions between the view and the model. Ideally you don't want the view to know anything about the model. Think about it, do you want a jsp to make all the database calls directly? (Unless it's something like a login lookup.) You want the view to render data and not have any business logic, unless it's view rendering logic, but not business logic perse.

In GWT, you get a cleaner separation with MVP. There is no business logic whatsoever (if it's done right) in the view. The presenter acts as a controller and the view has no knowledge of the model. Model data is simply passed over to the view.

2

A Controller could help abstract the interfaces of both the View and the Model so that they don't have to know about each other directly. The less an object has to know, the more portable and unit testable it becomes.

For instance the Model could be playing another instance of itself thru one Controller. Or a networked Controller could connect two player's Views objects together. Or it might be a Turing test where nobody knows which.

hotpaw2
  • 7,938
  • 4
  • 21
  • 47
1

Document-View (ie model view) is the standard model for the majority of Windows apps written in MFC so it must work for a lot of cases.

Martin Beckett
  • 15,776
  • 3
  • 42
  • 69
1

I understand the role of the model and view in the Model-View-Controller pattern, but I have a hard time understanding why a controller is necessary.

Are you sure about that?(At least as originally described) The point of the model is to be the domain model. The view is supposed to display the domain model to the user. The controller is supposed to map low level input to high level model speak. As far as I can tell the reasoning is something along the lines of: A) a high level use of the SRP. B) The model was considered the important part of the app so keep the unimportant and faster changing stuff out of it. C) easily testable (and script-able) business logic.

Just think if you want to make your Chess program useable by the blind, swap out the view for a audible version, and a controller that works with the keyboard. Say you want to add games by mail, add a controller that accepts text. Net version of the game? A controller that accepts commands from a socket would do the job. Add a nice 3d render to it, a cool new view. Zero model changes necessary Chess is still chess.

If you mix input in with model representation then you lose that ability. Suddenly Chess isn't Chess, it is Chess with a mouse which is different from Chess with a keyboard or network connection.

stonemetal
  • 3,371
  • 16
  • 17
0

I think MVC is dumb, maybe in specific areas it works well but personally even websites i write are not suited to mvc. Theres a reason why you hear frontend, backend and never database-end or something-else-end

IMO there should be an API (backend) and the app which uses the API (frontend). I guess you could call the GET request the controller (which simply calls the backend api) and the html the view but i don't usually hear people talking about view as pure html nor model being backend API.

IMO everything should be a solid API. Actually they don't need to be solid (as in clean and well built) but its internals should remain private and the app/frontend/outside of the api should never get say the database connection nor be able to make raw queries.

Now if your code/design involves glue its fine. If in your chess game there is some markup you can edit to skin the GUI, the gui collects the coords/input and calls MovePiece(srcPosition, dstPostion) (which may return a bool or enum to say if it is a valid move or not) and your ok with all logic being in the model then sure call it MVC. However i'd still organize things by classes and APIs and make sure theres no kitchen-sink class that touches everything (nor any APIs to have to know about everything).

  • You're welcome to your opinion, but this answer doesn't attempt to address the OP's question. – Caleb Dec 15 '17 at 05:18
0

Think of a browser that displays a static web page. The Model is the HTML. The View is the actual result on the screen.

Now add some JavaScript. That is the Controller. When the user clicks on a button or drags something the Event is sent to the JavaScript, it decides on what to do and alters the underlying HTML (Model) and the browser/renderer displays those changes on the screen (View).

Perhaps another button is clicked, the event is sent to some handler (Controller), and it may cause a request for further data to be sent to a webservice. The result is then added to the HTML (Model).

The Controller responds to events and controls what is in the Model and hence what is on the screen/View.

Stepping back a bit, you can think of the whole browser as the View and the server as the Controller and the data as the Model. When the user clicks a button in the browser the event it sent to the server (Controller), it gathers together resources as an HTML page (Model) and sends that back to the browser to be displayed (View)

Down in the server whether it is asp, php, or java the 'code' (Controller) receives the click event and queries a database or document repository (Model) and creates HTML. From the server point of view the result of all its actions are a View (HTML) of its underlying datastore (Model). But from the client point of view the result of its request to the server is its Model (HTML)

Even if you jumble up your JavaScript in your HTML or your PHP in your HTML the Model, View, Controller still exists. Even if you think of your request to a server and the response back from the server as a simple two way street, there is still a Model, a View, and a Controller.

zeus
  • 1
-2

In my experience, in a traditional desktop mvc gui program, the controller ends up spaghettied into the view. Most people do not take the time to factor out a controller class.

the gang-of-four book says:

Design Patterns in Smalltalk MVC

The Model/View/Controller (MVC) triad of classes [KP88] is used to build user interfaces in Smalltalk-80. Looking at the design patterns inside MVC should help you see what we mean by the term "pattern."

MVC consists of three kinds of objects. The Model is the application object, the View is its screen presentation, and the Controller defines the way the user interface reacts to user input. Before MVC, user interface designs tended to lump these objects together. MVC decouples them to increase flexibility and reuse.

MVC decouples views and models by establishing a subscribe/notify protocol between them. A view must ensure that its appearance reflects the state of the model. Whenever the model's data changes, the model notifies views that depend on it. In response, each view gets an opportunity to update itself. This approach lets you attach multiple views to a model to provide different presentations. You can also create new views for a model without rewriting it.

The following diagram shows a model and three views. (We've left out the controllers for simplicity.) The model contains some data values, and the views defining a spreadsheet, histogram, and pie chart display these data in various ways. The model communicates with its views when its values change, and the views communicate with the model to access these values.

Taken at face value, this example reflects a design that decouples views from models. But the design is applicable to a more general problem: decoupling objects so that changes to one can affect any number of others without requiring the changed object to know details of the others. This more general design is described by the Observer (page 293) design pattern.

Another feature of MVC is that views can be nested. For example, a control panel of buttons might be implemented as a complex view containing nested button views. The user interface for an object inspector can consist of nested views that may be reused in a debugger. MVC supports nested views with the CompositeView class, a subclass of View. CompositeView objects act just like View objects; a composite view can be used wherever a view can be used, but it also contains and manages nested views.

Again, we could think of this as a design that lets us treat a composite view just like we treat one of its components. But the design is applicable to a more general problem, which occurs whenever we want to group objects and treat the group like an individual object. This more general design is described by the Composite (163) design pattern. It lets you create a class hierarchy in which some subclasses define primitive objects (e.g., Button) and other classes define composite objects (CompositeView) that assemble the primitives into more complex objects.

MVC also lets you change the way a view responds to user input without changing its visual presentation. You might want to change the way it responds to the keyboard, for example, or have it use a pop-up menu instead of command keys. MVC encapsulates the response mechanism in a Controller object. There is a class hierarchy of controllers, making it easy to create a new controller as a variation on an existing one.

A view uses an instance of a Controller subclass to implement a particular response strategy; to implement a different strategy, simply replace the instance with a different kind of controller. It's even possible to change a view's controller at run-time to let the view change the way it responds to user input. For example, a view can be disabled so that it doesn't accept input simply by giving it a controller that ignores input events.

The View-Controller relationship is an example of the Strategy (315) design pattern. A Strategy is an object that represents an algorithm. It's useful when you want to replace the algorithm either statically or dynamically, when you have a lot of variants of the algorithm, or when the algorithm has complex data structures that you want to encapsulate.

MVC uses other design patterns, such as Factory Method (107) to specify the default controller class for a view and Decorator (175) to add scrolling to a view. But the main relationships in MVC are given by the Observer, Composite, and Strategy design patterns.

Caleb
  • 38,959
  • 8
  • 94
  • 152
Ray Tayek
  • 137
  • 5
  • 1
    It looks like this entire post minus the first two paragraphs is taken verbatim from *Design Patterns*. I've formatted that section as a quote so that readers understand that -- please edit if I've quoted paragraphs that are your own. – Caleb Mar 25 '13 at 14:05
  • 1
    I have to disagree with your opinion that "the controller ends up spaghettied into the view." Perhaps it varies with the platform and framework that you're using, but it's far more common in Cocoa and Cocoa Touch programming to create appropriate controllers than to omit them. If an Objective-C programmer omits one of the categories, it's almost certain to be the model that suffers. – Caleb Mar 25 '13 at 14:11
  • If you agree that this is the "proper" interpretation of MVC then MVC buys absolutely nothing. It may as well just be MV and leave out the C because everytime you create a new View you also need to create a new Controller. So what's the point in taking pains to separate them other than for theoretical reasons of separation of concerns. – Dunk Mar 28 '13 at 14:48