I've been reading and learning about Object-Oriented programming (Head First Object-Oriented Analysis and Design and Code Complete: A Practical Handbook of Software Construction – thanks to suggestions found on StackOverflow). I've also been learning how to use a couple PHP MVC frameworks (specifically Codeigniter and Kohana).
Some of the principals of Object-Oriented that I've read about are handled differently by the MVC frameworks. I think I've managed to understand the differences and why the decisions were made (complete and easy to use solution), but I wanted to test my assumptions...so if you'll humour me...please comment or correct.
Assumption #1:
Thinking about the right abstraction for a web application, the directory containing the library of classes should be located outside of the directory containing the presentation files. This organization adheres to the DRY ("Don't Repeat Yourself") principal allowing for multiple presentation folders (www.domain.com, management.domain.com, api.domain.com, etc.) to work with the same objects.
Assumption #2:
If all your classes are located outside of your presentation folders, then the models in your MVC implementation just use instances of those classes. If that's true, then the MVC framework is just a presentation class (the controller) that helps to manage the input (GET & POST requests), the response (models or instances) and output (views or templates).
Assumption #3:
If the MVC framework is just a presentation class, then the database class that the controller instance initializes breaks the abstraction of the controller class. A model (of the controller instance) shouldn't have a ("has a") database, it should have a thing (user, product) from the library of classes and that thing should have a database.
Assumption #4:
Furthermore, if the MVC framework is just a presentation class, the database class that the controller instance initializes is too tightly coupled with the controller class. Changing from one method of storage to another requires re-factoring of all the models.
Assumption #5:
With a HMVC framework, the issues with the controller containing the database is worse, because your models are more module (more models, more re-factoring).
UPDATE:
Sorry, I may have used the terms controller and model a little loosely...maybe that speaks to the tight coupling. The source of my confusion stems from the database class syntax.
With a model, shouldn't it be:
$user = new User($id);
$data['name'] = $user->getName();
$data['title'] = $user->getTitle();
return $data
Instead of:
$query = $this->db->get_where('user', array('id' => $id), 1, 0);
$row = $query->row_array();
$data['name'] = $row['name'];
$data['title'] = $row['title'];
return $data
Assumption #1: Thinking about the right abstraction for a web
application, the directory containing
the library of classes should be
located outside of the directory
containing the presentation files.
This organization adheres to the DRY
("Don't Repeat Yourself") principal
allowing for multiple presentation
folders (www.domain.com,
management.domain.com, api.domain.com,
etc.) to work with the same objects.
This is correct in the sense that libraries are not used for presentation (i.e. not views). They are modules that will be used across multiple controllers. Usually they should not use persistent data since they are not models but in some cases do (codeigniter sessions for example).
Assumption #2:
If all your classes are located
outside of your presentation folders,
then the models in your MVC
implementation just use instances of
those classes. If that's true, then
the MVC framework is just a
presentation class (the controller)
that helps to manage the input (GET &
POST requests), the response (models
or instances) and output (views or
templates).
This is a little confusing to me. You are correct the the controller is just used for orchestration of GET and POST request but becareful about calling then the "presentation class". the controller is responsible for the orchestration of models (persistent data) and views (presentation of data).
Assumption #3:
If the MVC framework is just a
presentation class, then the database
class that the controller instance
initializes breaks the abstraction of
the controller class. A model (of the
controller instance) shouldn't have a
("has a") database, it should have a
thing (user, product) from the library
of classes and that thing should have
a database.
This is very confusing and I don't really understand what you're saying here. MVC is a just a "presentation class", a model doesnt have a "database", the framework may hold a connection to a database and models are abstractions of the database (object like user, product).
Assumption #4:
Furthermore, if the MVC framework is
just a presentation class, the
database class that the controller
instance initializes is too tightly
coupled with the controller class.
Changing from one method of storage to
another requires re-factoring of all
the models.
The controller doesn't initialize the database, the framework usually handles controllers only access the abstraction of the database (models). If the database system is replaced by anything only the implementation of the models interface is re-factored.
Assumption #5:
With a HMVC framework, the issues with
the controller containing the database
is worse, because your models are more
module (more models, more
re-factoring).
HMVC doesn't necessarily mean more models. Using HMVC allows for portable modules from a project that can be access across multiple controllers. Often you will see Libraries doing this in non HMVC frameworks ie Library that doesn't some db/templating.
UPDATE: Just wanted to answer/comment on my confused question.
Kohana provides a Modules folder that addresses my earlier concerns.
For example, if you were to setup a domain, with a subdomain, using Plesk, the folder structure would be the following.
httpdocs
subdomains
+--management
+--httpdocs
If you want to share code between the domain and subdomain, using Kohana's modules, you could setup your file system like this:
modules
system
httpdocs
+--application
+--index.php
subdomains
+--management
+--httpdocs
+--application
+--index.php
Where httpdocs/index.php and subdomains/management/httpdocs/index.php has the following:
$application = 'application';
$modules = '/root/pathto/modules';
$system = '/root/pathto/system';
Any objects that are used in both the domain and the subdomain can be placed in the modules folder to be used by the application.
Hope that helps.
Related
Wikipedia says:
MVC provides front and back ends for the database, the user, and the
data processing components. The separation of software systems into
front and back ends simplifies development and separates maintenance.
I still don't see the link between the model-view-controller principle and the idea of front- and backend. Can the Model with its access to the database be seen as the Backend and the View as the frontend?
OK.. first the terms:
Frontend - are the parts, which are visible to users: HTML, CSS, client-side Javascript. It all is basically "frontend". In a desktop application frontend would be the GUI.
Backend - is the invisible part. In web applications that is your java, ruby, php or any other serverside code. It can be either interpreted or compiled, because "how" it works has no impact on "what" it is.
If you read GUI Architectures and research the MVC pattern in general, you will understand that MVC is not about separation of backend and frontend. Especially when it comes to MVC-inspired patterns, that we use for web applications.
The goal of MVC and related patterns is to separate presentation from domain business logic.
Here are the basic responsibilities of MVC parts:
Model - business logic
View - presentation logic
Controller - changing state of model and view (based on user input)
Let's take an example:
alternative client application for twitter
uses OAuth for authentication
user can input different search phrases
takes information via Twitter's REST API
validates data
parses the JSON responses
manipulates DOM to present the information
This all can be done with client-side JavaScript. You can have MVC triad running "frontend"! At the same time, the "backend" which provides REST API is an MVC-like structure. Only this time the View is generating JSON responses, instead of HTML.
*Conclusion: You can use MVC pattern both on backend and frontend.**
Post Scriptum
Since you have been building some applications with Rails, your understanding of MVC might be a but distorted. The reason I say this is because, since RoR was initially made as a prototyping framework (notice all the scaffolding and other features for generating throw-away code), and because of its origin, Rails is actually implementing a very anemic version of MVP.
I call it "anemic", because they nerfed both View (it should be a passive object in MVP, not a simple template) and Model Layer (yes, it is supposed to be a complicated layer, not a collection of ORM instances).
I would recommend for you to read two publications to get a much better grasp on the subject:
Patterns of Enterprise Application Architecture.. mandatory reading for serious developers
A Description of the Model-View-Controller User Interface Paradigm in the Smalltalk-80 System
The second one is as close as you can get to initial definition of pattern. That, together with "GUI Architectures" article, should provide you a solid footing on the subject. And the PoEAA book (hard read, btw) would give you context in which to expand it.
Maybe the figure below can help..
MVC Human language
--------------- ---------------
model -> data
controllers -> actions
views -> GUI
In very simple applications you end up with models being the database, views the HTML (or GUI for desktop applications) and controllers just the code linking the two.
However with today's complex web applications you can have an MVC framework both at backend (Django) and frontend (React, Angular). So it's all relative.
In backend:
MVC backend
--------------- ---------------
model -> database
controllers -> glue code (from user or framework)
views -> exposed API
In frontend
MVC frontend
--------------- ---------------
model -> data structure (in sync with what is received from backend)
controllers -> glue code (from user or framework)
views -> HTML
Bottom line: You can apply MVC anywhere where you want to decouple complexity
The front end is what the user sees which are the views. The back end are the controllers and the model.
views = frontend
models = backend
controllers = glue between frontend and backend
In this case, backend traditionally means the deeper OS code or even your code that is not being seen/controlled by the user.
The frontend is the actual view being seen by the user.
I assume your question is in reference with M-V-C being used in developing full stack.
Front end : View pages;
Back end : Controller, Model
I am working on a business application which is being developed from scratch. We have opted to design our business logic using Entity Framework, and since the application has to be delivered on the Web we have selected MVC 3 (Razor) for presentation.
Things are pretty fine yet, but I am afraid how will I manage if anytime in the future we need to change our Entity Classes (like adding/removing fields in the business entities or adding more relational entities etc.). I know I can update my model by selecting "Update Model from Database" in Visual Studio (we are using Database first approach). In this case will I have to scrap my old views and generate new ones or is there any way I can update my exiting views.
That questions a little ambigous, so I'll talk about MVC concepts
The whole approach of MVC is "serperation of concerns" so you should be able to lititimatly change your Model (database, entity Framework, etc.) without updating your controllers or views.
That said your model's responsibillity is to return the data required by the controller/view. So it needs to be consistant. So if you model is bound to a view that return data x, if this view is updated, moved to a new platform, etc, etc then the model should still return the same basic information (for it to continue to work with your existing views/controllers).
If your using code first then you should be able to generate any required db views, etc. on a new db, providing this db supports code first generation (so basically MS-SQL I believe)
When using Editor- or DisplayFor you can pass in the entire model and it will show all the properties on the model.
I'm working on some new software, and I'm trying to make it as modular as possible. I have been coding for a while..but I lack some key principles which I am learning as I go along.
In trying to make my current project modular, I am using the model-view-controller architecture. In designing my application, I have found certain things I am unsure of. So I come to you...
I'll give you some information which may be useful:
I am developing this application in Qt.
It is a desktop application.
Single user, so it is not very complicated
My questions are:
When implementing the various modules(models, views etc..) and all
of the classes associated with them, should I be initializing
modules within modules? Should I create a 'model' instance within a
'controller', or should I create everything in 'MAIN' and simply
pass the modules as references?
My strategy is to separate my application into many MVC bundles.
Each one will follow the basic principles: model gets the data, view
displays it, and controller takes care of all interactions between
model-view, and performs all required logic. Is this correct?
I appreciate all of your help.
Thanks.
Should I create a 'model' instance within a 'controller', or should I create everything in 'MAIN' and simply pass the modules as references?
Pass the modules as references. I don't know if Qt has the concept of packages within a bundle, but in Java, I have separate packages for the model and the view.
My strategy is to separate my application into many MVC bundles. Each one will follow the basic principles: model gets the data, view displays it, and controller takes care of all interactions between model-view, and performs all required logic. Is this correct?
Yes, that's correct MVC principles.
Sometimes in a more complicated application, your application view might consist of the GUI (a view) and a model of the GUI (a model). In this case, the application model, which is probably a database access model, interacts with the GUI model. The controller for both the GUI and the application is driven by the actions of the user.
I'd just like to get some clarification in the MVC pattern as to what belongs in Models, specifically the contents of the Models folder in MVC3, versus repositories and objects.
Right now, in my current MVC3 Solution, I have 4 projects:
A Project called "Objects", which holds information about all the core objects in my application.
A Project called "Data" which holds information information about the Data Context and repositories for each of the objects (created using MVC3 scaffolding)
The Web project, which holds the Controllers, Views, and -- the subject of this question -- Models
A Unit Testing project
What I really would like to get clarification about is the difference between what should go in the Objects project vs. what goes in the Models folder of the web project. Right now I'm only using the Models folder for holding what I'd call "View Models", which typically contain combinations of the core objects. Should the files in this folder only contain definitions defining the model contents, or should it contain other code that the controller may call?
I think that I have a pretty good understanding of both controllers and repositories, but sometimes I get confused as to whether certain code should go in one or the other. Are there any specific guidelines or limitations out there as to what absolutely should NOT go in a controller but should go in either a repository or a model instead?
Thanks as always.
We do something very similar except that the Objects and Data are combined in a Core library which is referenced by all projects. The models folder in the MVC project is strictly for View Models.
If your controller require additional classes, it really depends on what it needs as to where it goes. I will typically include a Helpers folder with subfolders for HtmlHelpers, Attributes and Filters. If it's a dependency that makes sense to exist outside the MVC project (common classes which are used across all projects) I'll add it to Core.
In MVC, do controllers belong with an application, or can they go into a shared library? For example:
//this is a shared library
LibShared
//these are two apps
appA ->LibShared
appB ->LibShared
Shouldn't each app implement its own MVC and use any shared libraries as perhaps part of the app's logical model or simply another library reference (utilities)?
Also, is there ever a situation in which an MVC Controller is stuck in a shared library? I thought Controllers needed specific views located in a specific app. Meaning, the Controller must go in that app?
Or can Controllers be generic (i.e. shared library)? Doesn't that mean they are no longer Controllers?
I would advise that you should only be separating out your controllers into their own module/package/library (herein referred to as modules) if you have a requirement to do so (i.e. immediate re-use). If no such requirement exists at present then I would defer the decision to when it is required, it sounds in your case you are about to unnecessarily over-engineer. It should in theory be possible to refactor later to a separate modules without much hindrance, however be careful regarding coupling, separating out to different modules doesn't reduce the coupling, look carefully at your dependencies at how much the controller is orientated to one style of view.
one liners answers to your question to your application is
YES, YOU CAN MOVE YOUR CONTROLLER TO A SEPARATE LIBRARY WITHOUT A SINGLE LINE CODE CHANGES.
I suppose any code can go anywhere, what would drive us to put something in a shared library or keep it with the app?
I would consider two things:
1). What's the rate of change? When we change the app overall is this likely to change.
2). Could anything else need to use it? If so when I realease a new version would the other client immediately
Typically a controller would be strongly associated with the application and hence not of much interest to any other app, and it's probably fundamental to the app changing as the app changes. Hence packaging with the app makes sense.
Now if the conroller is somehow more generic, perhaps configuration driven then shared library makes sense.
Controllers does not necessarily needs to be even in the same operating system. You could have a view in Windows, a Controller in Unix and your Model in a Sparc. Remember MVC is just a pattern, a way you could do something which is more robust and easier to modify.
Your controller could be a shared library. Does your controller should be aware of your views? Not necessarily. That depends on how you handle the communication between modules. On a good MVC implementation, modules simply interchange messages or events. So, a View send an event to the Controller, the Controller decides what to do and send a message back. The response of the controller could be something like "Show Window X". Be advised that "Window X" could be interpret by the View module, if the View is an a Web module, then the View just put the proper aspx page. If you have another view who happens to be a web application the renders Form X.
At least in CakePHP and in the architecture that Mike McShaffry explains in his Game Coding Complete book the controller does belong to the application.
However, in both cases the architecture is such that the application inherits the basic functionality of a model, view, and a controller from the framework.
Eg.:
// "super" controller of all applications using this framework
class Controller
// uses basic libraries that allows the inheriting applications to work minimally
class AppController extends Controller
// mainly uses the parent class's methods but can also substitute to using
// additional libraries
By framework here I mean the system that encapsulates the use of libraries. In CakePHP this encapsulation in turn is done by using libraries in the respecting models, views, and controllers. So neither of those components is free from attachment to libraries.
In Mike McShaffry's architecture however, only the controllers and views use libraries. So the models are left uncoupled and are thus highly portable to different applications.