MVC frameworks, should models resemble a 'module'-like structure? - php

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

Related

Service Layer and Entities in Yii 2

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.

Model architecture without ORM or Framework for API

Let me first say that I realize this question is vague and does not have a single answer. Nonetheless, I would greatly appreciate the insight of the StackOverflow community. To the purpose of this site, an answer will be chosen based on adherence to the specification and its address of roadblocks.
Overview
I am starting a project that will largely be a RESTful API, currently with about a half dozen models. However, their will also be a website. The goal is loosely to follow an MVC architecture so that the site and API utilize the same codebase. My plan is to heavily utilize Models, and light (or not at all) on Controllers. The views will vary between JSON (API) and HTML (website).
Specification
No ORM. I'm married to MySQL + PHP at the moment. While this may change later, I'm comfortable committing to the two and therefore don't need an ORM.
Balanced Abstraction. I do believe in Fat Models. However, per the above, I don't need queries written for me. Nonetheless, I still want to encapsulate the model properties.
Speed. As the site will largely utilize the API, speed is a cornerstone. With respect, I'd rather avoid the weight of a full-stack framework.
Roadblocks
If models are custom classes, what would be the best way to load multiple. I'd prefer to lazy load, but not at the expense of performance. Without pre-optimizing, what would be a clean approach for loading multiple models without the a half dozed require() statements at the top of every page.
Balancing abstraction, I don't want to create getX() methods in each Model for every possible query. Yet, I would like to avoid writing queries in my views. So how can I cleanly balance this between abstraction and still respect MVC paradigm?
If something exists that focuses on Model abstraction, which it probably does, please point me in that direction. However, I am familiar with CakePHP, Frapi, Code Ignitor and have read up on Doctrine. I believe these don't meet the specification.
Check out Eric Evans' Domain-Driven Design, or the free online redux Domain-Driven Design Quickly.
Specification
You don't need to use an ORM if you don't want to. Or you can use an ORM sometimes, or custom SQL other times as needed. Whatever code you write within those methods to query a database is an implementation detail and should be abstracted by the public-facing interface of the Model class.
You should write Model methods to encapsulate logical operations pertaining to your application. That is, your classes and methods are based on higher-level business requirements, not as low-level CRUD operations.
There's no need to have a Framework with a capital F to utilize Models. Check out the Page Controller pattern, which IMHO fits the PHP convention better than the Front Controller pattern that is so common among frameworks.
Roadblocks
Regarding lazy-loading, try the autoloading feature of PHP.
Avoid tedious getters and setters by designing your Model classes to higher-level interfaces, according to business goals, not low-level CRUD. A Model method could return a PHP hash array of other Model object instances. For simple object fields, you could simply make object member variables public.

CodeIgniter: what makes a good model

What makes a good MVC model in CodeIgniter. What my 'user' model does now is basically using the same active record functions from the database library. The only difference is that you don't need to specify the database table and just do:
$this->usermodel->where('username','test'),
$user = $this->usermodel->get();
This feels kinda awkward, since its not making it 'a lot easier'.
Another way I thought of was making the user model like an user object with a load function. But this is not efficient when loading more than 1 user.
Can I get some tips from you guys? Thanks.
A good tip would be, not letting model an view talk with each other straight, you always(or when it's possible) have to use controller to do this kind of communication.
I've heard also the opinion that it's a bad practice to have logic inside your models...I don't know if this is true but it's a rule I have broken lots of times(if somebody knows more about the subject please correct me).
And of course always have in mind that model should be reusable , so I try to give general solution to some problems and not application specific...on the other hand controller seems to be the throwaway component so this is where you should do ugly stuff that will never be used in other projects...
Hope it helps a little
I think 'a lot easier' comes in when you are working with large sets of data, and have many complex queries to make. As I understand it, if you are working on something that is relatively simple, you can forego the model and make your db calls from within the controller. There isn't a 'best practice' per se, but rather personal preference.
The MVC architecture allows for better compartmentalizing of code, and can allow for better structure and re-use of code, but you needn't follow the MVC idea to the letter to accomplish many things -- again it comes down to preference.
The point is to abstract all of your application logic into Models and use Controllers simply for 'controlling' your web interface and mediating between the web interface and the models.
The models are your program proper you should be able to pretty easily completely redesign the user interface without affecting the application models.

PHP data access design patterns to complement an ORM

I've currently got a site that depends on an Active Record pattern using the Doctrine ORM in PHP. I'm generally a fan of this approach - it's very straightforward and works well for managing for simple CRUD apps. But as this site grows, I think my need for more robust domain functionality will grow as well. I was wondering what other kinds of data design patterns work well in conjunction with an ORM.
My basic problem right now is that Doctrine seems to work best as a fancy querying language, so my models are littered with methods like:
function getBySomeClassfication($classification)
{
return Doctrine_Query::create()
->select('stuff')
->from('ModelClass')
->where('something = ?', $classification)
->execute();
}
or if I want to access a model class directly:
Doctrine::getTable('ModelClass')->findAll();
This means I end up working with Doctrine's object wrappers instead of directly on my domain objects. I feel like all this should exist at a lower level of abstraction.
I'm just not quite sure what the best approach is. I feel like the ORM is an excellent layer for querying single tables and dealing with relationships. But I'd like to have more flexibility in creating domain objects that work across multiple models/tables.
I've read up on using the Repository pattern, but still have a few hesitations:
I don't want to just create a pointless layer of abstraction that simply bubbles up the original problem.
I don't want to re-create or render useless the whole point of using an Active Record ORM.
Any thoughts or suggestions?
You need to work with the object wrappers (Data Access Objects) at some point and at some point your calls will be implementation (here Doctrine-) specific. It mainly depends on your current architecture on how many layers you want to put in between, but I would say - as less as possible. Is there any specific problem you have that Doctrine doesn't solve?
I sometimes don't see the point in having to deal with database specifics (e.g. one Domain Entity spreading over several tables) at all when using the ORM as a tool for (from scratch) Object Oriented Domain Model development.
I recently answered a more Java specific question here, but maybe it helps you, too for the architecture idea.
You might have a look at the Zend Framework ORM implementation(if you haven't already) where it is also possible to define relationships across multiple tables.
I hope that helps.

How to extend this simple DataMapper?

Can someone please derive a concrete example from the following:
http://www.urdalen.com/blog/?p=210
..that shows how to deal with one-to-many and many-to-many relationships?
I've emailed the author some time ago but received no reply. I like his idea, but can't figure out how to implement it beyond simple single table relations.
Note: I don't want to use a full-blown ORM. I like doing my SQL by hand. I would like to improve the design of my app code though. Right now each domain object has its own class full of queries wrapped in static methods. They just return scalar, 1d-array (record) or 2d-array (recordset) depending on the query.
The problem of ORM's (The impedance mismatch, as it's called) is precisely with relations. In an object graph (In-memory objects), relationships are pointers to other objects. In a relational database, relationships are reversed; This makes it impossible to do a simple mapping between the two models, and that is why ORM's are so complex.
If you want to stay close to the database (avoiding an ORM), then you shouldn't try to abstract relationships away. The way I write datamappers is something like the following:
$car42 = $car_gateway->fetch(42);
$wheels = $wheel_gateway->selectByCar($car42);
In contrast to the ORM way:
$car42 = $car_gateway->fetch(42);
$wheels = $car42->selectWheels();
This does mean that the gateways end up in your client-code, but it also keeps things very transparent and close to the database.
If you're looking for a simple and portable DataMapper ORM, have a look at phpDataMapper. It's only dependencies are PHP5 and PDO, and it's very small and lightweight. It supports table relations and some other very nice features as well.
Given your response to Tom's answer, I would recommend that you look at something like Zend Framework. Its ORM has a take it or leave it architecture that can be implemented in stages.
When I came to my present employer, they had an application that had just been completed months previously but had been through one or two prior versions and the current version had been in development six months longer than it was supposed to have been. However, the code base was mess. For example there was no abstraction between the database access logic and the business logic. And, they wanted me to move the site forward building new functionality, extending existing features, and fixing existing bugs in the code. To further complicate things they weren't using any form of sanitation on data inputs or outputs.
As I started to wade into the problem, I realized that I would need a solution to abstract concerns that could be implemented in steps because they obviously weren't going to go for a complete rewrite. My initial approach was to write a custom ORM and DAL that would do the heavy lifting for me. It worked great because it didn't intrude on the existing code base, and so it allowed me to move entire portions of the application to the new architecture in an unobtrusive manner.
However, after having ported a large portion of the user's area of our site to this new structure and having built an entire application on my custom framework (which has come to also include a custom front-end controller and mvc implementation), I am switching to Zend Framework (this is my choice though I am certain that some of the other frameworks would also work in this situation).
In switching to the Zend Framework I have absolutely no concerns about the legacy code base because:
I can build new models and refactor
old models (built on my custom
framework) unobtrusively.
I can refactor the existing
controllers (such as they are) to be
wrapped within a class that behaves
in a manner consistent with Zend's
MVC framework so that it becomes a
minor issue to actually begin using
Zend's Front-End Controller.
Our views are already built in
Smarty so I don't have to worry
about separating controller and view
logic, but I will be able to extend
the Zend Framework so that I can
render existing templates in Smarty
while building new templates in
straight PHP.
Basically, Zend Framework has a take it or leave architecture that makes its a joy to use within existing projects because new code and refactored code doesn't need to intrude on existing code.

Categories