at the moment im integrating ORM (doctrine) into a MVC framework (codeigniter).
then it hit me that this was the obvious way of setting up a MVC:
the controller calls the models that are representing database tables.
look at this picture:
MVC + ORM
then i wondered, how can a MVC without ORM be real MVC? cause then the models are not real objects, rather aggregations of different functions that perform CRUD, then returning the result to the controller. and there is no need for a state (object properties) i guess so the functions would be all static?
correct me if im wrong on this one.
i guess a lot of people are using models without ORM. please share your thoughts. how do your models look like?
MVC is a general purpose UI pattern originally conceived for OO languages (I believe Smalltalk was the first).
If you don't have a relational database as a back end (say, a binary serialized file format) you have no need of an ORM layer.
The two are quite distinct and can exist without each other.
MVC has nothing to do with objects. That makes it quite simple to have MVC without an ORM.
What about applications which don't use a database but use some other serialization for their data (such as writing out an XML file)? MVC and ORM are orthogonal concepts. MVC is about how you organize your internal object interactions, and ORM is about how you serialize and deserialize the model. You can certainly use MVC without ORM by simply substituting a different serialization method.
The controller part of MVC is not about making the low-level calls to serialize, it is about tying together views and models to create the proper user experience and task flow.
Related
I've been learning Yii2 framework for a couple of weeks now. One of its core concepts is "Fat models, thin controllers". Reading the source code of the advanced application template I found that due to this concept nearly all the logic is contained within the models.
Well, there could be no questions at all if I hadn't some experience with Spring MVC where service layer seems to be a kind of natural way to decouple application's logic from its actual data.
So the question is: can it be a good practice to implement such an enterprise-like structure in an application built with Yii2? Speaking more specifically: is it worth breaking Yii's models into Entities, DTOs and Services?
Thank you in advance!
P.S.: The question can seem to be a kind of too abstract or subjective but having little experience with Yii2 I'd like to know are there any architectural features in Yii2 that could make the above mentioned implementation be not optimal in regard to code maintenance, performance and so on?
You can actually create models that are not ActiveRecords, so they actually become your service layer, just need to extend from yii\base\Model or yii\base\Object as you see fit, and implement all the logic you need there. You can also create those models on another folder called services, so their namespace would become app\services\ModelName
Using another feature instead of built-in feature can not be a good practice for every framework.
IMO, the model part is a killer feature of yii2, so if you do not need scaffold (code generation), you can use any other php framework without model part (zf2, symfony2, micro-frameworks).
So you can use your own model architecture without any perfomance lag but you'll need to write more code to make things done and your models will be hard to support by other people that are using yii2 and therefore I recommend to use another framework which comes without model layer.
CakePHP doesn't seem to ever mention separating the business logic and data access layers of an app. This is my first MVC app and my "fat models" are turning out to be very fat because they contain all kinds of business logic whose only real thing in common is requiring access to the same database.
When you hear the suggestion to move your business logic from controllers into the model, is it really acceptable to wind up in such a state? Does CakePHP provide any structure for a separate business logic layer as part of their framework?
Thanks, Brian
No. It sounds to me that what you are running into is the classic downside of the Active Record pattern. Also, it doesn't help that CakePHP is all based around result associative arrays instead of object instances. I suggest that you take a look at packages like Doctrine 2. It implements a DataMapper pattern instead of an ActiveRecord pattern. It keeps your business logic completely separate from your data access layer.
There are CakePHP extensions to integrate Doctrine into CakePHP.
Many PHP frameworks claim that they implement MVC design pattern. However, in their implementation, the model and view don't know each other and each communication in between must be done through controller. As I read in wikipedia, this is MVA (Model View Adapter) instead of MVC design pattern approach because in MVC, model and view communicates directly.
Those frameworks' claim are wrong or did I miss something?
Frameworks like CodeIgniter are MVA, yes. However, their claims are not wrong since MVA is basically a different type of MVC deployment. Mediating controllers are hit by users which handle the business logic; they also call to the model to get the data and prepare the view.
This is not wholly diverged from strict MVC where the Model and View can talk to each other, so to say it's "wrong" is a bit harsh. I would say it's a different take on MVC.
EDIT:
See CodeIgniter's take on it:
https://www.codeigniter.com/user_guide/overview/at_a_glance.html#
Models are not required as everything can be done in the controller (not advised, obviously). Note that CI (and most other frameworks) say they are based on MVC principles.
I'm in the early stages of building a website using CodeIgniter, a PHP MVC framework. My models are, so far, fairly simple, yet I'm already doubting my coding approach. Is it a bad idea to let models use eachother? While it certainly reduces the amount of code needed, it also raises a strong dependency on outside code within each model method. Is this okay? Or does the methods need a more 'module' approach where they just work, independent of other methods?
Thanks for your time.
In theory, models should be grouped together into independent modules. You should then be able to move that module from CodeIgniter app to CodeIgniter app and it should work with little to no modification.
So it's OK for models to use each other. A model should represent a real-world object, and real-world objects rely on each other too!
Yea There is 2 ways to do it how ever,
There is the model call (Instantiate) the new object its self
Or you can have your controller call (Instantiate) the object and pass it to your model
ether works but my personal preference to do the first
I used to write the data access functionalities in model itself. Now I want to separate data access from business logic. I am using codeigniter as framework.
It seems that one way of doing it is use ORM, but it will have a performance penalty I guess.
are there any general best practices?
Have a look at POEAA's Data Source Architectural Patterns:
Table Data Gateway
Row Data Gateway
Active Record
Data Mapper
CodeIgniter claims to use ActiveRecord, but it doesnt. It's more like a rudimentary QueryObject. To truly separate your DAO from your Domain objects, you have to use a DataMapper. Depending on the complexity of your mapping needs you can build one yourself or use an ORM. Ironicaly, the majority of ORMs in the PHP World are based on ActiveRecord, which is pretty ill-suited for ORM. Doctrine 2 is the only I know that uses a DataMapper approach.
An ORM will always come with a performance penalty (and it can be a serious one). However, you should not rule out an ORM just because of that. Handcrafting an efficient DataMapper in a high impedance mismatch scenario can be tedious and difficult work. Again, see POEAA for a list of common Object-Relational patterns.
There seems to a DataMapper implementation for CodeIgniter with Overzealous DMZ. I have never worked with it and cannot say anything about it. It just came up after a quick google, so I thought I add it here.