I am new to MVC but I can already see its benefits and advantages. However, I have a (probably easy to answer) design question:
I have been thinking about models and debating the proper way to structure them. The way I see it there are a few options:
1) Models and table structure have a 1 to 1 relationship...meaning that pretty much for every table there is a corresponding model. The model class has attributes corresponding to the table columns and has whatever methods that are needed (like getters and setters) to manipulate data in the table in whatever way is necessary. This seems like the generic option and I guess I would then have the controller call the models as necessary to perform whatever business function is necessary.
2) Models are tied more closely to the operation of the business logic rather than the data: so for example if on the front end a deletion of a certain object affects multiple tables, the model then 'models' this behavior and interacts with several tables and performs the necessary function. The controller then simply needs to call a single model for whatever business behavior is desired. This is less generic since the models are much more tightly coupled..but seems quicker to implement.
3) Something in between the first 2 options. Or maybe I am completely missing the point.
Hopefully this makes sense! If I am not totally missing the point, I am inclined to think that option (1) is better. Any idea?
Edit: Not that it should matter, but I plan on using Codeigniter PHP MVC framework.
Both are valid implementations, and, depending on your needs, can work well.
Your #1 is essentially describing the Active Record pattern, which is used by SubSonic, Castle, and lots of other ORM implementations.
Your #2 is essentially describing the Entity Framework/Hibernate/LightSpeed approach, where you are dealing with objects that are more conceptually related to your domain rather than to tables. Instead of your objects containing foreign key ID properties, they actually contain the other domain object references, which are then instantiated in an on-access basis.
Both ways are great. The Active Record approach is usually more intuitive for beginners and has potentially less pitfalls. EF-style can save a lot of base-level coding and dealing with FK's directly in code.
Edit: To be clear, what you describe in both situations is data access layer related, rather then strictly model related. However in reality you're pretty close, as most models tend to simply represent one or more of these types of objects.
All of the above.
The approach you use depends on your design philosophy. If you prefer to design your application using business domains and drive that into the database design, then you favor the second approach. If you prefer to build your database first, and then create model classes from the database schema, then you favor the first approach. Both methods are valid ways to build software.
Number 1 is the way to go. Option 2 is really the controller's job. For example, the controller then takes the models and performs actions on them, and passes the results to the view.
Think of it this way:
Model = your data
Controller = business logic
View = display of data and actions
This is highly simplistic, but it's how I picture it in my mind when I go to design a system.
Think of the database as the Model, the business logic as the Controller, and the UI as the View. That may help. It's an overly simplified approach to things, but it gets the data / behavior separation roughly correct.
I don't think it has to be an either/or situation. Your first point is what would be called a Model, but your 2nd point sounds like a View Model, which is most often a composition of various Models and parts of Models that will be sent to the view. The controller is responsible for doing that composition and potentially decomposition when information is sent back from the View.
Related
Until now, in my MVC application, I've been using the Model mainly just to access the database, and very little else. I've always looked on the Controller as the true brains of the operation. But I'm not sure if I've been correctly utilizing the MVC model.
For example, assume a database of financial transactions (order number, order items, amount, customer info, etc.). Now, assume there is a function to process a .csv file, and return it as an array, to be inserted into the database of transactions.
I've placed my .csv parse function in my Controller, then the controller passes the parsed information to a function in the Model to be inserted. However, strictly speaking, should the .csv parsing function be included in the Model instead?
EDIT: For clarity's sake, I specifically am using CodeIgniter, however the question does pertain to MVC structure in general.
The internet is full of discussion about what is true MVC. This answer is from the perspective of the CodeIgniter (CI) implementation of MVC. Read the official line here.
As it says on the linked page "CodeIgniter has a fairly loose approach to MVC...". Which, IMO, means there aren't any truly wrong ways to do things. That said, the MVC pattern is a pretty good way to achieve Separation of Concerns (SoC) (defined here). CI will allow you to follow the MVC pattern while, as the linked documentation page says, "...enabling you to work in a way that makes the most sense to you."
Models need not be restricted to database functions. (Though if that makes sense to you, then by all means, do it.) Many CI developers put all kinds of "business logic" in Models. Often this logic could just as easily reside in a custom library. I've often had cases where that "business logic" is so trivial it makes perfect sense to have it in a Controller. So, strictly speaking - there really isn't any strictly speaking.
In your case, and as one of the comments suggests, it might make sense to put the CSV functionality into a library (a.k.a. service). That makes it easy to use in multiple places - either Controller or Model.
Ultimately you want to keep any given block of code relevant to, and only to, the task at hand. Hopefully this can be done in a way that keeps the code DRY (Don't Repeat Yourself). It's up to you to determine how to achieve the desired end result.
You get to decide what the terms Model, View, and Controller mean.
As a general rule MVC is popular because it supports separation of concerns, which is a core tenet of SOLID programming. Speaking generically (different flavors support/ recommend different implementations), your model holds your data (and often metadata for how to validate or parse), your view renders your data, and your controller manages the flow of your data (this is also usually where security and validation occur).
In most systems, the Single Responsibility Principle would suggest that while business logic must occur at the controller level, it shouldn't actually occur in the controller class. Typically, business logic is done in a service, usually injected into the controller. The controller invokes the service with data from the model, gets a result that goes into the model (or a different model), and invokes the view to render it.
So in answer to your question, following "best practices" (and I'll put that in quotes because there's a lot of opinions out there and it's not a black and white proposition), your controller should not be processing and parsing data, and neither should your model; it should be invoking the service that processes and parses the data, then returning the results of aforementioned invocation.
Now... is it necessary to do that in a service? No. You may find it more appropriate, given the size and complexity of your application (i.e. small and not requiring regular maintenance and updates) to take some shortcuts and put the business logic into the controller or the model; it's not like it won't work. If you are following or intend to follow the intent of the Separation of Concerns and SOLID principles, however (and it's a good idea on larger, more complex projects), it's best to refactor that out.
Back to the old concept of decomposing the project logic as Models and Business Logic and the Data Access Layer.
Models was the very thin layer to represent the objects
Business Logic layer was for validations and calling the methods and for processing the data
Data Access Layer for connecting the database and to provide the OR relation
in the MVC, and taking asp.net/tutorials as reference:
Models : to store all the object structure
View: is like an engine to display the data was sent from the controller ( you can think about the view as the xsl file of the xml which is models in this case)
Controller: the place where you call the methods and to execute the processes.
usually you can extend the models to support the validations
finally, in my opinion and based on my experience, most of the sensitive processes that take some execution time, I code it on the sql server side for better performance, and easy to update the procedures in case if any rule was injected or some adjustments was required, all mentioned can be done without rebuilding your application.
I hope my answer gives you some hints and to help you
If your CSV processing is used in more than one place, you can use a CI library to store the processing function. Or you can create a CSV model to store the processing function. That is up to you. I would initially code this in the controller, then if needed again elsewhere, that is when I would factor it out into a library.
Traditionally, models interact with the database, controllers deal with the incoming request, how to process it, what view to respond with. That leaves a layer of business logic (for instance your CSV processing) which I would put in a library, but many would put in its own model.
There is no hard rule about this. MVC, however it was initially proposed, is a loose term interpreted differently in different environments.
Personally, with CI, I use thin controllers, fat models that also contain business logic, and processing logic like CSV parsing I would put in a library, for ease of reuse between projects.
In our new project we decided to use hexagonal architecture. We decided to use repository pattern to gain more data access abstraction. We are using command bus pattern as service layer.
In our dashboard page we need a lot of data and because of that we should use 3 level many to many relations (user -> projects -> skills -> review) and also skills should be active(status=1).
The problem rises here, where should i put this?
$userRepository->getDashboardData($userId).
2.$userRepository->getUser($userId)->withProjects()->withActiveSkills()->withReviews();
3.$user = $userRepository->getById();
$projects = $projectRepository->getByUserId($user->id);
$skills = $skillRepository->getActiveSkillsByProjectsIds($projectIds);
In this case, I couldn't find the benefits of repository pattern except coding to interface which can be achived with model interfac.
I think solution 3 is prefect but it adds a lot of work.
You have to decide (for example) from an object-oriented perspective if a "User" returned is one that has a collection of skills within it. If so, your returned user will already have those objects.
In the case of using regular objects, try to avoid child entities unless it makes good sense. Like, for example.. The 'User' entity is responsible for ensuring that the child entities play by the business rules. Prefer to use a different repository to select the other types of entities based on whatever other criteria.
Talking about a "relationship" in this way makes me feel like you're using ActiveRecord because otherwise they'd just be child objects. The "relationship" exists in the relational database. It only creeps into your objects if you're mixing database record / object like with AR.
In the case of using ActiveRecord objects, you might consider having specific methods on the repository to load the correctly configured member objects. $members->allIncludingSkills() or something perhaps. This is because you have to solve for N+1 when returning multiple entities. Then, you need to use eager-loading for the result set and you don't want to use the same eager loading configuration for every request.. Therefore, you need a way to delineate configurations per request.. One way to do this is to call different methods on the repository for different requests.
However, for me.. I'd prefer not to have a bunch of objects with just.. infinite reach.. For example.. You can have a $member->posts[0]->author->posts[0]->author->posts[0]->author->posts[0].
I prefer to keep things as 'flat' as possible.
$member = $members->withId($id);
$posts = $posts->writtenBy($member->id);
Or something like that. (just typing off the top of my head).
Nobody likes tons of nested arrays and ActiveRecord can be abused to the point where its objects are essentially arrays with methods and the potential for infinite nesting. So, while it can be a convenient way to work with data. I would work to prevent abusing relationships as a concept and keep your structures as flat as possible.
It's not only very possible to code without ORM 'relationship' functionality.. It's often easier.. You can tell that this functionality adds a ton of trouble because of just how many features the ORM has to provide in order to try to mitigate the pain.
And really, what's the point? It just keeps you from having to use the ID of a specific Member to do the lookup? Maybe it's easier to loop over a ton of different things I guess?
Repositories are really only particularly useful in the ActiveRecord case if you want to be able to test your code in isolation. Otherwise, you can create scopes and whatnot using Laravel's built-in functionality to prevent the need for redundant (and consequently brittle) query logic everywhere.
It's also perfectly reasonable to create models that exist SPECIFICALLY for the UI. You can have more than one ActiveRecord model that uses the same database table, for example, that you use just for a specific user-interface use-case. Dashboard for example. If you have a new use-case.. You just create a new model.
This, to me.. Is core to designing systems. Asking ourselves.. Ok, when we have a new use-case what will we have to do? If the answer is, sure our architecture is such that we just do this and this and we don't really have to mess with the rest.. then great! Otherwise, the answer is probably more like.. I have no idea.. I guess modify everything and hope it works.
There's many ways to approach this stuff. But, I would propose to avoid using a lot of complex tooling in exchange for simpler approaches / solutions. Repository is a great way to abstract away data persistence to allow for testing in isolation. If you want to test in isolation, use it. But, I'm not sure that I'm sold much on how ORM relationships work with an object model.
For example, do we have some massive Member object that contains the following?
All comments ever left by that member
All skills the member has
All recommendations that the member has made
All friend invites the member has sent
All friends that the member has established
I don't like the idea of these massive objects that are designed to just be containers for absolutely everything. I prefer to break objects into bits that are specifically designed for use-cases.
But, I'm rambling. In short..
Don't abuse ORM relationship functionality.
It's better to have multiple small objects that are specifically designed for a use-case than a few large ones that do everything.
Just my 2 cents.
I've worked with OOP for a while now, and have gotten into the habit of creating classes for 'things', such as person, account, etc. I was coding in Java for this.
Recently I begun to work with MVC (in PHP), and I've come to realise that, contrary to what I originally thought, the model is not like an OOP class - feel free to correct me if I'm wrong, but my understanding is that the model is simply an interface between the controller and the database (maybe with data processing - more on this below). My reason for thinking this stems from my recent messing around with the CodeIgniter framework for PHP. CI doesn't allow for instances of models. Rather, it's a singleton pattern, and in most tutorials I've seen, it's used only for database queries and sometimes some static method.
Now, coming from OOP, I've gotten into the habit of having classes where the data is stored and able to be manipulated (an OOP class). My issue is that in MVC, I'm not sure where this takes place, if it does (I initially thought 'class' was synonymous with 'model'). So, I guess what I'm looking for is someone to explain to me:
Where does the manipulation of data (business logic) take place? I've read many articles and posts, and it seems some prefer to do it in the controller, and others in the model. Is one of these more correct than the other in terms of MVC?
Where/how do I store data for use within my application, such as that from a database or JSON/XML files returned from an API call? I'm talking things that would usually be attributes in an OOP class. Does this even still take place, or is it straight from the database to the view without being stored in variables in a class?
If you could link me to any guides/sites that may help me to understand this all better, I would appreciate it.
Representing MVC in terms of classes, you can say that:
Model - A class which stores/provides data.
View - A class which provides functionality to display the provided data in a particular fashion.
Controller - A class which controls that how the data is manipulated and passed around.
MVC design is adopted to provide facility to easily replace any of the module (Model/View/Controller) without affecting the other. In most cases, it is the view which gets changed (like same data represented in form of graphs, chats) but other modules must also be made independent of others.
This is an interesting question, and you often hear contrary things about how clean and stripped down models should be vs them actually doing everything you'd think they should do. If I were you I'd take a look at data mappers. Tons of people much smarter than I have written on the subject, so please do some research, but I'll see if I can summarize.
The idea is that you separate out your concept of a model into two things. The first is the standard model. This simple becomes a property bag. All it does is have a state that often reflects your database data, or what your database data will be once saved, or however you use it.
The second is a data mapper. This is where you put the heavy-lifting stuff. It's job becomes providing a layer between your pure model, and the database, that's it. It talks to the database, retrieves data specific to your model, and maps it to the model. Or it reads the model, and writes that data to the database. Or it compares the model's data with that of the DB.
What this does is it allows each layer to concern itself with only one thing. The model only has to keep a state, and be aware of its state. Or have some functionality related to the model that does not involve the database or storage. Now the model no longer cares about talking to the database which is hugely freeing! Now if you ever switch to a different database, or you switch to cookies or storing things in files or caching or any other form of persistence, you never need to change your models. All you have to change is the mapping layer that communicates between your models and the DB.
I'm new in this, so bear with me. I've been using one MVC framework in a couple of projects lately, and after a while, I'm disillusioned in the perceived usefulness of the 'Model' in MVC.
I get the usefulness of Controllers and Views, I know that separation between presentation and logic is important to make the code more maintainable in the future, although not necessarily faster or more robust.
If all logic should be placed inside the controller in the first place, I don't see any use for Model, especially the Active-Record. We already have a language that is so robust and easy to use to communicate with the database, am I right? It's called SQL. For me when models are implemented like active-record, it's usefulness depends on whether or not you want your app to fit in multiple databases.
So what I'm asking is, if you're only using one database, why bother with Models and Active-Records? Why don't just use SQL? Why the extra layer of complexity? Do you guys have any case studies/real-life stories where models actually can do things better than just using the database class and SQL-away?
Again, I'm sorry if I seem to be so ignorant, but I really don't know why Models are important. Thanks for answering.
First, you are assuming that a model layer necessarily uses some kind of ORM, in order to abstract SQL away. This is not true: you may create a model layer which is loosely-coupled from the Controller layer but tightly-coupled to a particular DBMS, and so avoid using a full-featured ORM.
There are some ORM libraries, like Hibernate (Java), NHibernate (.NET), Doctrine (PHP) or ActiveRecord-Rails (Ruby) that really can generate all actual SQL statements for you; but if you think ORM is unnecessary, and you want to define all SQL statements by hand, don't use them.
Still, IMHO this does NOT mean you should just place all you DB related logic inside the controller layer. This is called the "fat controller" approach, and it is a road that leads, many times, to bloated, unmaintainable code. You could use it for simple CRUD projects, but anything beyond that will demand the existence of a real "Model".
You seem to care about MVC. Please, read also something about TDD. A wise man once said "legacy code is code without tests". When you learn that automated unit tests are as important as the "real" code, you will understand why there are so many layers in an enterprise application, and why your Model layer should be separate from the Controller. A block of code that tries to do everything (presentation, business logic, data persistence) simply cannot be easily tested (nor debugged by the way).
Edit
"Model" is a little bit fuzzy term. Depending from where you look at, it can mean something slightly different. For instance, PHP e Ruby programmers frequently use it as a synonym to an Active Record, which is not accurate. Some other developers seem to believe that a "model" is just some kind of DTO, which is also not right.
I rather use the definition of model as seen in Wikipedia:
The central component of MVC, the model, captures the application's behavior in terms of its problem domain, independent of the user interface. The model directly manages the application's data, logic and rules.
So the Model is the biggest, most important layer in most MVC applications. That's why it is usually divided in sub-layers: Domain, Service, Data Access and so on. The Model is usually exposed through the Domain, because it's there where you'll find the methods that your controller will call. But the Data Access layer belongs to the "Model" too. Anything that is related to data persistence and business logic belongs to it.
In most real-life situations, data that comes from the user doesn't go straight into the database.
It must often be validated, filtered, or transformed.
The role of the model layer is usually to make sure that data arrives properly into the backend store (usually the database) by performing these operations, which should not be the responsibility of the controller (skinny controller, fat model), and not the responsibility of the database engine itself.
In other words, the Model layer is responsible - or `knows' - how the data should be handled.
Most modern MVC frameworks provide ways to specify contracts over the data validity requirements, such as Rails.
Here's an example from http://biodegradablegeek.com/2008/02/introduction-to-validations-validation-error-handling-in-rails/:
class Cat
validates_inclusion_of :sex, :in => %w(M F), :message => 'must be M or F'
validates_inclusion_of :vaccinated, :in => [true,false]
validates_inclusion_of :fiv, :in => [true,false]
validates_inclusion_of :age, :within => 1..30
validates_each :weight do |record, attr, value|
record.errors.add attr, 'should be a minimum of 1 pound' if value and value /^[01][0-9]\/[0-9]{2}\/[0-9]{4}$/
validates_length_of :comment, :allow_blank => true, :allow_nil => true, :maximum => 500
end
Here, several of the data validity requirements cannot be handled by the database, and should not be handled in controllers, because any modification in those requirements might break the code in several places.
Therefore, the model is the best place to make sure data is coherent for your domain.
There's a lot more to be said about it, but I felt like tackling a point that seems important to me, motivated by practical experience :)
It's not an ignorant question at all! Just the fact that you're asking it instead of simply ignoring the whole MVC theory and doing as you please is nice. :-)
To answer your question: conceptually, Models simply provide a nice abstraction for your data. Instead of thinking in terms of "how do I write this inner join to get all the fields I need", models enable you to think in terms of "how are my application's objects related to each other, how do they interact and how can I get the data I need from them".
In the same way that Views and Controllers help you seperate presentation from logic, Models help you seperate the application's logic (from a user's perspective, anyway) from the gritty details as to where your data actually comes from and how it's represented internally.
To give a more specific example (if not completely realistic): in theory, you could write your whole application in a way you fetched all the data through SQL queries. But later you realized you wanted to use some noSQL (CouchDB, etc) engine because you needed horizontal scaling.
With models (and a framework that can use both types of storage, of course :-)) you wouldn't have to worry about the details, as all your important data is already represented in a generic manner through your models and both views and controllers can act upon that representation.
Without them, you'd probably have to rewrite a large chunk of code just to adapt your data fetching to the new backend.
And that's just on the boring storage part. With pure SQL, it's much harder to define the interactions between your application's objects (i.e. the business logic) because you just won't do that in SQL (probably, anyway).
It's not a perfect explanation (far from it), but I hope it helps.
The models should contain all your logic. The controller is only responsible with logic related to user interaction. All the domain-related functionality (what's known as "business logic") should be placed in the model and decoupled from controller code. Like this you can achieve a better separation of concerns and code reusability.
For example, let's say you are writing an application to let users enter information about themselfs and receive diet recomandations.
One the one hand, you would put code related to transforming user provided data into a list of diet recomandations in the model part. This includes database access, but also any calculations , algorithms and processing related to the problem in question (the problem domain).
On the other hand, you put the code to log the users in, show a form, gather the form data, validate it, in the controller. This way for instance you could later add an api to your app (which uses different code for authentication, getting data from the user, validation etc.) and reuse the code to generate the results (from the model).
This is just an example of what the model is good for.
I always relate Model to data irrespective of where it is present or how it is represented. In MVC V displays data and C handles change. Even if you have all the data to be presented on the screen in a HashMap inside your controller; that HashMap will be called the Model.
Question number three in my quest to properly understand MVC before I implement it:
I have two cases in mind:
The primary application
window needs to launch the
preferences window. (One View
invoking another View.)
The primary Model for an application
needs to access a property
in the preferences Model. (One Model
accessing another Model.)
These questions are related in that they both involve communication across Model-View-Controller triplets, a topic that I haven't found much discussion of in my Googling.
The obvious way to fix this is to wrap everything in a top-level "application" object that handles transactions between Models and allows Controllers to invoke one another's methods. I have seen this implemented, but I'm not convinced its a good idea. I can also see possibilities involving Controllers observing more than one Model and responding to more than one View, but this seems like its going to become very cluttered and difficult to follow.
Suggestions on how best to implement this sort of cross-talk? I feel like its a very obvious question, but I've been unable to find a well-documented solution.
On a broader note, if anyone has a link that shows typical approaches to these sorts of MVC issues, I would love to see it. I haven't had much luck finding solid, non-trivial references. Examples in Python would be lovely, but I'll gladly read anything.
Edit 1:
I see some pretty interesting things being said below and in general no-one seems to have a problem with the approach I've described. It is already almost a lazy form of the FrontController design that Vincent is describing. I certainly don't foresee any problems in implementing that pattern, however, it doesn't seem that anyone has really addressed the question in regards to communication amongst Models. All the answers seem to be addressing communication among objects in a single Model. I'm more interested in maintaining separate Models for separate components of the application, so that I'm not stuffing fifty state properties into a single Model class. Should I be maintaining them as sub-Models instead?
With respect to (1), views don't invoke other views. They invoke controller actions that may result in other views being rendered. In your case, the primary application window contains a user interface element (button, link) that invokes a controller action to display the preferences window.
With respect to (3), model components certainly could be related to one another. This isn't unexpected nor to be avoided, necessarily. For instance your Customer model may have an associated set of Orders. It would be perfectly natural to access the customer's orders via a method in the Customer class.
You might want to take a look at the MVC page on wikipedia for an overview.
You may want to consider looking up the Front Controller design pattern.
The Front Controller pattern defines a single component that is responsible for processing application requests. A front controller centralizes functions such as view selection, security, and templating, and applies them consistently across all pages or views. Consequently, when the behavior of these functions need to change, only a small part of the application needs to be changed: the controller and its helper classes.
This way all requests from the view goes to the FrontController who then decides which specific action (controller) to invoke. Sometimes, it could forward straight to another view as in your first case.
There is no problem with multiple objects in the model talking to each other. In fact that will be very common. The way I see it, all the objects in the Model act like one component to represent the data and operations on the data.
This article might help. And this one.
Model does not mean a single model object. The model is the subset of the entirety of your domain model which is directly related to the controller actions and the views in question.