I have a question regarding a custom mvc framework. I am a little confused with how I should implement the models portion. I am thinking since doctrine entities will be my models, then I could create another folder named models in my file structure and within this model folder I will have individual files that will perform the crud functionality. The reason I am trying to do my own framework is that I plan to use dojo mvc on the front-end.
for instance my models folder would look like:
models --> users
logger
blog
and inside say users class some code my look like:
class Users{
public function getUsers(){
$users = $this->em->getRepository('entities\Users')->findAll();
echo // the data from
}
// also there will be setUsers, etc...
}
Thanks everyone
With in the MVC's Model (at least to my comprehension), the Doctrine should be dealing only with information storage and retrieval for Domain Objects.
And, depending on how you actually implement the front-end part, you might have a very thin interface (that's what views and controller provide) over the model layer, which basically just provides REST API.
Materials you might be interested in:
GUI Architectures
SOLID principles
Law of Demeter
.. added the last two, because your code bit feels a bit off.
Related
How will you write your controller in MVC pattern without PHP frameworks?
This is the simplest version of my controller,
//Controller
class Controller
{
private $model;
public function __construct($model){
$this->model = $model;
}
public function clicked() {
$this->model->string = "Updated Data, thanks to MVC and PHP!";
}
}
As you can see that only model is passed into my controller as its dependency.
This is how I understand the controller in MVC pattern which can be referenced in these following articles,
https://r.je/views-are-not-templates.html
http://www.sitepoint.com/the-mvc-pattern-and-php-1/
PHP framework developers probably disagree with this, because as most frameworks seem to be MVC, but probably are Model 2.
In a Model 2 application, requests from the client browser are passed
to the controller. The controller performs any logic necessary to
obtain the correct content for display. It then places the content in
the request (commonly in the form of a JavaBean or POJO) and decides
which view it will pass the request to. The view then renders the
content passed by the controller.
So if we are going to put these frameworks aside, how do you do your controller then?
I've written a series of articles for writing MVC applications, inspired by one of the links you posted. Among those there is an article about Controllers:
Controllers are taking SRP seriously
Have a read at it first.
So if we are going to put these frameworks aside, how do you do your
controller then?
My controllers don't have a reference to the view. They only update the model as shown in your code sample, and I think that's the right way to do. Controllers shouldn't contain binding logic to the view. Instead, the view gets its data from the model (see The View gets its own data from the Model where I also explain the advantages of such a design).
Controllers can consume as many dependencies as they want (they might need more than just the model injected), but if you follow SRP closely, controllers won't need a lot of dependencies.
In most popular frameworks, you see a controller with a bunch of actions and binding logic for view rendering; I instead separate all these actions into separate controllers so that I have a 1:1 relationship between controller and view. This allows me to have controllers without binding logic to the view (see link above for detailed explanation on how I do that). My Controllers also follow SRP more closely this way.
When I said above, that the controller updates the model, beware that MVC Models are not just Domain Models. In addition to Domain Models, View Models store the state that the view needs for rendering, e.g.: the view allowing to update an entity like let's say a User, needs to know which user needs to be updated (again, read articles for more detailed explanations). My Controllers have thus in most cases at least two dependencies,
a domain model (most frequently an ORM instance) allowing me to update the datasource
a view model allowing me to update the application state (like which user is to be updated, search filters, ...) necessary for view rendering
I'd not seen Model 2 before this question, but as far as I can tell it is just a Java-specific approach to MVC, it isn't a separate design pattern as such.
You've not really explained why you think the PHP frameworks you mentioned aren't following MVC, in ZF at least it is quite common practice for dependencies to be passed in via. a controller's constructor as you have in the example from your own framework.
It's easy to fall down the rabbit hole with design patterns, really a lot of it is down to interpretation. Just because your implementation of a pattern isn't the same as another, doesn't necessarily mean the other implementation is wrong.
I am writing an application where most of the legwork is done in the models, the models perform 2 (fairly distinct) groups of tasks:-
CRUD database operations
Create Table, Form and ContentBox objects, populated with with data from the database
Some of the models as a result are quite big, so I have setup the Illuminate Database component from the Laravel framework and I am thinking of using the Eloquent ORM to create models that do the CRUD and then have separate models which generate the Tables and Forms, calling methods in the Eloquent models to get data.
What would be the correct terms for these 2 different 'models' in domain driven design? Do I call the models that do the CRUD entities and the other models models?
I've read a few of the related posts and I understand a model is a model of something in the real world. So for example I've got a model called Invoices which has methods for returning a Form object, for creating a new invoice, and a Table object, for listing all the invoices. But it also has a method for returning a PDF of a single invoice. So this isn't really a model of a single invoice - it has the ability to return data for multiple invoices... is this still a model?
Apologies there are actually 2 questions here, I'm just wondering what the correct terms are, or looking for suggestions to somewhere I can read about this sort of thing, so that I can do something that is considered best practice and will make sense to other programmers.
Thanks in advance.
Update So after reading this it seems to me that what Laravel calls a model (before adding business logic to it) is in fact an entity. So what I'm planning to do is have a folder called Entities with my ORM 'models' in and another folder called Models with the business logic 'models' in - is this common practice?
I don't think Table or Form are domain models in your case.
Domain models are reflection of your core business concepts. For example, you can answer whether an Invoice is overdue by call invoice.isOverdue()
On the other hand, Table for listing invoices, outport pdfs are responsible for taking care of presentation concerns.
Presetation components have dependence on Domain objects, but not vice versa. For example, you may list Invoices on a html page or outport Invoices by pdf. But you probably don't want the code looks like this:
public class Invoice {
Table list() {...}
File outport() {....}
...add another method for excel maybe?
}
You may interested in this post for the component's responsibilities.
It's common practice to setup what are models in laravel in the Models folder. I believe what you are looking for are called repositories which you'd make a folder for, and add it to the autoload section in your composer.json file.
It's considered good practice to have lightweight controllers and models aren't really intended to contain all the extra logic, so having repositories where you'd put all the heavy lifting would help keep your app very organized.
Traditionally in a MVC framework (Such as CodeIgniter or Kohana) I create controllers as I create different pages. There will be a login controller, a home controller and so on. But recently I learned more about objective oriented programming and want to start using it. And even though the framework uses classes, it's not the same principle as an object.
Yes. The login controller is as an object. But where am I supposed to write my "User" class for example? Do I write them in a library and import them when needed? What is the proper way of doing this, if there even is any.
I'm just puzzled on how I can do this right.
<rant>
If you start out with frameworks that are either direct Rails clones or heavily influenced by Rails architecture, you are not really implementing MVC. Ruby on Rails framework was originally intended to be a purely rapid prototyping framework, which means that they sacrificed most of MVC concepts on "The Altar of Scaffolding".
Rails-based PHP frameworks replace fully functional views with templates, model layer with some collection of active record instance and for the "controller" to deal with all the presentation and application logic.
</rant>
The bases of MVC design pattern is the separation between business logic (contained in model layer) and user interface (managed by presentation layer). These two layers each contains different groups of structure.
The User is not a model. There are no "models" in modern MVC. Instead your User instance is a domain object. Also, it should not be directly exposed to the controllers or other presentation layer structures.
The interaction between presentation layer and model layer should be performed by services. Services in model layer are structures, which are responsible for handling the interaction between domain objects and storage abstractions (either data mappers directly or via repositories and/or units of work).
namespace Controller;
class Authentication
{
// .... snip
public function postLogin( $request )
{
$service = $this->serviceFactory->create('Recognition');
$service->authenticate( $request->getParameter('username'),
$request->getParameter('password') );
}
// .... snip
}
In this case the User instance is somewhere inside the recognition service, which is there to deal with different business-logic aspects of user authentication. And do not confuse it with authorization. For authorization in MVC context there is a bit different recommended approach.
P.S.: if you are just now starting to really delve into OOP, you might find this list useful in your research.
my two cents
It is better to write your User class as a library since it is not a controller(assumption) and you should not have direct access to the User class through the URL. So the best practice is to write a Class if you want it to be object oriented. Or you can create a helper file if you want to have static functions.
I think it's too individual. Really depends on what kind of application is built. Let's think out of the CodeIgniter or Kohana, but for your individual framework, with individual application.
If you have simple login system, where the user is nothing but a Name and an ID, and all the interactions are between the other stages of the application, instead interactions between the users, your User Class which only contains information about the user (simple queries to the db which retrieves certain information from users table), can be a helper.
But in some applications (platforms in this case), the user might be an equal to any other object in it.
For example building a Forum-like application, you might want to have Warn level, Reputation, various logs of user actions, etc.
Also the user is an equal object like a 'topic', which also have for example likes/dislikes, priority, etc.
In this case you build a model and a controller for the user. For example in your Model you will have methods like
createUser(), getUser(), getUserWarnActions(), updateUserActions(), logUserActionChange(), etc, etc.
All of that methods, will be in a class called i.e. UserModel which extends the Model main class
where for example UserActions are the warn level, the email change, username change, reputation change.
In your controller, you might want to have
updateWarnLevel() => which interracts with updateUserActions(), tells the model it's action = warn level, and updates it, by the given value
so these methods will be in a class i.e. called UserController which extends the Controller main class
But at all it really depends how you look on your User class as. According to me it will be bad practice to have Controller/Model called Warn level, since it's a part of another abstraction, but not individual one.
To assume which is a child or a parent, I would try to make a structure, like a db one, and then create models/controllers/helpers.
If you have the following database tables:
users
user_reputation
user_warnlevels
topics
topic_votes
warn_levels // contains i.e. id | level | something_which_depends_on_the_level
It definately means that Users and Topics would be Models/Controllers in your application, where warn_levels won't be, since they are separate table only because they have some logic, but they are no parent table, only child one
Looking through several tutorials and books regarding data access in Zend Framework, it seems as if most people do data access within their models (Active Record Pattern) or even controllers. I strongly disagree with that. Therefore I want to have a Data Access Layer (DAL) so that my domain layer remains portable by not having any "ZF stuff" in it. I have searched around but have not really found exactly what I wanted. Heads up: I am new to ZF.
DAL structure
So, the first problem is where to place the Data Access Layer. While it could certainly be placed within the library folder and adding a namespace to the autoloader, that does not seem logical as it is specific to my application (so the applications folder is suitable). I am using a modular structure. I am thinking of using the below structure:
/application/modules/default/dal/
However, I am not sure how include this folder so that I can access the classes within the controllers (without using includes/requires). If anyone knows how to accomplish this, that would be super! Any other ideas are of course also welcome.
The idea is to have my controllers interact with the Data Access Objects (DAO). Then the DAOs use models that can then be returned to the controllers. By doing this, I can leave my models intact.
Implementation
In other languages, I have previously implemented DAOs per model, e.g. DAL_User. This resulted in an awful lot of DAO classes. Is there a smarter way to do this (using a single class does not seem easy with foreign keys)?
I would also appreciate suggestions on how to implement my DAO classes in ZF. I have not spent an awful lot of time reading about all of the components available for database interaction, so any ideas are very welcome. I suspect that there is something smarter than standard PDO available (which probably uses PDO internally, though). Name drops would be sufficient.
Sorry for the many questions. I just need a push in the right direction.
Well, the first thing you have to take into account when dealing with the Data Access Layer, is that this layer also have sub-layers, it's unusual to find folders called "dal" in modern frameworks (I'm taking as basis both Zend Framework and Symfony).
Second, about ActiveRecord, you must be aware that by default Zend Frameworks doesn't implement it. Most of the tutorials take the easiest path to teach new concepts. With simple examples, the amount of business logic is minimal, so instead of adding another layer of complexity (mapping between database and model's objects) they compose the domain layer (model) with two basic patterns: Table Data Gateway and Row Data Gateway. Which is enough information for a beginner to start.
After analyzing it, you will see some similarity between ActiveRecord
and Row Data Gateway patterns. The main difference is that
ActiveRecord objects (persistable entities) carries business logic and
Row Data Gateway only represents a row in the database. If you add
business logic on a object representing a database row, then it will
become an ActiveRecord object.
Additionally, following the Zend Framework Quick Start, on the domain model section, you will realize that there's a third component, which uses the Data Mapper Pattern.
So, if the main purpose of your DAL is to map data between business objects (model) and your storage, the responsibility of this task is delegated to the Data Mappers as follows:
class Application_Model_GuestbookMapper
{
public function save(Application_Model_Guestbook $guestbook);
public function find($id);
public function fetchAll();
}
Those methods will interact with the Database Abstraction Layer and populate the domain objects with the data. Something along this lines:
public function find($id, Application_Model_Guestbook $guestbook)
{
$result = $this->getDbTable()->find($id);
if (0 == count($result)) {
return;
}
$row = $result->current();
$guestbook->setId($row->id)
->setEmail($row->email)
->setComment($row->comment)
->setCreated($row->created);
}
As you can see, the Data Mappers interacts with a Zend_Db_Table instance, which uses the Table Data Gateway Pattern. On the other hand, the $this->getDbTable->find() returns instances of the Zend_Db_Table_Row, which implements the Row Data Gateway Pattern (it's an object representing a database row).
Tip: The domain object itself, the guestbook
entity, was not created by the find() method on the DataMapper,
instead, the idea is that object creation is a task of factories
and you must inject the dependency in order to achieve the so called
Dependency Inversion Principle (DIP) (part of the SOLID principles). But that's
another subject, out of the scope of the question. I suggest you
to access the following link http://youtu.be/RlfLCWKxHJ0
The mapping stuff begins here:
$guestbook->setId($row->id)
->setEmail($row->email)
->setComment($row->comment)
->setCreated($row->created);
So far, I think I have answered your main question, your structure will be as following:
application/models/DbTable/Guestbook.php
application/models/Guestbook.php
application/models/GuestbookMapper.php
So, as in the ZF Quick Start:
class GuestbookController extends Zend_Controller_Action
{
public function indexAction()
{
$guestbook = new Application_Model_GuestbookMapper();
$this->view->entries = $guestbook->fetchAll();
}
}
Maybe you want to have a separated folder for the data mappers. Just change:
application/models/GuestbookMapper.php
to
application/models/DataMapper/GuestbookMapper.php
The class name will be
class Application_Model_DataMapper_GuestbookMapper
I've seen that you want to separate your domain model objects into modules. It's possible too, all you need is to follow the ZF's directory and namespace guidelines for modules.
Final tip: I've spent a lot of time coding my own data mappers for
finally realize that it's nightmare to maintain the object mapping when
your application grows with a lot of correlated entities. (i.e Account
objects that contain references to users objects, users that contain
roles, and so on) It's not so easy to write the mapping stuff at this
point. So I strongly recommend you, if you really want a true
object-relational mapper, to first study how legacy frameworks perform
such tasks and perhaps use it.
So, take some spare time with Doctrine 2, which is the
one of the best so far (IMO) using the DataMapper pattern.
That's it. You still can use your /dal directory for storing the DataMappers, just register the namespace, so that the auto loader can find it.
In my opinion you should have a gateway abstraction (not just Database access) per model. A DAO is not enough. What if you need to get the data from the cloud at some point? This is quickly coming a reality. If you abstract your gateway logic into something generic and then implement it using a database you can have the best of both worlds.
The implementation of a specific gateway interface could use a generic data mapper if you so chose. I work for a small company and have always just created my implementation using PDO. This lets me be close enough to the database to deal with any interesting bits of SQL I might need but am able to support a very abstracted interface.
I have not used the Zend Framework at all. I do not know if they have data-mapper tools that could help you implement the gateway interfaces.
I am using Zend framework and doctrine in this app
In my web application i have various individual modules like events, conferences, case studies.. so i am making controller design at this moment. In the below image regulatory document is the controller and its sub are its actions. So regulatory doc, videos, podcasts all are having almost the same kind of functionality. so is this design appropriate...?
In mvc for each action i will be having a separate view. And on user type i may have to put access levels on this modules. so i have kept separate controller so that i can easily control the module for each user type. But this is resulting in duplicate code.
Now i am thinking to make one parent class and in that i will have all the common methods. eg. I will have common class Resources and in that i will keep list, search, suggest, addFavorite etc. And that will be the parent to the above given controllers.
So than how will i manage my view for all these different modules if i go with this approach..? if i go with this than my code will be bit messy..?
I would suggest to keep all the controllers to have nice URLs and clear structure in the modules, however keep the controllers thin. Put your domain logic into Services or Entities, hence no (or just less) code duplication is required.
More in:
Is MVC + Service Layer common in zend or PHP?
How to implement service layer in Zend Framework?
From DDD:
http://domaindrivendesign.org/node/118
controllers belong to application layer / domain logic belongs to domain layer
If I understand you correctly you have a set of common behaviors among your regulatory documents, videos and podcasts.
In this case you should probably try to abstract the commonalities out into a parent class from which these three areas inherit.
As an example, I have my own MVC framework where I define a superclass tnh_controller from which my other controllers (eg: venue_controller, group_controller) inherit. In the parent controller I define the header() and footer() and delete() methods. I can then use those unchanged in the child classes and save myself some effort.
You can likewise do some of the common work for your models (CRUD) in a model superclass, only overriding it as needed. Most of the logic for different models comes from class variables (table names, column names, etc).
I wouldn't worry too much about being "strict" MVC. Instead try to work out what will save you time and keep your code organized. It sounds like you're on the right track putting similar behaviors at a parent level.
You can still have a separate controller to contain suggest, addFavorite actions without having to make it the parent class for all the controllers. Basically the UI elements related to these you can render as partial views and call on to the actions in the relevant controller. That way you can get rid of the problem with the views.
MVC designing means that for each view, you have a controller and a model. However, the models don't need to be classes at all, nor having a different model for each MVC. Usually you will share a model between some MVCs, or your model might just be an integer value which you define in the own controller. Usually, you might even want to share data between them, then you will have a singleton mode:
http://www.galloway.me.uk/tutorials/singleton-classes/