4

creating an MVC structure and pondering this...

My view has an Add button. Click it and we send off a request to the controller (using pub/sub so view doesn't really know who its talking to). Having done this the view disables its Add button until it receives a "data added" event from the controller (again pub/sub so doesn't really know who from). At this points it updates its list and re-enables the add button.

My question is this. Should the view contain this logic about enabling/disabling the add button or should the controller? My thoughts so far are perhaps the controller because it is up to the controller whether multiple adds can be handled at any one time or whether they need to be serialised in the method described. however, it is easier to implement the current scheme in the view as don't have to expose so many methods to control the view.

Is there a preferred way that is the most MVC compliant? Thanks :)

Jimbo
  • 217
  • 2
  • 7
  • 1
    Related: http://stackoverflow.com/questions/17836421/how-dumb-can-mvp-views-really-be – durron597 Jan 30 '15 at 15:01
  • Oh man, can't believe I didn't find that one! Thanks :) – Jimbo Jan 30 '15 at 15:04
  • 1
    possible duplicate of [Is it possible for business logic not to creep into the view?](http://programmers.stackexchange.com/questions/240598/is-it-possible-for-business-logic-not-to-creep-into-the-view) – gnat Jan 30 '15 at 15:06
  • @gnat: I don't really see how that applies here. – Robert Harvey Jan 30 '15 at 15:13
  • 1
    @gnat - arguable about whether or not disabling a button is business logic. On the one side, you ought to have a business rule in place that says "disable buttons while operations are in progress." but that's also considered a good UX design principle that the business rules may assume are already there. –  Jan 30 '15 at 15:14
  • @GlenH7 the way how question is written, it reads a business logic to me: _disables its Add button until it receives a "data added" event from the controller_ – gnat Jan 30 '15 at 15:29
  • @gnat: But timing issues like that are not business logic, any more than routine form validation is. – Robert Harvey Jan 30 '15 at 15:42
  • @RobertHarvey I did "business-free" button disabling in one of the past projects. It was strictly timer based - pure UX, no trace of any business logic involved. IIRC it was about 600-800 milliseconds to give user a sense of button press feedback, or about [nanocentury](http://wordaligned.org/articles/pi-seconds) if I wanted them to pay attention – gnat Jan 30 '15 at 15:46

3 Answers3

8

The Controller should be just as dumb as the View.

So in this case, we need to ask about responsibility.

Views are responsible for UI elements and displaying things. Controllers are responsible for connecting Views with Models and providing data for the View to display.

A Controller should be dumb about what the View has within it, buttons included. So the View should be responsible for enabling / disabling the button.

Keeping the Controller oblivious of the View allows you to more easily decouple the View from the Controller and have multiple types of Views reuse the same Controller.

  • Hi, this also makes sense and got me thinking... If the view is responsible for the enable/disable, this also implies it knows that it can only do one add at a time. So, doesn't this imply it has some knowledge about the overall architecture? Is there a good way to get around this? Should the controller know this and tell the View how many adds it can accept simultaneously? Should the model? Should the main application? – Jimbo Jan 30 '15 at 15:13
  • 1
    @Jimbo: You're almost certainly overthinking this. The question you should be asking yourself is "why would the controller ever be responsible for a button in the browser?" To put it another way, you need Javascript to enable and disable buttons. – Robert Harvey Jan 30 '15 at 15:15
  • @Jimbo Sure, a View often cannot be re-used with another Model because it has dependencies on the Model, but in practice that might be OK. – dcorking Jan 30 '15 at 15:15
  • 1
    If a View can only do one thing at a time, that's an issue for the View. An asynchronous application wouldn't necessarily have that limitation, so that's a special property of the View. A Controller wouldn't care about throttling a View's requests like that. –  Jan 30 '15 at 15:16
  • @dcorking A properly written view should not have dependencies on the model. Client manipulation of a view should fire events off into an event handler which eventually reach the model. But these events should not be model specific. – durron597 Jan 30 '15 at 15:17
  • Hi Guys, thanks for your answers, all very helpful. I think I'm more clear on how to apply the concept :) – Jimbo Jan 30 '15 at 15:21
  • @durron597 I agree. The situation I imagined was if the OPs MVC combination was the only part of the program that needed "enable/disable" or "add data/data added" messages. – dcorking Jan 30 '15 at 15:25
1

In all likelihood, you should be doing this so that the add button doesn't get enabled again until there is something to add. That means you need client-side validation, which occurs in the View.

Robert Harvey
  • 198,589
  • 55
  • 464
  • 673
0
  • If you can thoroughly test the view, then there is no limit to how smart it can be.

  • If it is not practically feasible to test the view, then it should be so dumb that you can tell that it is correct by just looking at it.

Let's take an example.

Suppose that you have a model which deals with public opinion polls, exposing poll results as a list of floats, and you have a view which displays those results as customizable bar charts or pie charts.

If your view is rendering the charts in a web page, then it is testable, because you can produce various sets of sample data and display options, feed them to the view, capture the html output for each, and check to make sure that it is as expected.

If your view is rendering the charts on the screen, then it is not really testable, because even if you capture its output in a bitmap, it is extremely difficult to verify that the image contains what it is supposed to contain.

So, in the second case you need to dumb down your view, to the point where it is so simple that it does not require testing. That would be a view which takes graphics primitives (polygons and texts) and simply sends them to a renderer. Obviously, there is a gap here: on one hand you have a model which produces a list of float, and on the other hand you have a view which needs a list of polygons and texts. So, your view would need to be hooked up not to your actual model, but to an intermediate model which transforms lists of poll results to sets of polygons and tests. This transformer is testable, so it can be as smart as it needs to be.

Mike Nakis
  • 32,003
  • 7
  • 76
  • 111