I need some help as I seem not to be able to grasp the concept.
In a framework, namely Yii, we create models that correspond to database tables. We extend them from CActiveRecord.
However, if I want to create a class that will get some data from other models but then will do all the computations based on those results and do something with them... then how do I proceed?
I want to clearly divide the responsibility so I don't want put all the calculations in source db based models. Basically the idea is that it will be taking some stuff from some models and then updating another models with the results of the calculations.
What do I do?
Keep all the calculations in some controller and use required models? (Hesitant about this because there is a rule to keep controller slim)
Create a none db model and then work from there (how?)?
Do something else (what?)?
Thanks for any help!
For you to use the Yii interpretation of Model, you will have to create class, which depends on CModel. It is an abstract class, thus you will be required to implement attributeNames() method.
To use other "Models" with this new structure, you will need to inject them in constructor, or right after your custom model has been created.
In real MVC model is a layer, which mostly contains two sets of classes with specific responsibilities: domain business logic and data access operations. Objects which are responsible for Domain Business Logic have no clue where the information is stored and where it comes from. Or even if there is such a thing as "database".
This video might explain a bit: https://vimeo.com/21173483
Related
I am trying to understand the MVC Pattern, and I finally understand a lot of it. There is one concept that I don't quite understand yet. I have looked through all the posts on here that try to explain MVC, but this one question isn't answered clearly yet.
Do you create variables in the model or the controller or both?
I can see someone passing variables from the controller to the model to change the data held within the variables, but would it be better to create them in the model then just call their values from the controller? Or would it be better to create variables in the model, and copy their values to the same variables in the controller?
If you know, please explain why one is better than the other, please. I am asking to understand, not just to know the right answer. Thank you.
If I give a straight forward answer for
Do you create variables in the model or the controller or both?
It doesn't really matter.
The main idea behind Model and Controller is
Controller resides only Presentation Logic.
Model resides only Business Logic.
So that, if you want to present your model with a different presentation logic, you can get your existing Model out and plug it with a new Controller without any problem because your business logic & presentation logic is decoupled(not mixed with each other).
This is the best diagram I found for MVC architecture. Hope you can upgrade your understanding with this.
So in terms of variables, in Model you should make variables only for business logic purpose. In Controller, it's only for presentation purpose. :))
Persistent data needed throughout the lifetime of the application should be held within the Model. Model method calls to set, get and manipulate the data within the Model should be done by the Controller.
Temporary data needed by the application or the view (for any reason) can be held in the controller... but no persistent data should ever be held within the controller, as it's considered to be a bad MVC design pattern implementation to do so.
In MVC, MVVM, or MVP I typically have models that either put a heavy emphasis on using other models in conjunction to get the full set of data needed or that basically require joins to other tables (models). When I run into this I usually just extend the model's functionality like normal but will include a join to another table in new method I'm creating. What's tricky for me to sometimes decide is which model I should put this functionality/join in since it makes it dependent on something not specific to that model. Is there a better way of dealing with relationships when using patterns that utilize data models?
Here is some pseudo code to help illustrate what I mean with some active record mixed in:
public static void getAll() {
this.db("sometable").join("anothertable", "column", "=", "anothercolumn").select();
}
Now if the model was for sometable I'm creating a dependency of sorts by joining to another table in the method above. Now the model for sometable also deals with anothertable which would have its own separate model.
'Model' is an abstract term. It doesn't need to be one single model.
I look at MVP as a presenter, a view and whatever else I need to get the job done. This might be one class, an enumeration or a number of repositories. As long as I keep my presenter's dependencies low, I'm happy.
Could you consider making your controller or presenter dependent on something 'above' your models that can get related things as, and when, you need them?
For example: Let's say I'm grabbing a list of names and saving it to an NSMutableArray. Do I implement the method of actually calling the server to fetch the data in the controller (UIViewController) or the model(Friends object)?
It's a design decision that depends on what you're trying to accomplish. If your model only makes sense in the context of a single service, or if you want your model to provide access to all the data on the server, then build the connection to the server into your data model. This might make sense if you are, for example, building a client for a service like Twitter or Flickr.
On the other hand, if you're just grabbing a file from a server and that's the end of it, it may make sense to do the communication in the controller. Controllers tend to be less reusable and more customized for the particular behavior of the application. Keeping the specifics about where the data comes from out of the model makes the model more reusable. It also makes it easy to test -- you can write test code that just reads a local file and stores the data in the model.
That's a good question. I think the best way is through a controller because it decouples your model from requiring the other model to be present for it to work properly. Although I don't think you violate "proper mvc" by doing it in the model either.
I think you want to put it in the model. What you'll do is interrogate the model for the data and then the model will handle how to populate itself whether it's from an internal data store or an external one (like a server).
One approach is to use the repository pattern. To do this, you create Repository objects in your Model folder and you place all of you database-related methods in them. Your controllers call the repository classes to get the data. This allows you to separate the real model objects from the database accessing methods.
I use the MVCS pattern (Model-View-Controller-Store), which I discovered in Aaron Hillegass's book "IOS Programming: The Big Nerd Ranch Guide" (http://www.bignerdranch.com/book/ios_programming_the_big_nerd_ranch_guide_rd_edition_)
The store is specifically designed to fetch the data, whether it comes from a server, a local file, a persisted collection, a database, etc.
It allows to build very evolutive applications. For example, you can build your application based on a web service, and the day you want to persist your data, you juste have to modify the store, without having to modify a single line of code in your controller.
It's a lot like the Repository Pattern (http://msdn.microsoft.com/en-us/library/ff649690.aspx) (cf BobTurbo's answer)
I'd personally make a DAO, or data helper class. It's very hard to follow the strict MVC in objective C when things get more complicated. However, putting it in the model or the VC is not wrong as well.
This is a complicated question with many possible answers, so I'll break down my situation into simple bullet points to help narrow down the solution:
My Rails App Has the Following 'Objects'
Author
Feed
Update
FeedTypes
The Objects are Related Like So:
Authors can have 1 or more Feeds
Feeds can have one or more Updates
A Feed has one feedType
Example Setup:
Author: Levi Hackwith
Feed: view-source:http://www.twitter.com/statuses/user_timeline/opnsrce.xml
FeedType: Twitter
Update: The tweets inside the Feed
My problem and My Questions:
Problem:
I need to parse the above-mentioned feed and store each tweet in the updates table. To parse the feed, I was thinking of writing a custom Feed class which would get inherited by TwitterFeed, FacebookFeed, TumblrFeed, etc.
However, I'm not sure if this is the 'Best Practice' for solving this kind of problem.
Questions:
When is it appropriate to develop a custom class to perform an action in RoR (as opposed to going through the Model or Controller)?
If this situation does not call for a custom class, which element should I apply the parsing logic to? The model or the controller?
If this is an appropriate situation for a custom class, where in my rails application should I store it (in other words, what's the right 'convention')?
You are probably going to have a background task invoked from time-to-time to check all the feeds, fetch new updates and store those in database. This task is completely separate from controllers and it should be possible to invoke it without any controller logic.
Your abstraction looks fine. You can further have something like XmlFeed < Feed if several feeds share a common XML structure.
1) Controllers should talk to database/models and pass relevant data to the view to render. Everything else should be either in a model, helper or library.
2) Are you asking where the parsing logic belongs to? In MVC, I think this would belong under the Model and/or a helper class, but definitely not the controller.. it's not its responsibility.
3) Classes holding data go into app/models. Classes that have nothing to do with holding data, go into the lib directory.
Don't shy away from using a custom class if it's appropriate. If you need another a class, then add one, the fact you are using rails is not relevant to that decision.
How would one implement lazy loading in the context of three tiers? I understand the basic architecture of Presentation Layer, Business Layer, and Data Layer:
You have your basic "dumb" classes that are nearly mirror images of the tables in the database with one exception. Instead of foreign key IDs you have a reference to the actual instance(s) of what is being referred to. For example: Employee with Name/DOB/Title properties.
Then for each of these classes you have a class that provides the CRUD operations on it plus any custom data storage routines you might need (calling a stored procedure that works with that object, etc). This class would be swapped out if you changed database. For example: EmployeeDAL.Save(myEmployee), EmployeeDAL.Get(myEmployee) (where myEmployee has their ID populated but nothing else)
You have business layer classes that perform validation and what not. The methods in these classes usually end by calling into the DAL to persist information or to retrieve it. This is changed when the customer changes their mind about what constitutes valid/invalid data or wants to change the way some calculation is done.
The presentation layer interacts with the business layer to display things and shuttle inserts/updates made in the UI to the lower layers. For example: it loops over a list of Employees and displays them in an HTML table.
But where exactly would the code for lazy loading references go? If the presentation layer has a Company object that it just displayed and is beginning the process of displaying myCompany.Employees, how is that achieved? myCompany is an instance of one of the dumb classes that mirror the database tables and isn't supposed to know about how to retrieve anything.
Do you do as the answer to this question suggests and create a Dummy version of each object? Then the DAL level object can have variables indicating if Employees has or has not been loaded and call DALEmployee.GetEmployees(this)? I feel as if I'm missing something crucial about the pattern...
If you use a pre-built framework such as nHibernate this will make it all much easier, you can define the lazy-loading in the class/table mapping and when a query is run. To do it yourself in a neat manner is going to take a fair bit of code although the System.Lazy class in .NET 4 may help.