In the classic MVC (Model-View-Controller) pattern, what job does each of the Model, View, and Controller play, and why does splitting responsibilities this way help maintainability?
answer
- Model=state+rules, View=render, Controller=input→Model→View
- Smalltalk 1979 origin
- fat controller anti-pattern
- web MVC ≠ desktop MVC
- Model has zero UI knowledge
basics
~10 sModel holds data and business rules, View shows it on screen, Controller takes user input and decides what happens next. Splitting them means you can change how something looks without touching how it works.
solid answer
~40 sMVC separates an app into three roles: the Model owns state and business logic and knows nothing about the UI; the View renders that state and is largely passive; the Controller receives user input (clicks, form submits), translates it into calls on the Model, and picks which View to show next. The dependency direction matters: Model never depends on View or Controller, so business logic can be tested and reused without a UI. View typically observes or reads the Model to redraw itself. Controller depends on both. This separation lets a team change the visual layer without rewriting business rules, and lets business logic be unit-tested without spinning up a UI. The main cost is indirection - three files/objects to coordinate for what could be one script.
go deeper
Can name the three roles and give the one-sentence job of each; doesn't need to know the Smalltalk history or framework-specific variants.
Explains the dependency direction (Model has no UI knowledge) and can point to at least one real framework's flavor of MVC (Rails, Spring MVC) and how requests flow through it.
Recognizes MVC's terminology drift across desktop/web/mobile, can diagnose a fat-Controller codebase, and knows how to extract logic into service/model layers without breaking testability.
Frames MVC as one point on a spectrum of UI-separation patterns, can justify at an org level when introducing MVC discipline (or moving away from it) pays for itself versus adds needless ceremony for a team's actual change patterns.
## The three roles MVC (Model-View-Controller) is an architectural pattern that partitions an application's UI layer into three collaborating objects, each with a narrow, well-defined responsibility. - **The Model** is the keeper of application state and business rules — a `Customer` object, an `Order` aggregate, a shopping cart total. It has no knowledge of pixels, widgets, or HTTP; it exposes methods to read and mutate state and, in the original Smalltalk formulation, fires change notifications when it mutates. - **The View** is a rendering layer: given the Model's current state, it produces what the user sees — HTML, a native widget tree, a terminal report. A well-behaved View is 'dumb': it does not contain business logic, only formatting and layout decisions. - **The Controller** is the entry point for user intent: it receives raw input events (a button click, a form POST, a keypress), interprets them, invokes the appropriate Model methods, and then chooses which View to render as a result. ## Why the split exists The reason this split exists is **separation of concerns under change**. Software rarely changes uniformly across layers — visual redesigns happen far more often than business-rule changes, and business rules change far more often than the need to swap rendering technology entirely. By keeping the Model ignorant of View and Controller, the core logic (tax calculation, validation rules, workflow state machines) can be unit-tested in isolation, with no UI framework bootstrapped. That testability was the historical motivation: **Trygve Reenskaug** designed MVC at Xerox PARC in 1979 for Smalltalk-80 specifically so that non-UI logic could be verified and reused independently of the on-screen presentation, and so that the same Model could back several different Views at once, all staying in sync via the Model's change notifications. ## The trade-offs The trade-offs run in both directions. - **On the plus side:** unit-testable business logic, easier parallel work (a backend engineer owns the Model, a frontend engineer owns the View, a thin Controller wires them), and the ability to reuse a Model behind multiple front ends. - **On the cost side:** indirection overhead for trivial screens — a CRUD form with three fields still needs three coordinated pieces instead of one script — and ambiguity about where logic belongs. ## The terminology drift The 'C' in web-framework MVC (Rails, Spring MVC, ASP.NET MVC) is not the same shape as the original Smalltalk Controller: web Controllers are typically per-request, stateless, and orchestrate HTTP request/response rather than continuously mediating live UI events, so 'MVC' means noticeably different things in a desktop GUI toolkit versus a web framework. That terminology drift is itself a common source of confusion and misapplied advice. ## The failure modes The most common production failure mode is the **'fat Controller'** (or 'fat Model' / 'massive View Controller' as popularized in iOS discourse before MVVM's rise there). 1. When a team is not disciplined about where logic goes, validation, formatting, orchestration, and even direct database queries creep into the Controller because it is the easiest place to add 'just one more check' during a request handler. Over months this produces a Controller method that is thousands of lines long, untestable except through full end-to-end HTTP calls, and effectively the entire application's logic funneled through one class. 2. A related failure is View logic leaking backward — a View that directly queries the Model's internal collections and applies business rules to decide what to render, which quietly re-couples the two layers MVC exists to decouple. ## A concrete example A concrete, widely recognized example is **Ruby on Rails**: - `ActiveRecord` models encapsulate persistence and validations, - `ERB` templates render HTML, - and controllers handle routing, parameter parsing, and calling into models before selecting a view or JSON response. Rails' own documented anti-pattern guidance ('skinny controller, fat model,' and more recently extracting service objects when even the model gets too fat) is a direct, practitioner-facing acknowledgment of the fat-Controller failure mode, and it illustrates that MVC discipline is an ongoing team practice, not a one-time architectural decision.
- Why does the Model never hold a reference to the View or Controller?Because it inverts the dependency the wrong way: if the Model imported UI types, business logic could no longer be tested or reused without a UI runtime, and every UI change would risk breaking core logic. Keeping the Model UI-agnostic is what lets multiple Views observe the same Model.
- How does a web framework's MVC differ from the original Smalltalk MVC?Web Controllers are stateless and per-request: they parse an HTTP request, call the Model, and return a rendered View or redirect, then discard all state. Smalltalk's Controller was a long-lived object continuously mediating live mouse/keyboard events against an in-memory Model that pushed change notifications to multiple attached Views in real time.
- What's a concrete sign a Controller has become 'fat' and needs refactoring?The Controller method directly contains validation rules, formatting logic, or multiple sequential database calls that should be a single Model/service operation, and it can only be tested by simulating a full HTTP request rather than calling a plain method. Extracting that logic into a service object or richer Model method is the usual fix.
Like a restaurant: the kitchen (Model) prepares and knows the food, the waiter (Controller) takes your order and relays it to the kitchen, and the plate presentation (View) is just how the food is shown to you - the kitchen doesn't care how it's plated.
saying these in an interview costs you the question
- says Controller and Presenter are literally the same thing with no distinction
- puts business validation logic inside the View
- thinks Model means 'database table'
- can't explain why Model shouldn't reference View
- claims MVC means the same thing in every framework