0

I've learned MVC (model-view-controller) but I've been unable to figure out how to implement it in a way that respects encapsulation between the three components.

For example, I was always taught that the front end and back end should be completely separate, and should never interact. But in MVC, the Model actually mutates the view, which means the model has a reference to the view.

Similarly, the controller needs to take in input from the front end (ex. button, text box, etc) and mutate the model. How can the controller be both separate from the view AND have its components (button, text box) inside of the view (otherwise they wouldn't be shown to the user). Wouldn't this mean the view would have to be mutable?

I asked my professor about this, and pointed out some violations in abstraction and encapsulation with MVC and he responded by saying that "it is part of the design, to responsibly use references to the view and model. If someone designing the model happens to take advantage of the lack of encapsulation of the view, then it violates the contract of the design."

Is there a way to implement MVC in a way where no one component can cause harm to another (ex. model cannot delete the scene of view, controller cannot null-out all data inside of model, etc etc). Is the key just to setup many accessors/mutators in view & model?

1
  • OP, are you thinking about MVC with respect to web applications, or in a more general sense? Commented Nov 5, 2018 at 19:14

3 Answers 3

-1

When I implement MVC, the Model has neither access to the Controller or to the View. In fact, I try to limit the model to simply being raw data - like a copy of a record from a database. Simple, light-weight.

The Controller is my wrapper around the Model and is where all the heavy duty logic sits. It alone is responsible for modifying the underlying Model (if editable), carrying out corresponding business logic, and for raising events when things change. The Controller has no direct access to the View (there may be several): instead the View invokes Controller functions and updates it's properties. The Controller may also "massage" the raw Model data into a format that is more easy for the UI layer to interact with.

The View has no direct interactions with the Model. It updates in response to events from the Controller. User-interactions (like editing a text-box, clicking a button, etc) generally get re-directed to the Controller. The UI layer should only care about UI-specific work.

Thus you have a nice layered software architecture: UI -> Business Logic -> Data. Nothing can directly interact with the layer on top of it - only indirect interactions through events are permitted. You can also pass around the same Controller instance to multiple Views so that they stay in sync.

Sign up to request clarification or add additional context in comments.

13 Comments

This is not MVC. See Wikipedia, or the answer from @Kata.
@jaco0646 - This is false. Models can just be pure data in MVC. You can also give them some limited behavior (like data change events) - but most of the logic goes into the Controller. As it states on wikipedia: 1. The model is responsible for managing the data of the application. It receives user input from the controller. 2. The view means presentation of the model in a particular format. 3. The controller responds to the user input and performs interactions on the data model objects. The controller receives the input, optionally validates it and then passes the input to the model
Additionally, the model updates the view whenever its data changes. The controller does not update the model and then update the view. The flow goes round a circle, as the diagram shows.
Yes the data change event commonly goes into the data layer, this would be the one discrepancy with what I did above. The View doesn't actually care about where the event comes from, however, it is simply important to that the View be updated via an event. Since the Controller is in charge of modifying the data - and never the View - it is reasonable that the Controller would fire such events, since it always knows and initiates such changes. Also, MVC refers to a family of programming models, with lots of such variations (MVP, MVVM, etc) where you do see the controller fire events.
Glad to hear that! Actually these days I don't mind to focus too much on these stuff of terminologies. Just design your program so that it is easy to manage and reuse, that's it! So, if you want to put business logic into Controller, go ahead. But in the future, if you want to reuse that logic in another environment which does not require UI, or requires a different UI, then you should extract that logic into Model.
|
-1

Model objects are not dumb data, they are true objects with behaviors. So Controller cannot null-out data of Model as you said. The job of Controller is just converting input sent from View, to a format that can be understood by the behaviors exposed by Model. If the converting succeeds, Controller will pass the converted input to Model. Otherwise, Controller will directly notice to View without bothering Model.

Model also cannot directly mutate View as you said. Model keeps an indirect reference to View: Model does not depend on the View type but depends the interface implemented by View. Model just notices the output to View. How View responds (like deleting a scene) to the received output is up to View.

Letting objects directly mutate data of other objects is a very bad practice in OOP.

4 Comments

Thanks for the reply. Can you show a brief example of what you mean by "Model keeps an indirect reference to View"?
class Model { private OutputPort op; public Model(OutputPort op) { this.op = op; } } ... interface OutputPort { void setResult(String result); } ... class View implements OutputPort { public void setResult(String result) { this.resultLabel.setText(result); } } ... You may find this article interesting blog.cleancoder.com/uncle-bob/2012/08/13/…
@Hatefiend, the relationship between model and view is the Observer Pattern.
The Model shouldn't explicitly reference the View. The View should be informed of updates to the Model via events. The event source can either be the Model itself or else the Controller.
-2

Think of it as two separate applications:

Controllers live in one application. Their purpose is to accept input and/or create output. Both input and output are a Model, often the same one (after a bit of validation). Models are just dumb containers for the inputs and outputs.

You can unit test controllers completely independently. A test harness can just feed them input (and mock their dependencies) and check their output. Because Models are dumb, they don't even have to be mocked.

Views live in another application. Their purpose is to accept input and make a page look a certain way. The input, of course, is the Model.

In a clean MVC architecture, models are as dumb as DTOs. Models do not manipulate views or manipulate controllers; in fact, they are fine having no behavior at all. When you do it this way, there are no dependencies at all between View and Controller, and the Model acts simply as an interface. This is how you get encapsulation and separation of concerns.

4 Comments

This answer is completely wrong. In MVC, "The model is the central component of the pattern." Wikipedia
This answer is totally wrong. Model is about about business domain, including data/logics/behaviors or whatever belong to the domain. Controller and View are non-domain things: UI.
With respect, @jaco0646 and kata, your feedback is a too black and white given the complexity and history of MVC. Modern MVC is actually an adaptation of the Model2 pattern, and in this context the models serve the role previously assigned to ViewModel. Business logic is extracted to services which are injected into controllers, and may have their own "model" (domain objects), which is what I suspect you are referring to. But there is actually some debate about this as well. Will edit my post with references if I get some time later.
I'm talking about the original MVC created by Trygve Reenskaug, which then echoed by Martin Fowler in his book (chapter 14) and by Uncle Bob in his article. If the asker of this question clarifies that he wasn't mentioning about the original MVC then I will remove my comment.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.