Three-tier architecture is perfectly good for describing the overall design of a software product, but it doesn’t address what happens inside the UI layer. That’s not very helpful when, as in many projects, the UI component tends to balloon to a vast size, amassing logic like a great rolling snowball.
It shouldn’t happen, but it does, because it’s quicker and easier to attach behaviors directly to an event handler (a la Smart UI) than it is to refactor the domain model. When the UI layer is directly coupled to your GUI platform (Windows Forms, Web Forms), it’s almost impossible to set up any automated tests on it, so all that sneaky new code escapes any kind of rigor. Three-tier’s failure to enforce discipline in the UI layer means, in the worst case, that you can end up with a Smart UI application with a feeble parody of a domain model stuck on its side.
In this architecture, requests are routed to a controller class, which processes user input and works with the domain model to handle the request. While the domain model holds domain logic (i.e., business objects and rules), controllers hold application logic, such as navigation through a multistep process or technical details like authentication.
When it’s time to produce a visible UI for the user, the controller prepares the data to be displayed (the presentation model, or ViewData in ASP.NET MVC, which for example might be a list of Product objects matching the requested category), selects a view, and leaves it to complete the job. Since controller classes aren’t coupled to the UI technology (HTML), they are just pure application logic. You can write unit tests for them if you want to. Views are simple templates for converting the view model into a finished piece of HTML. They are allowed to contain basic, presentation-only logic, such as the ability to iterate over a list of objects to produce an HTML table row for each object, or the ability to hide or show a section of the page according to a flag on some object in the view model, but nothing more complicated than that. By keeping them simple, you’ll truly have the benefit of separating application logic concerns from presentation logic concerns.