MVC Design - How many controllers? - model-view-controller

Overview
I’m building a simple web application consisting of a canvas and elements on the canvas.
The canvas supports the following operations: load, save
The elements support the following operations: move, resize
JavaScript on the web page sends a message to the server for each operation and the server sends an appropriate response.
My design
Note: the arrow between the Canvas and Element objects is supposed to denote that the Canvas object contains a list of Element objects. I didn't have the right symbols for the diagram.
Example work flow
An element on the canvas is moved generating an element_moved message.
The front controller manages the session and passes the message to the canvas controller with the correct canvas object.
The canvas controller inspects the message and sees that it is for an element on the canvas and passes it on to the element controller.
The element controller parses the message and updates the appropriate element object directly.
Question
Is this hierarchical arrangement of controllers common place in MVC designs or am I completely missing the point? I've searched for several hours but haven't found any sites which discuss MVC design in more depth than simply returning a page view.
My motivation behind the design was that each object that the client needs to interact with has a controller so that if the interface changes (to support new methods) then the corresponding controller can be updated without impacting the other parts of the design.

usually you won't have one controller calling another in MVC. What you have specified as Element Controller is really just a part of business logic to update the canvas model. If your use case requires you to update the elements independently of the Canvas, then you will have a separate Element Controller, calling the business logic to update the element.
Cheers,
Ryan

Your situation raises fundamental questions when attempting to organize concerns in client-side JavaScript for MVC.
First Fundamental Question
1) Should the entire "page" use one monolithic Controller, where member methods of such a Controller are the event handlers / starting points for working with a single Model and a single View for the entire page?
In regular expression speak ...
Controller{1}
Model{1}
View{1}
Since there is only ever one Controller, there is no ambiguity in the idea that its methods must serve as the event handlers / listeners for input into the scheme: Controller.moveCircle().
Playing dumb for a minute, if there is only ever one Model, then you can simply go to one place to create all the data / state handling methods that you need. Right? (hehehe) ;-) Model.calculatePosition(), Model.calculatePrice()
In the most basic client-side / web scenario, if there is only ever one View, one might think just putting all presentation logic there could get the job done: View.repositionCircle(x, y), View.repositionTriangle(x, y)
Discussion 1
Why might a monolithic Controller, Model, or View scheme like this be problematic in the future?
Can I transfer individual screen elements and their behaviors to other "pages" without any hassle or extra baggage?
Coupling and Cohesion
Think coupling. Does a monolithic Controller loosely or tightly couple accessing screen targets?
Think cohesion. Does a monolithic Controller group behaviors / methods related to accessing an individual target strongly or weakly?
Would Controller.moveCircleUp() and Controller.moveTriangleUp() be dealing with accessing one screen target, or two?
In this case, broad questions like these about a monolithic Controller would also apply to monolithic models and views. A Model is most likely composed of several objects for doing and dealing with the data / state of various things, so there's generally less confusion about it's place.
Yet, if it is a monolith too, then it must deal with the data / state of all screen targets. Even with using multiple object properties and multiple methods in such a model, that could get messy.
Re-usability and Maintainability
What I have written about here cannot be good for code re-usability and maintainability. Even if you are no SOLID expert, it is easy to understand why monoliths tend to violate the Single Responsibility Principle. You should not be in the same place to change something about a circle, where you also make changes for a triangle.
Why? Think of it this way. You are floating in the ocean after your boat capsizes. It is you and another crewman. Would you rather be joined at the hip, so that if he loses consciousness, he or she takes you down too? No, you would want to be independent of the crewman so that you are free to sink or swim on your own.
If you are coupled at the hip, you might hit each other in the face or make some other error that would not have happened if each was a single floater.
In other words, it is better to operate independently and work together, than it is to be joined at the hip and try to accomplish the same things. It is not about when things go well. It is about when thing go wrongly, or when independence is preferable. For example, when one is able to grab a rope ladder dangling from a helicopter, but the other is getting gnawed on by a shark.
You want to be able to reuse application elements in different screens or applications altogether. This is why loose coupling and strong cohesion are fundamental to object-oriented programming, and programming generally.
(**Note: View does not mean HTML only, even if this is the most common end result. Other possibilities include SVG, XML, Canvas graphics, image formats ... anything that fits the circumstance.)
Second Fundamental Question
2) Should each crafted, actionable object / element / target on the screen have its own Controller, Model, and View?
In regular expression speak ...
Controller+ (one or more)
Model+ (one or more)
View+ (one or more)
Discussion 2
Do you want to use screen targets / elements on other pages / screens and bring their specific behaviors with them?
In the first scenario, there is a 1:1:1 relationship between Controller, Model, and View. They are monolithic. There is one screen / webpage. In that setup, you cannot take a circle and put it on another page / screen without bringing along the logic for triangle, too!
If the goal is to make code reusable in another context, then the answer is that each shape requires a self-contained MVC arrangement. Each target would have its own Controller, Model, and View.
In effect, this would mean each screen element that you designate worthy would know how to accept input from an event, process it, and show the output. Some how, we made it back to something that sounds rather fundamental.
Final Thoughts
If one accepts the the above as true, then shapes are, well, alive. :-) They are independent of the context. Manipulating them should not depend on the some all encompassing, JavaScript, FrontController, event handling overlord to be triggered first, only to delegate the work to a method of the target's individual Controller.
PHP MVC
Server-side PHP uses the FrontController scheme before getting to the desired Controller sub-class because if you have a single point of entry into the application (/index.php), you have to translate (route) the HTTP request (/contact/send) into an instance of a Controller, and call the desired method from that controller: ContactController->send().
Performance
The real issue here is how well will the application perform after having downloaded and loaded all of the JavaScript into a user-agent.
Answer? The more you have going on, the more memory you will use. If each screen element has a minimum of three (3) files for its Controller, Model, and View, then ten elements could mean thirty (files to download) at minimum.
Of course, other configurations are possible, but that is where a tool of some sort might come into handy to concatenate and minify everything. In JavaScript, I would rather develop one object per file.
I hope this helps!

Related

Pros/cons of view being responsible for reading/writing data

I have a view that I may use in any number of applications. It's a special viewer for a kind of data type. It contains a special reader for files that pertain to this data type and it can write them. What are the pros and cons of doing it this way? In a recent project, the MVVM proponents argued the view must be "dumb". This makes no sense because how can it be dumb if it is a narrowly specialized viewer? Is it possible that MVVM comes from the web world where viewers are simple? Anyway, the MVVM proponents also believed any data that goes into a view must be conditioned first e.g. converted to HTML, if the view is a webview. Seems like overkill. Why do that?
The concept of MVVM is to separate business logic (model) from view. In your case the reader writer should be in the model code. The Pro is that if you at any point want to make changes to the view side you can do so without changing or moving around code that does the actual data exchange (read write).
It also means that you can write tests against your model and if you change your view the model and test code will be left untouched.
Con with MVVM is that it adds some extra layer of code, it can add some development time (at least when one is new to MVVM) and in the beginning one may feel a bit locked by follow a pattern.
In the end I usually find the Pros to be bigger. One get a good and well thought through Design, separation of concerns for the codebase, easy to test different parts and the day you get a request for modifying or extending the control it will be much easier.

Cocoa MVC ≠ actual MVC?

Today I was getting some refresh about software design patterns.
In particular I was wondering about the difference between MVC and Three-tier-layer. Basically, from what I read on wikipedia and other sources, the main difference between the two is the components interaction:
A fundamental rule in a three tier architecture is the client tier
never communicates directly with the data tier;
whilst
...the MVC architecture is triangular: the view sends updates to
the controller, the controller updates the model, and the view gets
updated directly from the model
Now: if we take the apple docs regarding this matter we see this:
And they clearify that Views and Model shouldn't communicate directly:
view objects are typically decoupled from model objects in an MVC
application
and
When a model object changes (for example, new data is received over a
network connection), it notifies a controller object, which updates
the appropriate view objects
And so on.
So, what's the matter here? Is Cocoa adopting its own idea of an MVC, regardless of the common one? Or am I missing something in the common way of seeing an MVC architecture?
While it can be said that Cocoa's version of MVC is a sort of subset of the actual definition of MVC, they are not separate entities. The Cocoa version of MVC typically revolves around the use of a View (typically an NSWindow and/or an NSView), a controller (typically an NSWindowController), and a model layer (anything from a simple array to a Core Data stack). The separation of powers in this model is clear, but where in the 'tier' structure that Wiki defines should each of these belong?
I would argue that the Controller and the View are a part of the client layer. Not only is the controller responsible for the delegation between the model and the view, but it is responsible for responding to user events and determining the correct course of action to take during non-framework error handling. By taking this approach to MVC, you can now begin to see how Cocoa does, in fact, satisfy the broader definition of the pattern.
A fundamental rule in a three tier architecture is the client tier never communicates directly with the data tier;
This one's probably the hardest to reason about of the 3, and it involves delving into what "communication" actually means in the context of the pattern. When we say communication, what we mean is that the controller has no direct involvement in the actions taken by the model. That's not to say that the controller cannot order a change in the contents of the model, but rather that the controller does not have a hand in how the model updates itself. The controller acts as a director, not an implementer, which vastly simplifies the creation of a database layer, and is one of the reasons that Core Data and SQLite3 exist as external frameworks rather than as Foundation classes.
view objects are typically decoupled from model objects in an MVC application
That brings up one of the age-old taboos when programming with the pattern: making your views too smart. The controller provides a solid barrier between the model and view, such that the controller acts as a director and a filter for content from the model layer. Without any such barrer, say a tableview, would have to ensure that every cell had a copy of the data from the database, and that each cell knew when and how to update itself when a change is propagated in another cell. In Cocoa, this is where our NSWindowControllers come in. They manage the display of a root view and act as a barrier between some model and the content of the view it manages. Though, it is important to note that the controller objects in Cocoa are view-biased, mostly because it would be nearly impossible to provide a generic outlet to any kind of model layer without quite a bit of unnecessary glue.
When a model object changes (for example, new data is received over a network connection), it notifies a controller object, which updates the appropriate view objects.
That's the way it should be, for the reasons I've laid out above. But, to build on the networking example you've given, consider this:
Given an NSOperation that fetches data, and a controller that manages a tableview, you would probably not like the controller sticking its fat fingers into the operation, nor would you like the tableview to receive raw NSData and have to spend valuable rendering time processing the result and displaying it.
And so on. So, what's the matter here? Is Cocoa adopting its own idea of an MVC, regardless of the common one? Or am I missing something in the common way of seeing an MVC architecture?
I guess the conclusion I would draw from this is that your definition of the separation of powers in MVC and in how Cocoa does it is off. Cocoa is fairly rigid about adhering to the pattern, though there is an interesting contemporary movement within the Objective-C community towards MVVM.
You are correct the MVC practiced in most cocoa apps is not the MVC as it is defined in the text books. There are many variations of MVC employed by different frameworks. The MVC employed by tools with visual designers are heavily influenced by their visual designer implementation. With XCode you have story boards and nibs. The cocoa libraries and the way concerns are separated are influenced by this. If you want to take advantage of these tools, I would recommend understanding how concerns are separated by Xcode and work within this approach. Your code will coexist with it more smoothly. Apple documentation will help with this.
That being said, MVC is about separation of concerns. Separating concerns is hugely important in designing and maintaining software. Separating concerns properly can reduce dependency, reduce cyclomatic complexity, and make your code much more testable and maintainable. I think it is good that you are paying attention to this and whatever way you structure MVC should look to the reason why you are separating concerns as the guide to implementation.

What should my ASP.NET MVC Controllers represent - "real world" application

I have an established web application built as an ASP.NET 3.5 Web App. We recently modified it to mix MVC into the app for some new functionality.
Now that it's in there, we want to leverage MVC wherever possible to begin to "transform" the app from clunky webforms to a more maintainable and testable MVC app.
The question that just came up in adding some new functionality is what controller should be responsible for a certain action.
Let me be more detailed.
The scenario involves at least three major conceptual areas in our app. The app needs to be able to set their PREFERENCE for a default MAP view while they are on a SEARCH screen. Preferences, Maps and Search are all major concepts in our system. Furthermore, this preference setting (basically, where should the map start out) may be used to set the initial map in more than one search page (it's basically a search preference).
The existing MVC controller in the app is a MAPCONTROLLER, with 3 actions that are responsible for generating HTML or JSON data to put on a map.
What we need to do now, is add an MVC route (controller + action) to allow the client view to save some information as their preference. Basically, whenever they are on the search page looking at a map, they can click a button that says "remember this as my default map view", and from then on, their map will always start with that view.
My question is (and I apologize, but I wanted to be very very clear, I see too many questions with no context to help). What should my controller represent? I obviously have 3 major system areas involved. Would it be proper to create a new SEARCH or PREFERENCES controller with a SaveDefaultMapView action (no view required), or piggyback on the xisting MAP controller, even though this new function is more about search and preferences than actual map generation? Should an MVC controller be aligned mostly with the screen (search page/search subsystem), the domain / data being manipulated (preferences), or the very specific visual element under scrutiny at the time the action is taken (the map)?
All of the examples and bootcamp projects are all well and good, but they are far too clean and simplified to apply to a huge legacy app. How does one design their MVC components around a system that incorporates many domain concerns into a single webpage?
Thanks all!
There are no hard and fast rules for how the controllers are organized. You organize them the way it makes most logical sense to you. This will require a bit of experimentation as you see how the routing works out, and you find the cleanest, most elegant design.
ASP.NET MVC is brilliantly agnostic in this respect. It doesn't care how you design your controller/route substructure, and it is flexible enough to handle most any design.
Your application design should be heavy on the Model side. Your controllers should be relatively small; if you find that you are stuffing a large amount of logic in the controllers, you should refactor that logic to the model, or add a service layer to contain the logic. Your controller layer is best thought of as a "patch panel"; it is the place where you connect your incoming Urls via routes to your model/service layer and your View Model/Views.
You should definitely check out Project Areas, as this might be an appropriate mechanism to contain your three different system areas.
Thanks, Robert.
I guess I could rephrase a bit...what guidelines have others found to be useful for keeping their controller responsibilities organized and logical?
While my example above only touches 3 of our areas, I expect to eventually replace most/all of the application with MVC.
Furthermore, each of the 3 areas I mentioned has relationships to multiple other areas.(eg, maps can be used to plot several location-based entities, preferences can apply to any area of the system, and, like maps, is capable of searching for several kinds of business entities (one at a time, not all together).
So the lines are blurry. I'm interested in hearing how others have found workable guidelines for controller organization.
Oh, and at the very least, we are sticking to the skinny controller/fat model paradigm!

Separated Presentation on a UI Centric Application

I having trouble figuring out the correct architecture for this kind of application: it's a diagramming application, which resembles MS Visio. The diagrams are used to generated data which is passed to another application.
When designing applications, I've always tried to used layering, but now I can't decide how to do this when the data is so tightly coupled with the presentation. For example, a certain object in my canvas has a (X,Y) data, which is used for presentation purposes only, but has to be stored like domain data.
Where I'm getting things wrong? I'm pretty sure I'm looking at this from the wrong angle, but I can't figure out the right one.
Thanks again!
UPDATE:
I'm also aware that maybe I shouldn't be separating UI from domain in this case. If that is so, please provide me with some rational of when to apply separation and when not to.
In a diagramming tool the x/y position of a shape is part of the domain data (the location of the shapes is part of the diagram - you cant draw the diagram without it), the code that use those x/y coordinates and draw a shape on the screen is part of the presentation tier.
I know some people think that data that is only used for display should be saved separately, but in every project I've ever worked on that saved data separately this turned up to be a huge maintenance and support nightmare.
In a simple diagramming tool (if the tool just draws and edit the diagram without any fancy processing based on the diagram) there is no business logic, there's only the code that draws and edit the diagram (that belongs in the presentation tier) and the diagram data (that is the domain model).
If there is no business logic, by using a separate set of objects for domain and presentation you'll have to duplicate all your model data twice (once in the model objects and once in the presentation objects) and you won't get any advantages from separating the business logic from the presentation (because there isn't any).
On the other hand, if you do have some algorithms you run on the data you do have something to gain by separating the graph data from the drawing code - you can run the algorithm outside the tool, you can have better automated tests, etc.
also if you write another system that operates on the same data you can at least share the model definition and save/load code if you separate it from the drawing code.
So, let's summarize:
All the diagram data is part of the model (including data only used for presentation purposes).
Anything that draws to the screen or handles user input is in the presentation tier (obviously).
If those two cover all your code and data than your application don't have any "business logic" and the tier separation is probably overkill.
If you have any code that doesn't fit into those two categories and you think it should be part of the model than you should build the two separate tiers.
If there's any chance for code sharing between systems you should make sure the shared code is not mixed in with the presentation code.
And one last "bonus" point - if this is a project that's likely to be in active development for a long time with new features added in the future - you may want to separate the UI/data anyway just to make future work easier - you have to decide if this future saving is worth the extra time now and if this separation is really likely to help in the future.
I think you need to make sure you're keeping the what and the how separate. What you are displaying is abstract, sets of coordinates, shape types. How you're displaying it is very specific. I'd make sure the domain model dealt purely with the what and the view layer dealt uniquely with the how. It's hard to get into specifics though without knowing more about your app.
You could try to implement some kind of view model, which saves the current layout of your objects. This way, x/y values together with the id of the object are stored in a layout file while pure model data is stores elsewhere.
Maybe this helps a bit,

MVC for desktop app with no data layer

Question might be tricky (because of its nature or my way of describing it), so really read this before answering.
I have this app to write:
a) desktop app;
b) no data layer in sense of database, files or any other repository (no need to save, store or load data);
c) app will have some computation algorithms implemented (Genetic Algorithm);
b) provides GUI which will display controls for app and computations results.
I am thinking about using MVC pattern but I have doubts how to use it. Since I have no data layer in sense of (for example) database (data is generated during execution based on user input) I am concerned about way of using MVC in this implementation. So far I have came up with two approaches:
GUI is the View. GeneticAlgorithm is the Controller. GeneticAlgorithmResults is the Model (as class that only stores data). Basic flow:
The View sends user input to the Controller;
The Controller is processing user input and generates data;
The Controller sends generated data to the Model;
The Model notifies the View about new data;
The View pulls new Data and updates the display.
GUI is the View. AppEngine is the Controller. GeneticAlgorithm nad GeneticAlgorithmResults are the Model. Now we have:
The View sends user input to the Controller;
The Controller is processing user input and sends control signals to the Model.
The Model updates its internal state (generates new data);
The Model notifies the Controller about new data;
The Controller pulls data to model;
The Controller processes data;
The controller pushes processed data to the View;
The View updates the display.
First approach seems to be more straightforward and more like MVC. The problem is that some logic would have to be in the Model - decide when to notify the model as not all data updates will be displayed, or maybe display will be updated with the sets of data not every little change. Those decisions will be based on user input. Whats more some additional processing of the data may be needed before actual display. This would be in the View.
On the other hand second approach seems to be more complicated and looks like to much messages are being passed to achieve the task. But it gives full control of Logic to the Controller and separates responsibilities of the View, the Controller and the Model (which is the main purpose of MVC).
Which approach would you recommend? Or maybe I should mix them and use first approach architecture with communication flow from second approach? Or some different design?
From my understanding of MVC, the second version is more like the strict MVC paradigm. However, one of my very intelligent teachers once told me that the design patterns are there to give a loose set of guidelines and are not necessarily meant to be followed to the T.
In my opinion, a mix of both is a good idea. If some logic ends up in the Model, it isn't the end of the world, it just means that you have to be more careful about keeping track of the separation of your components. If a small modification to MVC makes your life 50% easier (less message overhead), then it is probably a good idea.
I would definitely go with something closer to the second implementation. Yes, it does seem like more messages passed back and forth, but if your application grows and changes, you will be happy that you've built the application with small classes.
Consider: Where is the logic to handle mundane tasks like switching between algorithms, executing them and processing the data for viewing?
Genetic algorithms operate on some kind of input or starting data, don't they? You would get this from your data access layer. Don't you need seed data or initialization conditions? What about saving your results to file and retrieving them for review later? I would think that you need to do this once your application matures. Expect that at first you will use file based persistence. If you're feeling up to it, later you can upgrade to a database. If you code against an abstracted data persistence layer, you won't have to change business logic later to support the change from file to database.
You should use the strategy pattern to implement your algorithms. This will allow you to change the implementation of your solver from genetic algorithm to your other algorithms without having to change the business logic for each algorithm.
The business layer will see a ISolver that takes inputs, and you will call mySolver.Solve(). You should be able to switch between the different versions without having to change your business layer logic (Open Closed Principle). The only difference in the way the business logic should interact with the algorithms should be in the constructor, and even there, you should consider using a Factory pattern.

Resources